void se_read_conf(const char *word, char *cptr) { int major, minor; int value; char *cp, *cp2; char e_name[BUFSIZ]; char e_enum[ BUFSIZ]; if (!cptr || *cptr=='\0') return; /* * Extract the first token * (which should be the name of the list) */ cp = copy_nword(cptr, e_name, sizeof(e_name)); cp = skip_white(cp); if (!cp || *cp=='\0') return; /* * Add each remaining enumeration to the list, * using the appropriate style interface */ if (sscanf(e_name, "%d:%d", &major, &minor) == 2) { /* * Numeric major/minor style */ while (1) { cp = copy_nword(cp, e_enum, sizeof(e_enum)); if (sscanf(e_enum, "%d:", &value) != 1) { break; } cp2 = e_enum; while (*(cp2++) != ':') ; se_add_pair(major, minor, strdup(cp2), value); if (!cp) break; } } else { /* * Named enumeration */ while (1) { cp = copy_nword(cp, e_enum, sizeof(e_enum)); if (sscanf(e_enum, "%d:", &value) != 1) { break; } cp2 = e_enum; while (*(cp2++) != ':') ; se_add_pair_to_slist(e_name, strdup(cp2), value); if (!cp) break; } } }
int register_sec_mod(int secmod, const char *modname, struct snmp_secmod_def *newdef) { int result = 0; struct snmp_secmod_list *sptr; char *othername, *modname2 = NULL; for (sptr = registered_services; sptr; sptr = sptr->next) { if (sptr->securityModel == secmod) { return SNMPERR_GENERR; } } sptr = SNMP_MALLOC_STRUCT(snmp_secmod_list); if (sptr == NULL) return SNMPERR_MALLOC; sptr->secDef = newdef; sptr->securityModel = secmod; sptr->next = registered_services; registered_services = sptr; modname2 = strdup(modname); if (!modname2) result = SE_NOMEM; else result = se_add_pair_to_slist("snmp_secmods", modname2, secmod); if (result != SE_OK) { switch (result) { case SE_NOMEM: snmp_log(LOG_CRIT, "snmp_secmod: no memory\n"); break; case SE_ALREADY_THERE: othername = se_find_label_in_slist("snmp_secmods", secmod); if (strcmp(othername, modname) != 0) { snmp_log(LOG_ERR, "snmp_secmod: two security modules %s and %s registered with the same security number\n", modname, othername); } break; default: snmp_log(LOG_ERR, "snmp_secmod: unknown error trying to register a new security module\n"); break; } return SNMPERR_GENERR; } return SNMPERR_SUCCESS; }
/** * Initilizes the VACM code. * Specifically: * - adds a set of enums mapping view numbers to human readable names */ void init_vacm (void) { /* views for access via get/set/send-notifications */ se_add_pair_to_slist (VACM_VIEW_ENUM_NAME, strdup ("read"), VACM_VIEW_READ); se_add_pair_to_slist (VACM_VIEW_ENUM_NAME, strdup ("write"), VACM_VIEW_WRITE); se_add_pair_to_slist (VACM_VIEW_ENUM_NAME, strdup ("notify"), VACM_VIEW_NOTIFY); /* views for permissions when receiving notifications */ se_add_pair_to_slist (VACM_VIEW_ENUM_NAME, strdup ("log"), VACM_VIEW_LOG); se_add_pair_to_slist (VACM_VIEW_ENUM_NAME, strdup ("execute"), VACM_VIEW_EXECUTE); se_add_pair_to_slist (VACM_VIEW_ENUM_NAME, strdup ("net"), VACM_VIEW_NET); }
static void _access_interface_entry_save_name(const char *name, oid index) { int tmp; if(NULL == name) return; tmp = se_find_value_in_slist("interfaces", name); if (tmp == SE_DNE) { se_add_pair_to_slist("interfaces", strdup(name), index); DEBUGMSGTL(("access:interface:ifIndex", "saved ifIndex %" NETSNMP_PRIo "u for %s\n", index, name)); } else if (index != (oid)tmp) { NETSNMP_LOGONCE((LOG_ERR, "IfIndex of an interface changed. Such " \ "interfaces will appear multiple times in IF-MIB.\n")); DEBUGMSGTL(("access:interface:ifIndex", "index %" NETSNMP_PRIo "u != tmp for %s\n", index, name)); } }
/** * load cache data * * @param container container to which items should be inserted * * @retval MFD_SUCCESS : success. * @retval MFD_RESOURCE_UNAVAILABLE : Can't access data source * @retval MFD_ERROR : other error. * * This function is called to cache the index(es) (and data, optionally) * for the every row in the data set. * * @remark * While loading the cache, the only important thing is the indexes. * If access to your data is cheap/fast (e.g. you have a pointer to a * structure in memory), it would make sense to update the data here. * If, however, the accessing the data invovles more work (e.g. parsing * some other existing data, or peforming calculations to derive the data), * then you can limit yourself to setting the indexes and saving any * information you will need later. Then use the saved information in * ifTable_row_prep() for populating data. * * @note * If you need consistency between rows (like you want statistics * for each row to be from the same time frame), you should set all * data here. * */ int ifTable_cache_load(netsnmp_container * container) { ifTable_rowreq_ctx *rowreq_ctx; int rc = MFD_SUCCESS; /* * this example code is based on a data source that is a * text file to be read and parsed. */ FILE *filep; char line[MAX_LINE_SIZE]; int fd; /* * temporary storage for index values */ /* * ifIndex(1)/InterfaceIndex/ASN_INTEGER/long(long)//l/A/w/e/R/d/H */ long ifIndex; DEBUGMSGTL(("verbose:ifTable_cache_load", "called\n")); /* *************************************************** *** START EXAMPLE CODE *** ***---------------------------------------------***/ /* * open our data file. */ filep = fopen("/proc/net/dev", "r"); if (NULL == filep) { return MFD_RESOURCE_UNAVAILABLE; } /* * create socket for ioctls */ fd = socket(AF_INET, SOCK_DGRAM, 0); if(fd < 0) { fclose(filep); return MFD_RESOURCE_UNAVAILABLE; } /* * ignore header lines */ fgets(line, sizeof(line), filep); fgets(line, sizeof(line), filep); /* ***---------------------------------------------*** *** END EXAMPLE CODE *** ***************************************************/ /* * TODO: update container * * loop over your data, allocate, set index, insert into the container */ /* * The rest of the file provides the statistics for an interface. * Read in each line in turn, isolate the interface name * and retrieve (or create) the corresponding data structure. */ while (1) { struct ifreq ifrq; int scan_count; char *stats, *ifstart; unsigned long rec_pkt, rec_oct, rec_err, rec_drop; unsigned long snd_pkt, snd_oct, snd_err, snd_drop, coll; /* *************************************************** *** START EXAMPLE CODE *** ***---------------------------------------------***/ /* * get a line (skip blank lines) */ do { if (!fgets(line, sizeof(line), filep)) { /* * we're done */ fclose(filep); filep = NULL; } } while (filep && (line[0] == '\n')); /* * check for end of data */ if (NULL == filep) break; /* * TODO: parse line * parse line into variables */ ifstart = line; while (*ifstart && *ifstart == ' ') ifstart++; if ((!*ifstart) || ((stats = strrchr(ifstart, ':')) == NULL)) { snmp_log(LOG_ERR, "interface data format error 1, line ==|%s|\n", line); DEBUGMSGTL(("ifTable", "found '%s'\n", ifstart)); continue; } /* * If we've met this interface before, use the same index. * Otherwise find an unused index value and use that. */ *stats++ = 0; /* null terminate name */ ifIndex = se_find_value_in_slist("interfaces", ifstart); if (ifIndex == SE_DNE) { ifIndex = se_find_free_value_in_slist("interfaces"); if (ifIndex == SE_DNE) ifIndex = 1; /* Completely new list! */ se_add_pair_to_slist("interfaces", strdup(ifstart), ifIndex); DEBUGMSGTL(("ifTable:ifIndex", "new ifIndex %d for %s\n", ifIndex, ifstart)); } if ((NULL == ifstart) || (0 == ifIndex)) { rc = MFD_END_OF_DATA; break; } /* ***---------------------------------------------*** *** END EXAMPLE CODE *** ***************************************************/ /* * allocate an row context and set the index(es) */ rowreq_ctx = ifTable_allocate_rowreq_ctx(); if (NULL == rowreq_ctx) { snmp_log(LOG_ERR, "memory allocation failed\n"); return MFD_RESOURCE_UNAVAILABLE; } if (MFD_SUCCESS != ifTable_indexes_set(rowreq_ctx, ifIndex)) { snmp_log(LOG_ERR, "error setting index while loading " "ifTable cache.\n"); ifTable_release_rowreq_ctx(rowreq_ctx); continue; } rec_pkt = rec_oct = rec_err = rec_drop = 0; snd_pkt = snd_oct = snd_err = snd_drop = coll = 0; if (scan_line_to_use == scan_line_2_2) { scan_count = sscanf(stats, scan_line_to_use, &rec_oct, &rec_pkt, &rec_err, &rec_drop, &snd_oct, &snd_pkt, &snd_err, &snd_drop, &coll); } else { scan_count = sscanf(stats, scan_line_to_use, &rec_pkt, &rec_err, &snd_pkt, &snd_err, &coll); } if(scan_count != scan_expected) { snmp_log(LOG_ERR, "error scanning interface data (expected %d, got %d)\n", scan_expected, scan_count); rc = MFD_ERROR; break; } if (scan_line_to_use != scan_line_2_2) { rec_oct = rec_pkt * 308; snd_oct = snd_pkt * 308; } /* * TODO: populate data context */ /* * TRANSIENT or semi-TRANSIENT data: * copy data or save any info needed to do it in row_prep. */ /* * TODO: setup/save data for ifDescr * ifDescr(2)/DisplayString/ASN_OCTET_STR/char(char)//L/A/w/e/R/d/H */ /** no code to get description yet */ rowreq_ctx->data.ifDescr[0] = 0; rowreq_ctx->data.ifDescr_len = 0; /* * TODO: setup/save data for ifMtu * ifMtu(4)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h */ /* * TODO: * value mapping */ /* * TODO: setup/save data for ifSpeed * ifSpeed(5)/GAUGE/ASN_GAUGE/u_long(u_long)//l/A/w/e/r/d/h */ /* * TODO: * value mapping */ /* * TODO: setup/save data for ifPhysAddress * ifPhysAddress(6)/PhysAddress/ASN_OCTET_STR/char(char)//L/A/w/e/r/d/H */ /* * make sure there is enough space for data */ if (sizeof(rowreq_ctx->data.ifPhysAddress) < 6) { snmp_log(LOG_ERR, "not enough space for address while loading " "ifTable cache.\n"); ifTable_release_rowreq_ctx(rowreq_ctx); continue; } rowreq_ctx->data.ifPhysAddress_len = 6; strncpy(ifrq.ifr_name, ifstart, sizeof(ifrq.ifr_name)); ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0; if (ioctl(fd, SIOCGIFHWADDR, &ifrq) < 0) memset(rowreq_ctx->data.ifPhysAddress, (0), 6); else { memcpy(rowreq_ctx->data.ifPhysAddress, ifrq.ifr_hwaddr.sa_data, 6); } /* * TODO: setup/save data for ifType * ifType(3)/IANAifType/ASN_INTEGER/long(u_long)//l/A/w/E/r/d/h */ /* * TODO: * value mapping */ if (MFD_SUCCESS != ifType_map(&rowreq_ctx->data.ifType, ifrq.ifr_hwaddr.sa_family)) { snmp_log(LOG_ERR, "error mapping ifType while loading " "ifTable cache.\n"); ifTable_release_rowreq_ctx(rowreq_ctx); continue; } /* * TODO: setup/save data for ifAdminStatus * ifAdminStatus(7)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h */ /* * TODO: * value mapping */ /* * TODO: setup/save data for ifOperStatus * ifOperStatus(8)/INTEGER/ASN_INTEGER/long(u_long)//l/A/w/E/r/d/h */ /* * TODO: * value mapping */ /* * TODO: setup/save data for ifLastChange * ifLastChange(9)/TICKS/ASN_TIMETICKS/u_long(u_long)//l/A/w/e/r/d/h */ /* * TODO: * value mapping */ /* * TODO: setup/save data for ifInOctets * ifInOctets(10)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h */ rowreq_ctx->data.ifInOctets = rec_oct; /* * TODO: setup/save data for ifInUcastPkts * ifInUcastPkts(11)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h */ rowreq_ctx->data.ifInUcastPkts = rec_pkt; /* * TODO: setup/save data for ifInNUcastPkts * ifInNUcastPkts(12)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h */ /* * TODO: * value mapping */ /* * TODO: setup/save data for ifInDiscards * ifInDiscards(13)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h */ rowreq_ctx->data.ifInDiscards = rec_drop; /* * TODO: setup/save data for ifInErrors * ifInErrors(14)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h */ rowreq_ctx->data.ifInErrors = rec_err; /* * TODO: setup/save data for ifInUnknownProtos * ifInUnknownProtos(15)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h */ /* * TODO: * value mapping */ /* * TODO: setup/save data for ifOutOctets * ifOutOctets(16)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h */ rowreq_ctx->data.ifOutOctets = snd_oct; /* * TODO: setup/save data for ifOutUcastPkts * ifOutUcastPkts(17)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h */ rowreq_ctx->data.ifOutUcastPkts = snd_pkt; /* * TODO: setup/save data for ifOutNUcastPkts * ifOutNUcastPkts(18)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h */ /* * TODO: * value mapping */ /* * TODO: setup/save data for ifOutDiscards * ifOutDiscards(19)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h */ rowreq_ctx->data.ifOutDiscards = snd_drop; /* * TODO: setup/save data for ifOutErrors * ifOutErrors(20)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h */ rowreq_ctx->data.ifOutErrors = snd_err; /* * TODO: setup/save data for ifOutQLen * ifOutQLen(21)/GAUGE/ASN_GAUGE/u_long(u_long)//l/A/w/e/r/d/h */ /* * TODO: * value mapping */ /* * TODO: setup/save data for ifSpecific * ifSpecific(22)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/A/w/e/r/d/h */ /* * TODO: * value mapping */ /* * it is hard to autogenerate code for mapping types that are not simple * integers, so here is an idea of what you might need to do. It may * need some tweaking to get right. */ /* * NOTE: this code would replace the memcpy below. * * if(MFD_SUCCESS != * ifSpecific_map(&rowreq_ctx->data.ifSpecific, &rowreq_ctx->data.ifSpecific_len, * TODO_FIND_ifSpecific, TODO_FIND_ifSpecific_len, 0)) { * return MFD_ERROR; * } */ /* * TODO: * update, replace or delete, if needed. */ /* * make sure there is enough space for data */ /** not implemented */ /* * insert into table container */ CONTAINER_INSERT(container, rowreq_ctx); } /* *************************************************** *** START EXAMPLE CODE *** ***---------------------------------------------***/ close(fd); if (NULL != filep) fclose(filep); /* ***---------------------------------------------*** *** END EXAMPLE CODE *** ***************************************************/ return rc; }