📄 snmp.c
字号:
assign_number (&ERROR_node -> var_value, (AWKNUM) status);}/* SCAN */struct search *snmp_assoc_scan (symbol, instance)NODE *symbol, *instance;{ register struct snmp_search *s; OID inst; register OT ot = (OT) symbol -> magic; register struct type_SNMP_VarBindList **vp, **vp2; if (!ot -> ot_getfnx && (!snmp_scalars_as_arrays || instance)) fatal ("can't use SNMP scalar variable as control for for-in"); if (instance) { char *instname; NODE *r; if ((r = instance) -> type != Node_val) r = r_tree_eval (instance); if ((inst = str2oid (instname = force_string (r) -> stptr)) == NULL) { snmp_diag (NULLCP, "str2oid: bad instance identifier \"%s\"", instname); free_temp (r); return NULL; } if (r != instance) free_temp (r); } else inst = NULL; 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)); s -> s_prototype = NULL; vp = &s -> s_reqs[0].r_bindings, vp2 = &s -> s_prototype; for (ot = ot -> ot_children; ot; ot = ot -> ot_sibling) { register int i; register unsigned int *ip, *jp; register struct type_SNMP_VarBindList *bind; register struct type_SNMP_VarBind *v, *v2; 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 (inst) { if ((v -> name = oid_extend (ot -> ot_name, inst -> oid_nelem)) == NULL) fatal ("oid_extend: out of memory"); ip = v -> name -> oid_elements + v -> name -> oid_nelem - inst -> oid_nelem; jp = inst -> oid_elements; for (i = inst -> oid_nelem; i > 0; i--) *ip++ = *jp++; } else if ((v -> name = oid_cpy (ot -> ot_name)) == NULL) fatal ("oid_cpy: out of memory"); v -> value = NULL; emalloc (bind, struct type_SNMP_VarBindList *, sizeof *bind, "snmp_assoc_scan4"); *vp2 = bind, vp2 = &bind -> next; bind -> next = NULL; emalloc (v2, struct type_SNMP_VarBind *, sizeof *v2, "snmp_assoc_scan5"); bind -> VarBind = v2; if ((v2 -> name = oid_cpy (v -> name)) == NULL) fatal ("oid_cpy: out of memory"); v2 -> value = NULL; } 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; do_deref (); l -> retval = NULL; if (done || snmp_get_next (s) == NOTOK || s -> s_reqs[0].r_bindings == NULL) { register struct snmp_req *sr; if (s -> s_prototype) free_SNMP_VarBindList (s -> s_prototype); for (sr = s -> s_reqs; sr -> r_bindings; sr++) { free_SNMP_VarBindList (sr -> r_bindings); if (sr -> r_pb) pe_free (sr -> r_pb); if (sr -> r_msg) free_SNMP_Message (sr -> r_msg); if (sr -> r_pe) pe_free (sr -> r_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_reqs[0].r_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;{ register struct type_SNMP_VarBindList *vp, *vp2, **vpp, **vpp2; register struct snmp_req *sr, *sp; if (snmp_ready (0) == NOTOK || snmp_get_next_aux (s) == NOTOK) return NOTOK; vpp = &s -> s_prototype, vp = NULL; for (sr = s -> s_reqs; sr -> r_bindings; sr++) { vpp2 = &sr -> r_msg -> data -> un.get__request -> variable__bindings; while ((vp = *vpp) && (vp2 = *vpp2)) { OID v = vp -> VarBind -> name, v2 = vp2 -> VarBind -> name; if (v -> oid_nelem > v2 -> oid_nelem || bcmp ((char *) v -> oid_elements, (char *) v2 -> oid_elements, v -> oid_nelem * sizeof v -> oid_elements[0])) { *vpp = vp -> next; vp -> next = NULL; free_SNMP_VarBindList (vp); *vpp2 = vp2 -> next; vp2 -> next = NULL; free_SNMP_VarBindList (vp2); } else vpp = &vp -> next, vpp2 = &vp2 -> next; } if (vp == NULL && (vp2 = *vpp)) { snmp_diag (NULLCP, "too many responses starting with: %s\n", oid2ode (vp2 -> VarBind -> name)); return NOTOK; } } if (vp) { snmp_diag (NULLCP, "missing variable in response"); return NOTOK; } for (sp = s -> s_reqs; sp < sr; sp++) { if (sp -> r_bindings) free_SNMP_VarBindList (sp -> r_bindings); if (sp -> r_pb) pe_free (sp -> r_pb); if (sp -> r_bindings && sp -> r_msg -> data -> un.get__request -> variable__bindings) { sp -> r_bindings = sp -> r_msg -> data -> un.get__request -> variable__bindings; sp -> r_msg -> data -> un.get__request -> variable__bindings =NULL; sp -> r_pb = sp -> r_pe, sp -> r_pe = NULL; free_SNMP_Message (sp -> r_msg), sp -> r_msg = NULL; continue; } if (sp -> r_msg) free_SNMP_Message (sp -> r_msg); if (sp -> r_pe) pe_free (sp -> r_pe); bzero ((char *) sp, sizeof *sp); } for (sr--; sr >= s -> s_reqs; sr--) if (sr -> r_bindings) for (sp = s -> s_reqs; sp < sr; sp++) if (!sp -> r_bindings) { *sp = *sr; /* struct copy */ bzero ((char *) sr, sizeof *sr); break; } return OK;}/* */static int snmp_get_next_aux (s)register struct snmp_search *s;{ int gotone, result, retries, status = -1; struct type_SNMP_Message *msg; register struct type_SNMP_PDU *parm; struct type_SNMP_VarBindList *vp; register struct snmp_req *sr; PE p = NULLPE; vp = msgs.data -> un.get__request -> variable__bindings; msgs.data -> offset = type_SNMP_PDUs_get__next__request; for (sr = s -> s_reqs; sr -> r_bindings; sr++) if ((result = req_ready (sr, 1)) == NOTOK) break; msgs.data -> un.get__request -> variable__bindings = vp; msgs.data -> offset = type_SNMP_PDUs_get__request; if (result == NOTOK) { snmp_diag (NULLCP, "encode_SNMP_Message: %s", PY_pepy); return NOTOK; } msg = NULL, gotone = 0; for (retries = snmp_retries; retries > 0; ) { int len; fd_set rfds; for (sr = s -> s_reqs; sr -> r_bindings; sr++) { if (sr -> r_msg) continue; if (debug > 1) print_SNMP_Message (sr -> r_pe, 1, NULLIP, NULLVP, NULLCP); len = ps -> ps_byteno; if (pe2ps (ps, sr -> r_pe) == NOTOK) { snmp_diag (NULLCP, "pe2ps: %s", ps_error (ps -> ps_errno)); goto error_x; } if ((sr -> r_toobig = ((len = ps -> ps_byteno - len) > 484)) && debug > 0) 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: for (sr = s -> s_reqs; sr -> r_bindings; sr++) if (sr -> r_toobig) goto make_smaller; retries--; continue; }again: ; 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; } gotone++; parm = msg -> data -> un.get__response; for (sr = s -> s_reqs; sr -> r_bindings; sr++) if (parm -> request__id == sr -> r_id) break; if (!sr -> r_bindings || sr -> r_msg) { if (debug > 0) fprintf (stderr, "%s response ID (got %ld)\n", sr -> r_bindings ? "duplicate" : "unexpected", (long) parm -> request__id); if (msg) free_SNMP_Message (msg), msg = NULL; if (p) pe_free (p), p = NULLPE; goto check; } switch (status = parm -> error__status) { case int_SNMP_error__status_noError: break; case int_SNMP_error__status_tooBig: { register int i; register struct type_SNMP_VarBindList **vpp; register struct snmp_req *sp; struct snmp_req *sz;make_smaller: ; i = 0; for (vp = sr -> r_bindings; vp; vp = vp -> next) i++; if ((i >>= 1) < 1) { snmp_diag (NULLCP, "%s for request with single variable", snmp_error (status)); goto out; } sz = s -> s_reqs + NREQ; for (sp = sr + 1; sp -> r_bindings; sp++) if (sp >= sz) { snmp_diag (NULLCP, "too many operations needed (%d max)", NREQ - 1); goto out; } for (sz = sr + 1; sp > sz; sp--) *sp = *(sp - 1); /* struct copy */ bzero ((char *) sp, sizeof *sp); for (vpp = &sr -> r_bindings; i-- > 0; vpp = &((*vpp) -> next)) continue; sp -> r_bindings = *vpp, *vpp = NULL; vp = msgs.data -> un.get__request -> variable__bindings; msgs.data -> offset = type_SNMP_PDUs_get__next__request; if ((result = req_ready (sr, 0)) != NOTOK) result = req_ready (sp, 0); msgs.data -> un.get__request -> variable__bindings = vp; msgs.data -> offset = type_SNMP_PDUs_get__request; if (result == NOTOK) { snmp_diag (NULLCP, "encode_SNMP_Message: %s", PY_pepy); goto out; } retries = snmp_retries; } goto check; default: { 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; } pe_free (sr -> r_pe); sr -> r_pe = p, p = NULLPE; sr -> r_msg = msg, msg = NULL; for (sr = s -> s_reqs; sr -> r_bindings; sr++) if (!sr -> r_msg) break; if (!sr -> r_bindings) { assign_number (&ERROR_node -> var_value, (AWKNUM) status); return OK; }check: ; FD_ZERO (&rfds); FD_SET (snmp_fd, &rfds); if (select_dgram_socket (snmp_fd + 1, &rfds, NULLFD, NULLFD, 1) > OK) goto again; } snmp_diag (NULLCP, "no %sresponse within %d retries of %s%d second%s each", gotone ? "acceptable " : "", snmp_retries + gotone, gotone ? "up to " : "", snmp_timeout, snmp_timeout != 1 ? "s" : ""); return NOTOK;error_x: ; if (ps) ps_free (ps), ps = NULLPS; if (snmp_fd != NOTOK) (void) close_udp_socket (snmp_fd), snmp_fd = NOTOK;out: ; if (p) pe_free (p); return NOTOK;}/* */static int req_ready (sr, do_val)register struct snmp_req *sr;int do_val;{ register struct type_SNMP_Message *msg = &msgs; register struct type_SNMP_PDU *parm = msg -> data -> un.get__request; if (do_val) { register struct type_SNMP_VarBindList *vp; for (vp = sr -> r_bindings; vp; vp = vp -> next) { register struct type_SNMP_VarBind *v = vp -> VarBind; if (v -> value) pe_free (v -> value); if ((v -> value = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_NULL)) == NULLPE) fatal ("pe_alloc: out of memory"); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -