int mp_snmp_subtree_get_value(const mp_snmp_subtree *subtree, const oid *oid_prefix, const size_t oid_prefix_len, const size_t idx, const u_char type, void **target, const size_t target_len) { size_t i, j = 0; if (!subtree || (subtree->size < 1)) return 0; for (i = 0; i < subtree->size; i++) { if (snmp_oidtree_compare(oid_prefix, oid_prefix_len, subtree->vars[i]->name, subtree->vars[i]->name_length) == 0) { if (j == idx) { return copy_value(subtree->vars[i], type, target_len, target); } j++; } } return 0; }
int netsnmp_tdata_compare_subtree_oid(netsnmp_tdata_row *row, oid * compareto, size_t compareto_len) { netsnmp_index *index = (netsnmp_index *)row; return snmp_oidtree_compare( index->oids, index->len, compareto, compareto_len); }
int setPass(int action, u_char * var_val, u_char var_val_type, size_t var_val_len, u_char * statP, oid * name, size_t name_len) { int i, rtest; struct extensible *passthru; char buf[SNMP_MAXBUF], buf2[SNMP_MAXBUF]; for (i = 1; i <= numpassthrus; i++) { passthru = get_exten_instance(passthrus, i); rtest = snmp_oidtree_compare(name, name_len, passthru->miboid, passthru->miblen); if (rtest <= 0) { if (action != ACTION) return SNMP_ERR_NOERROR; /* * setup args */ if (passthru->miblen >= name_len || rtest < 0) sprint_mib_oid(buf, passthru->miboid, passthru->miblen); else sprint_mib_oid(buf, name, name_len); snprintf(passthru->command, sizeof(passthru->command), "%s -s %s ", passthru->name, buf); passthru->command[ sizeof(passthru->command)-1 ] = 0; netsnmp_internal_pass_set_format(buf, var_val, var_val_type, var_val_len); strlcat(passthru->command, buf, sizeof(passthru->command)); DEBUGMSGTL(("ucd-snmp/pass", "pass-running: %s", passthru->command)); exec_command(passthru); DEBUGMSGTL(("ucd-snmp/pass", "pass-running returned: %s", passthru->output)); return netsnmp_internal_pass_str_to_errno(passthru->output); } } if (snmp_get_do_debugging()) { sprint_mib_oid(buf2, name, name_len); DEBUGMSGTL(("ucd-snmp/pass", "pass-notfound: %s\n", buf2)); } return SNMP_ERR_NOSUCHNAME; }
int mp_snmp_subtree_query(netsnmp_session *ss, const oid *subtree_oid, const size_t subtree_len, mp_snmp_subtree *subtree) { oid last_oid[MAX_OID_LEN]; size_t last_len; netsnmp_pdu *request = NULL; netsnmp_pdu *response = NULL; netsnmp_variable_list *var; size_t alloc_size = 0; int rc; /* prepare result */ memset(subtree, '\0', sizeof(*subtree)); subtree->vars = NULL; memcpy(last_oid, subtree_oid, subtree_len * sizeof(oid)); last_len = subtree_len; for (;;) { /* * setup request */ if (ss->version == SNMP_VERSION_1) { request = snmp_pdu_create(SNMP_MSG_GETNEXT); } else { request = snmp_pdu_create(SNMP_MSG_GETBULK); request->non_repeaters = 0; request->max_repetitions = 16; } snmp_add_null_var(request, last_oid, last_len); /* * commence request */ if (response) { snmp_free_pdu(response); response = NULL; } if (mp_verbose > 2) { char buf[128]; snprint_objid((char *) &buf, sizeof(buf), last_oid, last_len); printf("Fetching next from OID %s\n", buf); } rc = snmp_synch_response(ss, request, &response); if (mp_verbose > 3) printf("snmp_synch_response(): rc=%d, errstat=%ld\n", rc, response->errstat); if ((rc == STAT_SUCCESS) && response) { if (response->errstat == SNMP_ERR_NOERROR) { /* * loop over results (may only be one result in case of SNMP v1) */ for (var = response->variables; var; var = var->next_variable) { /* * check, if OIDs are incresing to prevent infinite * loop with broken SNMP agents */ if (snmp_oidtree_compare(var->name, var->name_length, last_oid, last_len) < 0) { if (response) snmp_free_pdu(response); mp_snmp_deinit(); critical("SNMP error: OIDs are not incresing"); } /* * terminate, if oid does not belong to subtree anymore */ if ((var->type == SNMP_ENDOFMIBVIEW) || (snmp_oidtree_compare(subtree_oid, subtree_len, var->name, var->name_length) != 0)) { snmp_free_pdu(response); return rc; } if (mp_verbose > 2) print_variable(var->name, var->name_length, var); if (var->type != SNMP_NOSUCHOBJECT || var->type != SNMP_NOSUCHINSTANCE) { if (alloc_size <= subtree->size) { alloc_size += 16; subtree->vars = mp_realloc(subtree->vars, alloc_size * sizeof(netsnmp_variable_list*)); } subtree->vars[subtree->size] = mp_malloc(sizeof(netsnmp_variable_list)); snmp_clone_var(var, subtree->vars[subtree->size]); subtree->size++; } /* * save last fetched oid */ memcpy(last_oid, var->name, var->name_length * sizeof(oid)); last_len = var->name_length; } /* for */ } else if ((ss->version == SNMP_VERSION_1) && (response->errstat == SNMP_ERR_NOSUCHNAME)) { if (mp_verbose > 3) printf("SNMP-V1: end of tree\n"); } else { /* * some other error occured */ if (mp_verbose > 0) printf("SNMP error: respose->errstat = %ld", response->errstat); rc = STAT_ERROR; //goto done; break; } } else { /* no response, assume an error */ rc = STAT_ERROR; break; } } if (response) snmp_free_pdu(response); return rc; }
int setPassPersist(int action, u_char * var_val, u_char var_val_type, size_t var_val_len, u_char * statP, oid * name, size_t name_len) { int i, rtest; struct extensible *persistpassthru; char buf[SNMP_MAXBUF], buf2[SNMP_MAXBUF]; /* * Make sure that our basic pipe structure is malloced */ init_persist_pipes(); for (i = 1; i <= numpersistpassthrus; i++) { persistpassthru = get_exten_instance(persistpassthrus, i); rtest = snmp_oidtree_compare(name, name_len, persistpassthru->miboid, persistpassthru->miblen); if (rtest <= 0) { if (action != ACTION) return SNMP_ERR_NOERROR; /* * setup args */ if (persistpassthru->miblen >= name_len || rtest < 0) sprint_mib_oid(buf, persistpassthru->miboid, persistpassthru->miblen); else sprint_mib_oid(buf, name, name_len); snprintf(persistpassthru->command, sizeof(persistpassthru->command), "set\n%s\n", buf); persistpassthru->command[ sizeof(persistpassthru->command)-1 ] = 0; netsnmp_internal_pass_set_format(buf, var_val, var_val_type, var_val_len); strlcat(persistpassthru->command, buf, sizeof(persistpassthru->command)); persistpassthru->command[ sizeof(persistpassthru->command)-2 ] = '\n'; persistpassthru->command[ sizeof(persistpassthru->command)-1 ] = 0; if (!open_persist_pipe(i, persistpassthru->name)) { return SNMP_ERR_NOTWRITABLE; } DEBUGMSGTL(("ucd-snmp/pass_persist", "persistpass-writing: %s\n", persistpassthru->command)); if (!write_persist_pipe(i, persistpassthru->command)) { close_persist_pipe(i); return SNMP_ERR_NOTWRITABLE; } if (fgets(buf, sizeof(buf), persist_pipes[i].fIn) == NULL) { close_persist_pipe(i); return SNMP_ERR_NOTWRITABLE; } return netsnmp_internal_pass_str_to_errno(buf); } } if (snmp_get_do_debugging()) { sprint_mib_oid(buf2, name, name_len); DEBUGMSGTL(("ucd-snmp/pass_persist", "persistpass-notfound: %s\n", buf2)); } return SNMP_ERR_NOSUCHNAME; }
u_char * var_extensible_pass_persist(struct variable *vp, oid * name, size_t * length, int exact, size_t * var_len, WriteMethod ** write_method) { oid newname[MAX_OID_LEN]; int i, rtest, newlen; char buf[SNMP_MAXBUF]; static char buf2[SNMP_MAXBUF]; struct extensible *persistpassthru; FILE *file; /* * Make sure that our basic pipe structure is malloced */ init_persist_pipes(); for (i = 1; i <= numpersistpassthrus; i++) { persistpassthru = get_exten_instance(persistpassthrus, i); rtest = snmp_oidtree_compare(name, *length, persistpassthru->miboid, persistpassthru->miblen); if ((exact && rtest == 0) || (!exact && rtest <= 0)) { /* * setup args */ if (persistpassthru->miblen >= *length || rtest < 0) sprint_mib_oid(buf, persistpassthru->miboid, persistpassthru->miblen); else sprint_mib_oid(buf, name, *length); /* * Open our pipe if necessary */ if (!open_persist_pipe(i, persistpassthru->name)) { return (NULL); } if (exact) snprintf(persistpassthru->command, sizeof(persistpassthru->command), "get\n%s\n", buf); else snprintf(persistpassthru->command, sizeof(persistpassthru->command), "getnext\n%s\n", buf); persistpassthru->command[ sizeof(persistpassthru->command)-1 ] = 0; DEBUGMSGTL(("ucd-snmp/pass_persist", "persistpass-sending:\n%s", persistpassthru->command)); if (!write_persist_pipe(i, persistpassthru->command)) { *var_len = 0; /* * close_persist_pipes is called in write_persist_pipe */ return (NULL); } /* * valid call. Exec and get output */ if ((file = persist_pipes[i].fIn)) { if (fgets(buf, sizeof(buf), file) == NULL) { *var_len = 0; close_persist_pipe(i); return (NULL); } /* * persistent scripts return "NONE\n" on invalid items */ if (!strncmp(buf, "NONE", 4)) { if (exact) { *var_len = 0; return (NULL); } continue; } newlen = parse_miboid(buf, newname); /* * its good, so copy onto name/length */ memcpy((char *) name, (char *) newname, (int) newlen * sizeof(oid)); *length = newlen; /* * set up return pointer for setable stuff */ *write_method = setPassPersist; if (newlen == 0 || fgets(buf, sizeof(buf), file) == NULL || fgets(buf2, sizeof(buf2), file) == NULL) { *var_len = 0; close_persist_pipe(i); return (NULL); } return netsnmp_internal_pass_parse(buf, buf2, var_len, vp); } *var_len = 0; return (NULL); } } if (var_len) *var_len = 0; *write_method = NULL; return (NULL); }
u_char * var_extensible_pass(struct variable *vp, oid * name, size_t * length, int exact, size_t * var_len, WriteMethod ** write_method) { oid newname[MAX_OID_LEN]; int i, rtest, fd, newlen; char buf[SNMP_MAXBUF]; static char buf2[SNMP_MAXBUF]; struct extensible *passthru; FILE *file; for (i = 1; i <= numpassthrus; i++) { passthru = get_exten_instance(passthrus, i); rtest = snmp_oidtree_compare(name, *length, passthru->miboid, passthru->miblen); if ((exact && rtest == 0) || (!exact && rtest <= 0)) { /* * setup args */ if (passthru->miblen >= *length || rtest < 0) sprint_mib_oid(buf, passthru->miboid, passthru->miblen); else sprint_mib_oid(buf, name, *length); if (exact) snprintf(passthru->command, sizeof(passthru->command), "%s -g %s", passthru->name, buf); else snprintf(passthru->command, sizeof(passthru->command), "%s -n %s", passthru->name, buf); passthru->command[ sizeof(passthru->command)-1 ] = 0; DEBUGMSGTL(("ucd-snmp/pass", "pass-running: %s\n", passthru->command)); /* * valid call. Exec and get output */ if ((fd = get_exec_output(passthru)) != -1) { file = fdopen(fd, "r"); if (fgets(buf, sizeof(buf), file) == NULL) { fclose(file); wait_on_exec(passthru); if (exact) { /* * to enable creation */ *write_method = setPass; *var_len = 0; return (NULL); } continue; } newlen = parse_miboid(buf, newname); /* * its good, so copy onto name/length */ memcpy((char *) name, (char *) newname, (int) newlen * sizeof(oid)); *length = newlen; /* * set up return pointer for setable stuff */ *write_method = setPass; if (newlen == 0 || fgets(buf, sizeof(buf), file) == NULL || fgets(buf2, sizeof(buf2), file) == NULL) { *var_len = 0; fclose(file); wait_on_exec(passthru); return (NULL); } fclose(file); wait_on_exec(passthru); return netsnmp_internal_pass_parse(buf, buf2, var_len, vp); } *var_len = 0; return (NULL); } } if (var_len) *var_len = 0; *write_method = NULL; return (NULL); }