void extensible_parse_config(const char *token, char *cptr) { struct extensible *ptmp, **pp; char *tcptr; int scount; /* * allocate and clear memory structure */ ptmp = (struct extensible *) calloc(1, sizeof(struct extensible)); if (ptmp == NULL) return; /* XXX memory alloc error */ if (*cptr == '.') cptr++; if (isdigit(*cptr)) { /* * its a relocatable extensible mib */ config_perror("WARNING: This output format is not valid, and is only retained for backward compatibility - Please consider using the 'extend' directive instead" ); for (pp = &relocs, numrelocs++; *pp; pp = &((*pp)->next)); (*pp) = ptmp; pp = &relocs; scount = numrelocs; } else { /* * it goes in with the general extensible table */ for (pp = &extens, numextens++; *pp; pp = &((*pp)->next)); (*pp) = ptmp; pp = &extens; scount = numextens; } /* * the rest is pretty much handled the same */ if (!strncasecmp(token, "sh", 2)) ptmp->type = SHPROC; else ptmp->type = EXECPROC; if (isdigit(*cptr)) { ptmp->miblen = parse_miboid(cptr, ptmp->miboid); while (isdigit(*cptr) || *cptr == '.') cptr++; } /* * name */ cptr = skip_white(cptr); copy_nword(cptr, ptmp->name, sizeof(ptmp->name)); cptr = skip_not_white(cptr); cptr = skip_white(cptr); /* * command */ if (cptr == NULL) { config_perror("No command specified on line"); } else { /* * Support multi-element commands in shell configuration * lines, but truncate after the first command for 'exec' */ for (tcptr = cptr; *tcptr != 0 && *tcptr != '#'; tcptr++) if (*tcptr == ';' && ptmp->type == EXECPROC) break; sprintf(ptmp->command, "%.*s", (int) (tcptr - cptr), cptr); } #ifdef NETSNMP_EXECFIXCMD sprintf(ptmp->fixcmd, NETSNMP_EXECFIXCMD, ptmp->name); #endif if (ptmp->miblen > 0) { /* * For relocatable "exec" entries, * register the new (not-strictly-valid) MIB subtree... */ register_mib(token, (struct variable *) extensible_relocatable_variables, sizeof(struct variable2), sizeof(extensible_relocatable_variables) / sizeof(*extensible_relocatable_variables), ptmp->miboid, ptmp->miblen); /* * ... and ensure the entries are sorted by OID. * This isn't needed for entries in the main extTable (which * don't have MIB OIDs explicitly associated with them anyway) */ if (scount > 1 && pp != &extens) { int i; struct extensible **etmp = (struct extensible **) malloc(((sizeof(struct extensible *)) * scount)); if (etmp == NULL) return; /* XXX memory alloc error */ for (i = 0, ptmp = *pp; i < scount && ptmp != 0; i++, ptmp = ptmp->next) etmp[i] = ptmp; qsort(etmp, scount, sizeof(struct extensible *), pass_compare); *pp = (struct extensible *) etmp[0]; ptmp = (struct extensible *) etmp[0]; for (i = 0; i < scount - 1; i++) { ptmp->next = etmp[i + 1]; ptmp = ptmp->next; } ptmp->next = NULL; free(etmp); } } }
void pass_persist_parse_config(const char *token, char *cptr) { struct extensible **ppass = &persistpassthrus, **etmp, *ptmp; char *tcptr, *endopt; int i; long int priority; /* * options */ priority = DEFAULT_MIB_PRIORITY; while (*cptr == '-') { cptr++; switch (*cptr) { case 'p': /* change priority level */ cptr++; cptr = skip_white(cptr); if (! isdigit((unsigned char)(*cptr))) { config_perror("priority must be an integer"); return; } priority = strtol((const char*) cptr, &endopt, 0); if ((priority == LONG_MIN) || (priority == LONG_MAX)) { config_perror("priority under/overflow"); return; } cptr = endopt; cptr = skip_white(cptr); break; default: config_perror("unknown option for pass directive"); return; } } /* * MIB */ if (*cptr == '.') cptr++; if (!isdigit((unsigned char)(*cptr))) { config_perror("second token is not a OID"); return; } numpersistpassthrus++; while (*ppass != NULL) ppass = &((*ppass)->next); (*ppass) = (struct extensible *) malloc(sizeof(struct extensible)); if (*ppass == NULL) return; (*ppass)->type = PASSTHRU_PERSIST; (*ppass)->miblen = parse_miboid(cptr, (*ppass)->miboid); while (isdigit((unsigned char)(*cptr)) || *cptr == '.') cptr++; /* * path */ cptr = skip_white(cptr); if (cptr == NULL) { config_perror("No command specified on pass_persist line"); (*ppass)->command[0] = 0; } else { for (tcptr = cptr; *tcptr != 0 && *tcptr != '#' && *tcptr != ';'; tcptr++); sprintf((*ppass)->command, "%.*s", (int) (tcptr - cptr), cptr); } strlcpy((*ppass)->name, (*ppass)->command, sizeof((*ppass)->name)); (*ppass)->next = NULL; register_mib_priority("pass_persist", (struct variable *) extensible_persist_passthru_variables, sizeof(struct variable2), 1, (*ppass)->miboid, (*ppass)->miblen, priority); /* * argggg -- pasthrus must be sorted */ if (numpersistpassthrus > 1) { etmp = (struct extensible **) malloc(((sizeof(struct extensible *)) * numpersistpassthrus)); if (etmp == NULL) return; for (i = 0, ptmp = (struct extensible *) persistpassthrus; i < numpersistpassthrus && ptmp != NULL; i++, ptmp = ptmp->next) etmp[i] = ptmp; qsort(etmp, numpersistpassthrus, sizeof(struct extensible *), pass_persist_compare); persistpassthrus = (struct extensible *) etmp[0]; ptmp = (struct extensible *) etmp[0]; for (i = 0; i < numpersistpassthrus - 1; i++) { ptmp->next = etmp[i + 1]; ptmp = ptmp->next; } ptmp->next = NULL; free(etmp); } }
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; static long long_ret; static in_addr_t addr_ret; char buf[SNMP_MAXBUF]; static char buf2[SNMP_MAXBUF]; static oid objid[MAX_OID_LEN]; struct extensible *passthru; FILE *file; long_ret = *length; for (i = 1; i <= numpassthrus; i++) { passthru = get_exten_instance(passthrus, i); rtest = snmp_oid_min_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); /* * buf contains the return type, and buf2 contains the data */ if (!strncasecmp(buf, "string", 6)) { buf2[strlen(buf2) - 1] = 0; /* zap the linefeed */ *var_len = strlen(buf2); vp->type = ASN_OCTET_STR; return ((unsigned char *) buf2); } else if (!strncasecmp(buf, "integer64", 9)) { static struct counter64 c64; uint64_t v64 = strtoull(buf2, NULL, 10); void * _c64 = (void *)&c64; if (sizeof(long) > 4) { /* 64-bit machine */ c64.high = v64 >> 32; c64.low = v64 & 0xffffffff; } else { /* 32-bit machine */ *(uint64_t *)_c64 = v64; } *var_len = sizeof(c64); vp->type = ASN_INTEGER64; return ((unsigned char *) &c64); } else if (!strncasecmp(buf, "integer", 7)) {
void extensible_parse_config(char *token, char* cptr) { struct extensible **pptmp; struct extensible **pprelocs = &relocs; struct extensible **ppexten = &extens; char *tcptr; if (*cptr == '.') cptr++; if (isdigit(*cptr)) { /* its a relocatable extensible mib */ while(*pprelocs != NULL) pprelocs = &((*pprelocs)->next); numrelocs++; (*pprelocs) = (struct extensible *) malloc(sizeof(struct extensible)); pptmp = pprelocs; } else { /* it goes in with the general extensible table */ while(*ppexten != NULL) ppexten = &((*ppexten)->next); numextens++; (*ppexten) = (struct extensible *) malloc(sizeof(struct extensible)); pptmp = ppexten; } /* the rest is pretty much handled the same */ if (!strncasecmp(token,"sh",2)) (*pptmp)->type = SHPROC; else (*pptmp)->type = EXECPROC; if (isdigit(*cptr)) { (*pptmp)->miblen = parse_miboid(cptr,(*pptmp)->miboid); while (isdigit(*cptr) || *cptr == '.') cptr++; } else { (*pptmp)->miboid[0] = 0; (*pptmp)->miblen = 0; } /* name */ cptr = skip_white(cptr); copy_word(cptr,(*pptmp)->name); cptr = skip_not_white(cptr); cptr = skip_white(cptr); /* command */ if (cptr == NULL) { config_perror("No command specified on line"); (*pptmp)->command[0] = 0; } else { for(tcptr=cptr; *tcptr != 0 && *tcptr != '#' && *tcptr != ';'; tcptr++); strncpy((*pptmp)->command,cptr,tcptr-cptr); (*pptmp)->command[tcptr-cptr] = 0; (*pptmp)->next = NULL; } #ifdef PROCFIXCMD sprintf((*pptmp)->fixcmd, EXECFIXCMD, (*pptmp)->name); #endif if ((*pptmp)->miblen > 0) { register_mib(token, (struct variable *) extensible_relocatable_variables, sizeof(struct variable2), 6, (*pptmp)->miboid, (*pptmp)->miblen); } }
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); }