📄 snmp.c
字号:
/* snmp.c - SNMP changes for gawk */#ifndef lintstatic char *rcsid = "$Header: /a/vulcan/xtel/isode/isode-master/snmp/gawk-2.11/RCS/snmp.c,v 8.0 91/07/17 13:02:46 isode Rel $";#endif/* * $Header: /a/vulcan/xtel/isode/isode-master/snmp/gawk-2.11/RCS/snmp.c,v 8.0 91/07/17 13:02:46 isode Rel $ * * * $Log$ *//* * 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/pepsy/SNMP-types.h>#include <isode/dgram.h>#include <isode/internet.h>#include <isode/isoaddrs.h>#include <isode/tailor.h>/* DATA */int debug = 0;int snmp_enabled = 1;int snmp_scalars_as_arrays = 1;static integer snmp_id = 0;static int snmp_portno = 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;NODE *SET_node;NODE *SET_inst;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 element in struct */ OT s_parent; struct type_SNMP_VarBindList *s_prototype;#define NREQ 10 struct snmp_req { struct type_SNMP_VarBindList *r_bindings; PE r_pb; integer r_id; PE r_pe; struct type_SNMP_Message *r_msg; int r_toobig; } s_reqs[NREQ]; struct snmp_search *s_prev; struct snmp_search *s_next;};static struct snmp_search *head = NULL;static struct snmp_search *tail = NULL;static snmp_onceonly (), snmp_get_next (), snmp_get_next_aux (), req_ready (), snmp_ready (), snmp_map (), snmp_diag ();char *snmp_error (), *snmp_variable ();NODE *node ();#ifndef SYS5long random ();#endif/* INIT */int snmp_init (){ char *addr; register struct hostent *hp; struct sockaddr_in lo_socket; snmp_onceonly (); if (lookup (variables, "AGENT") || !(hp = gethostbystring (getlocalhost ()))) return 1; inaddr_copy (hp, &lo_socket); addr = inet_ntoa (lo_socket.sin_addr); AGENT_node = install (variables, "AGENT", node (make_string (addr, strlen (addr)), Node_var, (NODE *) NULL)); return 0;}/* */int e_integer (), e_octets (), e_display (), e_objectID (), e_null (), e_counter (), e_gauge (), e_timeticks (), e_ipaddr (), e_clnpaddr ();int d_integer (), d_octets (), d_display (), d_objectID (), d_null (), d_ulong (), d_ipaddr (), d_clnpaddr ();static struct pair { char *pp_name; IFP pp_encode; IFP pp_decode;} pairs[] = { "INTEGER", e_integer, d_integer, "Services", e_integer, d_integer, "Privileges", e_integer, d_integer, "OctetString", e_octets, d_octets, "DisplayString", e_display, d_display, "PhysAddress", e_octets, d_octets, "ObjectID", e_objectID, d_objectID, "NULL", e_null, d_null, "IpAddress", e_ipaddr, d_ipaddr, "NetworkAddress", e_ipaddr, d_ipaddr, "Counter", e_counter, d_ulong, "Gauge", e_gauge, d_ulong, "TimeTicks", e_timeticks, d_ulong, "ClnpAddress", e_clnpaddr, d_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; SET_node = SET_inst = NULL; { char *cp = getenv ("MIBDEFS"); if (loadobjects (cp) == NOTOK) fatal ("loadobjects: %s", PY_pepy); } /* mark entries that are actually columns! */ for (ot = text2obj ("ccitt"); 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) break; if (ot2) continue; for (ot2 = ot -> ot_children; ot2; ot2 = ot2 -> ot_sibling) if (ot2 -> ot_syntax) ot2 -> ot_getfnx = (IFP) 1; else if (debug > 0) fprintf (stderr, "no syntax for columnar object \"%s\"\n", ot -> ot_text); } 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_encode = pp -> pp_encode; os -> os_decode = pp -> pp_decode; } 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}/* CHECK */int snmp_check (r, name)NODE *r;char *name;{ char c; register char *cp; OT ot; 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;}/* 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 (1) == 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 snmp_req *sr; 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 (sr = s -> s_reqs; sr -> r_bindings; sr++) { register struct type_SNMP_VarBindList *vp; for (vp = sr -> r_bindings; vp; vp = vp -> next) { if (ot -> ot_name -> oid_nelem >= (v = vp -> VarBind) -> 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 %ld, wanted %ld)\n", (long) parm -> request__id, (long) 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 starting with: %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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -