|
|
Initial revision
/* snmp.c - SNMP changes for gawk */
#ifndef lint
static char *rcsid = "$Header: /var/lib/cvsd/repos/CSRG/43BSDReno/contrib/isode-beta/snmp/gawk-2.11/snmp.c,v 1.1 2018/04/24 16:12:56 root Exp $";
#endif
/*
* $Header: /var/lib/cvsd/repos/CSRG/43BSDReno/contrib/isode-beta/snmp/gawk-2.11/snmp.c,v 1.1 2018/04/24 16:12:56 root Exp $
*
*
* $Log: snmp.c,v $
* Revision 1.1 2018/04/24 16:12:56 root
* Initial revision
*
* Revision 7.2 90/06/06 22:59:38 mrose
* update
*
* Revision 7.1 90/03/22 16:44:22 mrose
* touch-up
*
* Revision 7.0 90/03/05 10:33:19 mrose
* *** empty log message ***
*
*/
/*
* NOTICE
*
* Acquisition, use, and distribution of this module and related
* materials are subject to the restrictions of a license agreement.
* Consult the Preface in the User's Manual for the full terms of
* this agreement.
*
*/
#ifdef SNMP
#include "awk.h"
#ifdef HUGE
#undef HUGE
#endif
#include <isode/snmp/objects.h>
#include <isode/pepy/SNMP-types.h>
#include <isode/dgram.h>
#include <isode/internet.h>
#include <isode/tailor.h>
/* DATA */
int debug = 0;
int snmp_enabled = 1;
int snmp_scalars_as_arrays = 1;
char *snmp_file = NULLCP;
static int snmp_id = 0;
static int snmp_retries = 3;
static int snmp_timeout = 10;
static char *snmp_agent = NULL;
static char *snmp_community = NULL;
NODE *AGENT_node,
*COMMUNITY_node,
*DIAGNOSTIC_node,
*ERROR_node,
*RETRIES_node,
*TIMEOUT_node;
NODE *Ndot_string;
static int snmp_fd = NOTOK;
static struct sockaddr_in in_socket;
static PS ps = NULLPS;
static struct type_SNMP_Message msgs;
static struct type_SNMP_PDUs pdus;
static struct type_SNMP_PDU parms;
static struct type_SNMP_VarBindList vps;
static struct type_SNMP_VarBind vs;
struct snmp_search {
struct search s_search; /* must be first entry */
OT s_parent;
PE s_pe;
struct type_SNMP_VarBindList *s_bindings;
struct snmp_search *s_prev;
struct snmp_search *s_next;
};
static struct snmp_search *head = NULL;
static struct snmp_search *tail = NULL;
char *snmp_error (), *snmp_variable ();
#ifndef SYS5
long random ();
#endif
/* INIT */
int check_snmp (r, name)
NODE *r;
char *name;
{
char c;
register char *cp;
OT ot;
static int inited = 0;
if (inited == 0) {
inited = 1;
snmp_onceonly ();
}
for (cp = name; is_identchar (*cp); cp++)
continue;
if (c = *cp)
*cp = NULL;
if ((ot = text2obj (name)) && ot -> ot_syntax) {
r -> magic = (caddr_t) ot;
if (ot -> ot_getfnx || snmp_scalars_as_arrays)
r -> type = Node_var_array;
}
*cp = c;
}
/* */
int f_integer (), f_octets (), f_display (), f_objectID (), f_null (),
f_ipaddr (), f_clnpaddr ();
static struct pair {
char *pp_name;
IFP pp_value;
} pairs[] = {
"INTEGER", f_integer,
"Services", f_integer,
"OctetString", f_octets,
"DisplayString", f_display,
"ObjectID", f_objectID,
"NULL", f_null,
"IpAddress", f_ipaddr,
"NetworkAddress", f_ipaddr,
"Counter", f_integer,
"Gauge", f_integer,
"TimeTicks", f_integer,
"ClnpAddress", f_clnpaddr,
NULL
};
static snmp_onceonly () {
int i;
register struct pair *pp;
register struct type_SNMP_Message *msg = &msgs;
register struct type_SNMP_PDUs *pdu = &pdus;
register struct type_SNMP_PDU *parm = &parms;
register struct type_SNMP_VarBindList *vp = &vps;
register struct type_SNMP_VarBind *v = &vs;
OS os;
register OT ot,
ot2;
Ndot_string = make_string (".", 1);
Ndot_string -> flags |= PERM;
if (readobjects (snmp_file) == NOTOK)
fatal ("readobjects: %s", PY_pepy);
/* mark entries that are actually arrays! */
for (ot = text2obj ("iso"); ot; ot = ot -> ot_next) {
if (ot -> ot_syntax
|| (i = strlen (ot -> ot_text)) <= 5
|| strcmp (ot -> ot_text + i - 5, "Entry"))
continue;
for (ot2 = ot -> ot_children; ot2; ot2 = ot2 -> ot_sibling)
if (ot2 -> ot_children || !ot2 -> ot_syntax)
break;
if (ot2)
continue;
for (ot2 = ot -> ot_children; ot2; ot2 = ot2 -> ot_sibling)
ot2 -> ot_getfnx = (IFP) 1;
}
for (pp = pairs; pp -> pp_name; pp++)
if ((os = text2syn (pp -> pp_name)) == NULL)
fatal ("lost syntax for \"%s\"", pp -> pp_name);
else
os -> os_decode = pp -> pp_value;
bzero ((char *) msg, sizeof *msg);
msg -> version = int_SNMP_version_version__1;
msg -> data = pdu;
bzero ((char *) pdu, sizeof *pdu);
pdu -> offset = type_SNMP_PDUs_get__request;
pdu -> un.get__request = parm;
bzero ((char *) parm, sizeof *parm);
parm -> variable__bindings = vp;
bzero ((char *) vp, sizeof *vp);
vp -> VarBind = v;
bzero ((char *) v, sizeof *v);
if ((v -> value = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_NULL))
== NULLPE)
fatal ("pe_alloc: out of memory");
ps_len_strategy = PS_LEN_LONG;
#ifndef SYS5
srandom (getpid ());
#else
srand (getpid ());
#endif
}
/* GET */
int snmp_get (ptr, instname)
NODE *ptr;
char *instname;
{
int gotone,
retries,
status = -1;
struct type_SNMP_Message *msg = &msgs;
register struct type_SNMP_PDU *parm = msg -> data -> un.get__request;
register struct type_SNMP_VarBind *v =
parm -> variable__bindings -> VarBind;
PE pe = NULLPE,
p = NULLPE;
OID oid;
OT ot = (OT) ptr -> magic;
NODE *value = NULL;
if (snmp_ready () == NOTOK)
goto out;
parm -> request__id = snmp_id;
if (v -> name)
free_SNMP_ObjectName (v -> name), v -> name = NULL;
if (instname == NULL) {
if (ot -> ot_getfnx || snmp_scalars_as_arrays) {
register struct snmp_search *s;
for (s = tail; s; s = s -> s_prev) {
register struct type_SNMP_VarBindList *vp;
if (ot -> ot_name -> oid_nelem
!= (oid = s -> s_parent -> ot_name) -> oid_nelem + 1
|| bcmp ((char *) ot -> ot_name -> oid_elements,
(char *) oid -> oid_elements,
oid -> oid_nelem
* sizeof ot -> ot_name -> oid_elements[0]))
continue;
for (vp = s -> s_bindings; vp; vp = vp -> next) {
v = vp -> VarBind;
if (ot -> ot_name -> oid_nelem >= v -> name -> oid_nelem)
fatal ("snmp_get: internal error");
if (bcmp ((char *) v -> name -> oid_elements,
(char *) ot -> ot_name -> oid_elements,
ot -> ot_name -> oid_nelem
* sizeof ot -> ot_name -> oid_elements[0]))
continue;
goto get_value;
}
status = int_SNMP_error__status_noSuchName;
goto out;
}
if (ot -> ot_getfnx) {
snmp_diag (NULLCP,
"can't use SNMP array variable as scalar unless within for-in construct");
goto out;
}
}
if ((oid = v -> name = oid_extend (ot -> ot_name, 1)) == NULL) {
no_mem_for_inst: ;
snmp_diag (NULLCP, "oid_extend: out of memory");
goto out;
}
v -> name -> oid_elements[v -> name -> oid_nelem - 1] = 0;
}
else {
register int i;
register unsigned int *ip,
*jp;
OID inst = str2oid (instname);
if (inst == NULL) {
snmp_diag (NULLCP, "str2oid: bad instance identifier \"%s\"",
instname);
goto out;
}
if ((oid = v -> name = oid_extend (ot -> ot_name, inst -> oid_nelem))
== NULL)
goto no_mem_for_inst;
ip = oid -> oid_elements + oid -> oid_nelem - inst -> oid_nelem;
jp = inst -> oid_elements;
for (i = inst -> oid_nelem; i > 0; i--)
*ip++ = *jp++;
}
if (encode_SNMP_Message (&pe, 1, 0, NULLCP, msg) == NOTOK) {
snmp_diag (NULLCP, "encode_SNMP_Message: %s", PY_pepy);
goto out;
}
msg = NULL, gotone = 0;
for (retries = snmp_retries; retries > 0; ) {
int len;
fd_set rfds;
if (debug > 1)
print_SNMP_Message (pe, 1, NULLIP, NULLVP, NULLCP);
len = ps -> ps_byteno;
if (pe2ps (ps, pe) == NOTOK) {
snmp_diag (NULLCP, "pe2ps: %s", ps_error (ps -> ps_errno));
goto error_x;
}
if (debug > 0 && (len = ps -> ps_byteno - len) > 484)
fprintf (stderr, "sent message of %d octets\n", len);
FD_ZERO (&rfds);
FD_SET (snmp_fd, &rfds);
switch (xselect (snmp_fd + 1, &rfds, NULLFD, NULLFD, snmp_timeout)) {
case NOTOK:
snmp_diag ("failed", "xselect");
goto error_x;
default:
if (FD_ISSET (snmp_fd, &rfds))
break;
/* else fall... */
case OK:
if (debug > 0)
fprintf (stderr, "timeout...\n");
retries--;
continue;
}
if ((p = ps2pe (ps)) == NULLPE) {
snmp_diag (NULLCP, "ps2pe: %s", ps_error (ps -> ps_errno));
goto error_x;
}
if (decode_SNMP_Message (p, 1, NULLIP, NULLVP, &msg) == NOTOK) {
snmp_diag (NULLCP, "decode_SNMP_Message: %s", PY_pepy);
goto out;
}
if (debug > 1)
print_SNMP_Message (p, 1, NULLIP, NULLVP, NULLCP);
if (msg -> data -> offset != type_SNMP_PDUs_get__response) {
snmp_diag (NULLCP, "unexpected message type %d",
msg -> data -> offset);
goto out;
}
if ((parm = msg -> data -> un.get__response) -> request__id == snmp_id)
break;
if (debug > 0)
fprintf (stderr, "bad ID (got %d, wanted %d)\n",
parm -> request__id, snmp_id);
if (msg)
free_SNMP_Message (msg), msg = NULL;
if (p)
pe_free (p), p = NULLPE;
gotone++;
}
if (retries <= 0) {
snmp_diag (NULLCP,
"no %sresponse within %d retries of %s%d second%s each",
gotone ? "acceptable " : "", snmp_retries + gotone,
gotone ? "upto " : "",
snmp_timeout, snmp_timeout != 1 ? "s" : "");
goto out;
}
if ((status = parm -> error__status) != int_SNMP_error__status_noError) {
char *cp = snmp_variable (parm, parm -> error__index);
snmp_diag (NULLCP, cp ? "%s at position %d (%s)" : "%s at position %d",
snmp_error (status), parm -> error__index, cp);
goto out;
}
if (parm -> variable__bindings == NULL
|| (v = parm -> variable__bindings -> VarBind) == NULL) {
snmp_diag (NULLCP, "missing variable in response");
goto out;
}
if (debug > 0 && parm -> variable__bindings -> next)
fprintf (stderr, "too many responses: %s\n",
oid2ode (parm -> variable__bindings -> next -> VarBind -> name));
if (oid_cmp (oid, v -> name)) {
char buffer[BUFSIZ];
(void) strcpy (buffer, oid2ode (v -> name));
snmp_diag (NULLCP, "wrong variable returned (got %s, wanted %s)",
buffer, oid2ode (oid));
goto out;
}
get_value: ;
if ((*ot -> ot_syntax -> os_decode) (&value, v -> value) == NOTOK) {
snmp_diag (NULLCP, "decode error for variable \"%s\": %s",
oid2ode (v -> name), PY_pepy);
goto out;
}
goto out;
error_x: ;
if (ps)
ps_free (ps), ps = NULLPS;
if (snmp_fd != NOTOK)
(void) close_udp_socket (snmp_fd), snmp_fd = NOTOK;
out: ;
if (msg && msg != &msgs)
free_SNMP_Message (msg);
if (p)
pe_free (p);
if (pe)
pe_free (pe);
deref = ptr -> var_value;
do_deref ();
ptr -> var_value = value ? value : Nnull_string;
assign_number (&ERROR_node -> var_value, (AWKNUM) status);
}
/* */
static snmp_ready () {
int changed = 0;
char *pp;
struct sockaddr_in lo_socket;
register struct sockaddr_in *lsock = &lo_socket;
register struct sockaddr_in *isock = &in_socket;
register struct hostent *hp;
register struct servent *sp;
register NODE *tmp;
deref = DIAGNOSTIC_node -> var_value;
do_deref ();
DIAGNOSTIC_node -> var_value = Nnull_string;
if ((snmp_retries = (int) RETRIES_node -> var_value -> numbr) <= 0)
snmp_retries = 1;
if ((snmp_timeout = (int) TIMEOUT_node -> var_value -> numbr) <= 0)
snmp_timeout = 1;
if (snmp_id >= 0x7fffffff)
snmp_id = 0;
snmp_id++;
if (snmp_fd == NOTOK || ps == NULLPS)
changed++;
tmp = force_string (AGENT_node -> var_value);
if (snmp_agent == NULL || strcmp (snmp_agent, tmp -> stptr)) {
if (snmp_agent)
free (snmp_agent), snmp_agent = NULL;
emalloc (snmp_agent, char *, strlen (tmp -> stptr) + 1, "snmp_init1");
(void) strcpy (snmp_agent, tmp -> stptr);
changed++;
}
tmp = force_string (COMMUNITY_node -> var_value);
if (snmp_community == NULL || strcmp (snmp_community, tmp -> stptr)) {
register struct type_SNMP_Message *msg = &msgs;
if (snmp_community)
free (snmp_community), snmp_community = NULL;
emalloc (snmp_community, char *, strlen (tmp -> stptr) + 1,
"snmp_init2");
(void) strcpy (snmp_community, tmp -> stptr);
if ((msg -> community = str2qb (snmp_community,
strlen (snmp_community), 1)) == NULL) {
snmp_diag (NULLCP, "str2qb: out of memory");
free (snmp_community), snmp_community = NULL;
return NOTOK;
}
}
if (changed) {
if (ps)
ps_free (ps), ps = NULLPS;
if (snmp_fd != NOTOK)
(void) close_udp_socket (snmp_fd), snmp_fd = NOTOK;
}
else
return OK;
bzero ((char *) lsock, sizeof *lsock);
if ((hp = gethostbystring (pp = strcmp (snmp_agent, "localhost")
? getlocalhost () : "localhost"))
== NULL) {
snmp_diag (NULLCP, "%s: unknown host", pp);
return NOTOK;
}
lsock -> sin_family = hp -> h_addrtype;
inaddr_copy (hp, lsock);
if ((snmp_fd = start_udp_client (lsock, 0, 0, 0)) == NOTOK) {
snmp_diag ("failed", "start_udp_server");
return NOTOK;
}
bzero ((char *) isock, sizeof *isock);
if ((hp = gethostbystring (snmp_agent)) == NULL) {
snmp_diag (NULLCP, "%s: unknown host", snmp_agent);
return NOTOK;
}
isock -> sin_family = hp -> h_addrtype;
isock -> sin_port = (sp = getservbyname ("snmp", "udp"))
? sp -> s_port
: htons ((u_short) 161);
inaddr_copy (hp, isock);
if (join_udp_server (snmp_fd, isock) == NOTOK) {
snmp_diag ("failed", "join_udp_server");
return NOTOK;
}
if ((ps = ps_alloc (dg_open)) == NULLPS
|| dg_setup (ps, snmp_fd, MAXDGRAM, read_udp_socket,
write_udp_socket) == NOTOK) {
if (ps == NULLPS)
snmp_diag (NULLCP, "ps_alloc: out of memory");
else
snmp_diag (NULLCP, "dg_setup: %s", ps_error (ps -> ps_errno));
return NOTOK;
}
#ifndef SYS5
snmp_id = ((int) random ()) & 0x7fffffff;
#else
snmp_id = ((int) rand ()) & 0x7fffffff;
#endif
return OK;
}
/* */
#ifndef lint
static snmp_diag (va_alist)
va_dcl
{
char *what,
buffer[BUFSIZ];
va_list ap;
va_start (ap);
what = va_arg (ap, char *);
_asprintf (buffer, what, ap);
va_end (ap);
if (debug > 0)
fprintf (stderr, "%s\n", buffer);
deref = DIAGNOSTIC_node -> var_value;
do_deref ();
DIAGNOSTIC_node -> var_value = make_string (buffer, strlen (buffer));
}
#else
/* VARARGS */
static snmp_diag (what, fmt)
char *what,
*fmt;
{
snmp_diag (what, fmt);
}
#endif
/* SCAN */
struct search *snmp_assoc_scan (symbol)
NODE *symbol;
{
register struct snmp_search *s;
register OT ot = (OT) symbol -> magic;
register struct type_SNMP_VarBindList **vp;
if (!ot -> ot_getfnx && !snmp_scalars_as_arrays)
fatal ("can't use SNMP scalar variable as control for for-in");
emalloc (s, struct snmp_search *, sizeof *s, "snmp_assoc_scan1");
bzero ((char *) s, sizeof *s);
ot -> ot_name -> oid_nelem--;
s -> s_parent = name2obj (ot -> ot_name);
ot -> ot_name -> oid_nelem++;
if ((ot = s -> s_parent) == NULL)
fatal ("unable to find parent for \"%s\"", snmp_name (symbol));
vp = &s -> s_bindings;
for (ot = ot -> ot_children; ot; ot = ot -> ot_sibling) {
register struct type_SNMP_VarBindList *bind;
register struct type_SNMP_VarBind *v;
if (!ot -> ot_syntax)
continue;
emalloc (bind, struct type_SNMP_VarBindList *, sizeof *bind,
"snmp_assoc_scan2");
*vp = bind, vp = &bind -> next;
bind -> next = NULL;
emalloc (v, struct type_SNMP_VarBind *, sizeof *v, "snmp_assoc_scan3");
bind -> VarBind = v;
if ((v -> name = oid_cpy (ot -> ot_name)) == NULL)
fatal ("oid_cpy: out of memory");
if ((v -> value = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_NULL))
== NULLPE)
fatal ("pe_alloc: out of memory");
}
if (head == NULL)
head = tail = s;
else {
tail -> s_next = s;
s -> s_prev = tail;
tail = s;
}
return snmp_assoc_next (&s -> s_search, 0);
}
/* */
struct search *snmp_assoc_next (lookat, done)
struct search *lookat;
int done;
{
int i;
char *cp;
register struct snmp_search *s = (struct snmp_search *) lookat;
register struct search *l = &s -> s_search;
struct OIDentifier oids;
OID oid;
OT ot = s -> s_parent;
register struct type_SNMP_VarBind *v;
deref = l -> retval, l -> retval = NULL;
do_deref ();
if (done || snmp_get_next (s) == NOTOK || s -> s_bindings == NULL) {
if (s -> s_bindings)
free_SNMP_VarBind (s -> s_bindings);
if (s -> s_pe)
pe_free (s -> s_pe);
if (tail != s)
fatal ("snmp_assoc_next: internal error1");
if (tail = s -> s_prev)
tail -> s_next = NULL;
else
head = NULL;
free ((char *) s);
return NULL;
}
if ((v = s -> s_bindings -> VarBind) == NULL || (oid = v -> name) == NULL)
fatal ("snmp_assoc_next: internal error2");
if (ot -> ot_name -> oid_nelem >= oid -> oid_nelem
|| bcmp ((char *) ot -> ot_name -> oid_elements,
(char *) oid -> oid_elements,
ot -> ot_name -> oid_nelem
* sizeof oid -> oid_elements[0]))
fatal ("snmp_assoc_next: internal error3");
oids.oid_nelem = oid -> oid_nelem - (i = ot -> ot_name -> oid_nelem + 1);
oids.oid_elements = oid -> oid_elements + i;
cp = sprintoid (&oids);
l -> retval = make_string (cp, strlen (cp));
return l;
}
/* */
static int snmp_get_next (s)
register struct snmp_search *s;
{
int gotone,
result = NOTOK,
retries,
status = -1;
struct type_SNMP_Message *msg = &msgs;
register struct type_SNMP_PDU *parm = msg -> data -> un.get__request;
register struct type_SNMP_VarBindList *vp = parm -> variable__bindings,
*vp2,
**vpp;
PE pe = NULLPE,
p = NULLPE;
if (snmp_ready () == NOTOK)
goto out;
msg -> data -> offset = type_SNMP_PDUs_get__next__request;
parm -> request__id = snmp_id;
parm -> variable__bindings = s -> s_bindings;
result = encode_SNMP_Message (&pe, 1, 0, NULLCP, msg);
parm -> variable__bindings = vp;
msg -> data -> offset = type_SNMP_PDUs_get__request;
if (result == NOTOK) {
snmp_diag (NULLCP, "encode_SNMP_Message: %s", PY_pepy);
goto out;
}
result = NOTOK;
msg = NULL, gotone = 0;
for (retries = snmp_retries; retries > 0; ) {
int len;
fd_set rfds;
if (debug > 1)
print_SNMP_Message (pe, 1, NULLIP, NULLVP, NULLCP);
len = ps -> ps_byteno;
if (pe2ps (ps, pe) == NOTOK) {
snmp_diag (NULLCP, "pe2ps: %s", ps_error (ps -> ps_errno));
goto error_x;
}
if (debug > 0 && (len = ps -> ps_byteno - len) > 484)
fprintf (stderr, "sent message of %d octets\n", len);
FD_ZERO (&rfds);
FD_SET (snmp_fd, &rfds);
switch (xselect (snmp_fd + 1, &rfds, NULLFD, NULLFD, snmp_timeout)) {
case NOTOK:
snmp_diag ("failed", "xselect");
goto error_x;
default:
if (FD_ISSET (snmp_fd, &rfds))
break;
/* else fall... */
case OK:
retries--;
continue;
}
if ((p = ps2pe (ps)) == NULLPE) {
snmp_diag (NULLCP, "ps2pe: %s", ps_error (ps -> ps_errno));
goto error_x;
}
if (decode_SNMP_Message (p, 1, NULLIP, NULLVP, &msg) == NOTOK) {
snmp_diag (NULLCP, "decode_SNMP_Message: %s", PY_pepy);
goto out;
}
if (debug > 1)
print_SNMP_Message (p, 1, NULLIP, NULLVP, NULLCP);
if (msg -> data -> offset != type_SNMP_PDUs_get__response) {
snmp_diag (NULLCP, "unexpected message type %d",
msg -> data -> offset);
goto out;
}
if ((parm = msg -> data -> un.get__response) -> request__id == snmp_id)
break;
if (msg)
free_SNMP_Message (msg), msg = NULL;
if (p)
pe_free (p), p = NULLPE;
gotone++;
}
if (retries <= 0) {
snmp_diag (NULLCP,
"no %sresponse within %d retries of %s%d second%s each",
gotone ? "acceptable " : "", snmp_retries + gotone,
gotone ? "upto " : "",
snmp_timeout, snmp_timeout != 1 ? "s" : "");
goto out;
}
if ((status = parm -> error__status) != int_SNMP_error__status_noError) {
char *cp = snmp_variable (parm, parm -> error__index);
snmp_diag (NULLCP, cp ? "%s at position %d (%s)" : "%s at position %d",
snmp_error (status), parm -> error__index,
cp);
goto out;
}
for (vp = s -> s_bindings, vpp = &parm -> variable__bindings;
vp && (vp2 = *vpp);
vp = vp -> next) {
if (name2obj (vp -> VarBind -> name)
!= name2obj (vp2 -> VarBind -> name)) {
*vpp = vp2 -> next;
vp2 -> next = NULL;
free_SNMP_VarBindList (vp2);
}
else
vpp = &vp2 -> next;
}
if (vp) {
snmp_diag (NULLCP, "missing variable in response");
goto out;
}
else
if (vp2 = *vpp) {
if (debug > 0)
fprintf (stderr, "too many responses starting with: %s\n",
oid2ode (vp2 -> VarBind -> name));
*vpp = NULL;
free_SNMP_VarBindList (vp2);
}
if (s -> s_bindings)
free_SNMP_VarBindList (s -> s_bindings);
if (s -> s_pe)
pe_free (s -> s_pe);
s -> s_bindings = parm -> variable__bindings;
parm -> variable__bindings = NULL;
s -> s_pe = p;
p = NULLPE;
result = OK;
goto out;
error_x: ;
if (ps)
ps_free (ps), ps = NULLPS;
if (snmp_fd != NOTOK)
(void) close_udp_socket (snmp_fd), snmp_fd = NOTOK;
out: ;
if (msg && msg != &msgs)
free_SNMP_Message (msg);
if (p)
pe_free (p);
if (pe)
pe_free (pe);
assign_number (&ERROR_node -> var_value, (AWKNUM) status);
return result;
}
/* DECODE */
static NODE *make_octet_node (base, len)
char *base;
int len;
{
register char *bp,
*cp,
*ep;
char *s = "";
register NODE *r;
r = newnode (Node_val);
emalloc (r -> stptr, char *, len * 3 + 1, "make_octet_node");
bp = r -> stptr;
for (ep = (cp = base) + len; cp < ep; cp++, s = ":") {
(void) sprintf (bp, "%s%02x", s, *cp & 0xff);
bp += strlen (bp);
}
*bp = NULL; /* in case len == 0 */
r -> stlen = bp - r -> stptr;
r -> stref = 1;
r -> flags |= STR | MALLOC;
return r;
}
static int f_integer (x, pe)
NODE **x;
PE pe;
{
integer i = prim2num (pe);
if (i == NOTOK && pe -> pe_errno != PE_ERR_NONE) {
(void) strcpy (PY_pepy, pe_error (pe -> pe_errno));
return NOTOK;
}
*x = make_number ((AWKNUM) i);
return OK;
}
static int f_octets (x, pe)
NODE **x;
PE pe;
{
struct qbuf *qb = prim2qb (pe);
if (qb == NULL|| qb_pullup (qb) == NOTOK) {
(void) strcpy (PY_pepy, qb ? "qb_pullup: out of memory"
: pe_error (pe -> pe_errno));
return NOTOK;
}
*x = make_octet_node (qb -> qb_forw -> qb_data, qb -> qb_forw -> qb_len);
qb_free (qb);
return OK;
}
static int f_display (x, pe)
NODE **x;
PE pe;
{
struct qbuf *qb = prim2qb (pe);
if (qb == NULL|| qb_pullup (qb) == NOTOK) {
(void) strcpy (PY_pepy, qb ? "qb_pullup: out of memory"
: pe_error (pe -> pe_errno));
return NOTOK;
}
*x = make_string (qb -> qb_forw -> qb_data, qb -> qb_forw -> qb_len);
qb_free (qb);
return OK;
}
static int f_objectID (x, pe)
NODE **x;
PE pe;
{
char *cp;
OID oid = prim2oid (pe);
if (oid == NULLOID) {
(void) strcpy (PY_pepy, pe_error (pe -> pe_errno));
return NOTOK;
}
cp = sprintoid (oid);
*x = make_string (cp, strlen (cp));
return OK;
}
/* ARGSUSED */
static int f_null (x, pe)
NODE **x;
PE pe;
{
*x = make_str_node ("NULL", 4, 0);
return OK;
}
static int f_ipaddr (x, pe)
NODE **x;
PE pe;
{
char ipaddr[16];
struct type_SNMP_IpAddress *ip;
struct qbuf *qb;
if (decode_SNMP_IpAddress (pe, 1, NULLIP, NULLVP, &ip) == NOTOK)
return NOTOK;
if (qb_pullup (ip) == NOTOK) {
(void) strcpy (PY_pepy, "qb_pullup: out of memory");
free_SNMP_IpAddress (ip);
return NOTOK;
}
if ((qb = ip -> qb_forw) -> qb_len != 4) {
(void) sprintf (PY_pepy,
"IpAddress is wrong length (got %d, wanted 4)",
qb -> qb_len);
free_SNMP_IpAddress (ip);
return NOTOK;
}
(void) sprintf (ipaddr, "%d.%d.%d.%d",
qb -> qb_data[0] & 0xff, qb -> qb_data[1] & 0xff,
qb -> qb_data[2] & 0xff, qb -> qb_data[3] & 0xff);
*x = make_str_node (ipaddr, strlen (ipaddr), 0);
free_SNMP_IpAddress (ip);
return OK;
}
static int f_clnpaddr (x, pe)
NODE **x;
PE pe;
{
int len;
struct type_SNMP_ClnpAddress *clnp;
struct qbuf *qb;
if (decode_SNMP_ClnpAddress (pe, 1, NULLIP, NULLVP, &clnp) == NOTOK)
return NOTOK;
if (qb_pullup (clnp) == NOTOK) {
(void) strcpy (PY_pepy, "qb_pullup: out of memory");
free_SNMP_ClnpAddress (clnp);
return NOTOK;
}
qb = clnp -> qb_forw;
if ((len = qb -> qb_data[0] & 0xff) >= qb -> qb_len)
len = qb -> qb_len - 1;
*x = make_octet_node (qb -> qb_data, len);
free_SNMP_ClnpAddress (clnp);
return OK;
}
/* MISC */
char *snmp_name (ptr)
NODE *ptr;
{
return ((OT) (ptr -> magic)) -> ot_text;
}
/* */
static char *errors[] = {
"noError", "tooBig", "noSuchName", "badValue", "readOnly", "genErr"
};
static char *snmp_error (i)
int i;
{
static char buffer[BUFSIZ];
if (0 < i && i < sizeof errors / sizeof errors[0])
return errors[i];
(void) sprintf (buffer, "error %d", i);
return buffer;
}
static char *snmp_variable (parm, index)
register struct type_SNMP_PDU *parm;
int index;
{
register struct type_SNMP_VarBindList *vp;
if (index <= 0 || (vp = parm -> variable__bindings) == NULL)
return NULL;
for (index--; index > 0; index--)
if ((vp = vp -> next) == NULL)
return NULL;
return oid2ode (vp -> VarBind -> name);
}
#endif /* SNMP */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.