/************************************************************ * * Initialize the saHpiWatchdogTable table by defining its contents and how it's structured */ void initialize_table_saHpiWatchdogTable(void) { netsnmp_table_registration_info *table_info; if (my_handler) { snmp_log(LOG_ERR, "initialize_table_saHpiWatchdogTable_handler called again\n"); return; } memset(&cb, 0x00, sizeof(cb)); /** create the table structure itself */ table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); /* * if your table is read only, it's easiest to change the * HANDLER_CAN_RWRITE definition below to HANDLER_CAN_RONLY */ my_handler = netsnmp_create_handler_registration("saHpiWatchdogTable", netsnmp_table_array_helper_handler, saHpiWatchdogTable_oid, saHpiWatchdogTable_oid_len, HANDLER_CAN_RWRITE); if (!my_handler || !table_info) { snmp_log(LOG_ERR, "malloc failed in " "initialize_table_saHpiWatchdogTable_handler\n"); return; /** mallocs failed */ } /*************************************************** * Setting up the table's definition */ /* * TODO: add any external indexes here. */ /* * internal indexes */ /** index: saHpiWatchdogNum */ netsnmp_table_helper_add_index(table_info, ASN_UNSIGNED); table_info->min_column = saHpiWatchdogTable_COL_MIN; table_info->max_column = saHpiWatchdogTable_COL_MAX; /*************************************************** * registering the table with the master agent */ cb.get_value = saHpiWatchdogTable_get_value; cb.container = netsnmp_container_find("saHpiWatchdogTable_primary:" "saHpiWatchdogTable:" "table_container"); #ifdef saHpiWatchdogTable_IDX2 /* netsnmp_container_add_index(cb.container, netsnmp_container_find ("saHpiWatchdogTable_secondary:" "saHpiWatchdogTable:" "table_container")); cb.container->next->compare = saHpiWatchdogTable_cmp; */ #endif cb.can_set = 1; cb.create_row = (UserRowMethod *) saHpiWatchdogTable_create_row; cb.duplicate_row = (UserRowMethod *) saHpiWatchdogTable_duplicate_row; cb.delete_row = (UserRowMethod *) saHpiWatchdogTable_delete_row; cb.row_copy = (Netsnmp_User_Row_Operation *) saHpiWatchdogTable_row_copy; cb.can_delete = (Netsnmp_User_Row_Action *) saHpiWatchdogTable_can_delete; cb.set_reserve1 = saHpiWatchdogTable_set_reserve1; cb.set_reserve2 = saHpiWatchdogTable_set_reserve2; cb.set_action = saHpiWatchdogTable_set_action; cb.set_commit = saHpiWatchdogTable_set_commit; cb.set_free = saHpiWatchdogTable_set_free; cb.set_undo = saHpiWatchdogTable_set_undo; DEBUGMSGTL(("initialize_table_saHpiWatchdogTable", "Registering table saHpiWatchdogTable " "as a table array\n")); netsnmp_table_container_register(my_handler, table_info, &cb, cb.container, 1); netsnmp_register_read_only_counter32_instance("watchdoig_count", saHpiWatchdogCount_oid, OID_LENGTH(saHpiWatchdogCount_oid), &watchdog_count, NULL); }
/************************************************************ * * Initialize the saHpiHotSwapTable table by defining its contents and how it's structured */ void initialize_table_saHpiHotSwapTable(void) { netsnmp_table_registration_info *table_info; if(my_handler) { snmp_log(LOG_ERR, "initialize_table_saHpiHotSwapTable_handler called again\n"); return; } memset(&cb, 0x00, sizeof(cb)); /** create the table structure itself */ table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); /* if your table is read only, it's easiest to change the HANDLER_CAN_RWRITE definition below to HANDLER_CAN_RONLY */ my_handler = netsnmp_create_handler_registration("saHpiHotSwapTable", netsnmp_table_array_helper_handler, saHpiHotSwapTable_oid, saHpiHotSwapTable_oid_len, HANDLER_CAN_RWRITE); if (!my_handler || !table_info) { snmp_log(LOG_ERR, "malloc failed in " "initialize_table_saHpiHotSwapTable_handler\n"); return; /** mallocs failed */ } /*************************************************** * Setting up the table's definition */ /* * TODO: add any external indexes here. */ /** TODO: add code for external index(s)! */ /* * internal indexes */ /** index: saHpiDomainId */ netsnmp_table_helper_add_index(table_info, ASN_UNSIGNED); /** index: saHpiResourceId */ netsnmp_table_helper_add_index(table_info, ASN_UNSIGNED); /** index: saHpiResourceIsHistorical */ netsnmp_table_helper_add_index(table_info, ASN_INTEGER); table_info->min_column = saHpiHotSwapTable_COL_MIN; table_info->max_column = saHpiHotSwapTable_COL_MAX; /*************************************************** * registering the table with the master agent */ cb.get_value = saHpiHotSwapTable_get_value; cb.container = netsnmp_container_find("saHpiHotSwapTable_primary:" "saHpiHotSwapTable:" "table_container"); #ifdef saHpiHotSwapTable_IDX2 netsnmp_container_add_index(cb.container, netsnmp_container_find("saHpiHotSwapTable_secondary:" "saHpiHotSwapTable:" "table_container")); cb.container->next->compare = saHpiHotSwapTable_cmp; #endif #ifdef saHpiHotSwapTable_SET_HANDLING cb.can_set = 1; #ifdef saHpiHotSwapTable_ROW_CREATION cb.create_row = (UserRowMethod*)saHpiHotSwapTable_create_row; #endif cb.duplicate_row = (UserRowMethod*)saHpiHotSwapTable_duplicate_row; cb.delete_row = (UserRowMethod*)saHpiHotSwapTable_delete_row; cb.row_copy = (Netsnmp_User_Row_Operation *)saHpiHotSwapTable_row_copy; cb.can_activate = (Netsnmp_User_Row_Action *)saHpiHotSwapTable_can_activate; cb.can_deactivate = (Netsnmp_User_Row_Action *)saHpiHotSwapTable_can_deactivate; cb.can_delete = (Netsnmp_User_Row_Action *)saHpiHotSwapTable_can_delete; cb.set_reserve1 = saHpiHotSwapTable_set_reserve1; cb.set_reserve2 = saHpiHotSwapTable_set_reserve2; cb.set_action = saHpiHotSwapTable_set_action; cb.set_commit = saHpiHotSwapTable_set_commit; cb.set_free = saHpiHotSwapTable_set_free; cb.set_undo = saHpiHotSwapTable_set_undo; #endif DEBUGMSGTL(("initialize_table_saHpiHotSwapTable", "Registering table saHpiHotSwapTable " "as a table array\n")); netsnmp_table_container_register(my_handler, table_info, &cb, cb.container, 1); }
void group_requests(netsnmp_agent_request_info *agtreq_info, netsnmp_request_info *requests, netsnmp_container *request_group, table_container_data * tad) { netsnmp_table_request_info *tblreq_info; netsnmp_variable_list *var; netsnmp_index *row, *tmp, index; netsnmp_request_info *current; netsnmp_request_group *g; netsnmp_request_group_item *i; for (current = requests; current; current = current->next) { var = current->requestvb; /* * skip anything that doesn't need processing. */ if (current->processed != 0) { DEBUGMSGTL(("table_array:group", "already processed\n")); continue; } /* * 3.2.1 Setup and paranoia * * * * Get pointer to the table information for this request. This * * information was saved by table_helper_handler. When * * debugging, we double check a few assumptions. For example, * * the table_helper_handler should enforce column boundaries. */ row = NULL; tblreq_info = netsnmp_extract_table_info(current); netsnmp_assert(tblreq_info->colnum <= tad->tblreg_info->max_column); /* * search for index */ index.oids = tblreq_info->index_oid; index.len = tblreq_info->index_oid_len; tmp = (netsnmp_index*)CONTAINER_FIND(request_group, &index); if (tmp) { DEBUGMSGTL(("table_array:group", " existing group:")); DEBUGMSGOID(("table_array:group", index.oids, index.len)); DEBUGMSG(("table_array:group", "\n")); g = (netsnmp_request_group *) tmp; i = SNMP_MALLOC_TYPEDEF(netsnmp_request_group_item); if (i == NULL) return; i->ri = current; i->tri = tblreq_info; i->next = g->list; g->list = i; /** xxx-rks: store map of colnum to request */ continue; } DEBUGMSGTL(("table_array:group", " new group")); DEBUGMSGOID(("table_array:group", index.oids, index.len)); DEBUGMSG(("table_array:group", "\n")); g = SNMP_MALLOC_TYPEDEF(netsnmp_request_group); i = SNMP_MALLOC_TYPEDEF(netsnmp_request_group_item); if (i == NULL || g == NULL) return; g->list = i; g->table = tad->table; i->ri = current; i->tri = tblreq_info; /** xxx-rks: store map of colnum to request */ /* * search for row. all changes are made to the original row, * later, we'll make a copy in undo_info before we start processing. */ row = g->existing_row = (netsnmp_index*)CONTAINER_FIND(tad->table, &index); if (!g->existing_row) { if (!tad->cb->create_row) { if(MODE_IS_SET(agtreq_info->mode)) netsnmp_set_request_error(agtreq_info, current, SNMP_ERR_NOTWRITABLE); else netsnmp_set_request_error(agtreq_info, current, SNMP_NOSUCHINSTANCE); free(g); free(i); continue; } /** use undo_info temporarily */ row = g->existing_row = tad->cb->create_row(&index); if (!row) { /* xxx-rks : parameter to create_row to allow * for better error reporting. */ netsnmp_set_request_error(agtreq_info, current, SNMP_ERR_GENERR); free(g); free(i); continue; } g->row_created = 1; } g->index.oids = row->oids; g->index.len = row->len; CONTAINER_INSERT(request_group, g); } /** for( current ... ) */ }
netsnmp_container* netsnmp_container_iterator_get(void *iterator_user_ctx, netsnmp_container_compare * compare, Netsnmp_Iterator_Loop_Key * get_first, Netsnmp_Iterator_Loop_Key * get_next, Netsnmp_Iterator_Loop_Data * get_data, Netsnmp_Iterator_Ctx_Dup * save_pos, Netsnmp_Iterator_Ctx * init_loop_ctx, Netsnmp_Iterator_Ctx * cleanup_loop_ctx, Netsnmp_Iterator_Data * free_user_ctx, int sorted) { iterator_info *ii; /* * sanity checks */ if(get_data && ! save_pos) { snmp_log(LOG_ERR, "save_pos required with get_data\n"); return NULL; } /* * allocate memory */ ii = SNMP_MALLOC_TYPEDEF(iterator_info); if (NULL==ii) { snmp_log(LOG_ERR, "couldn't allocate memory\n"); return NULL; } /* * init container structure with iterator functions */ ii->c.cfree = (netsnmp_container_rc*)_iterator_free; ii->c.compare = compare; ii->c.get_size = (netsnmp_container_size*)_iterator_size; ii->c.init = NULL; ii->c.insert = (netsnmp_container_op*)_iterator_insert; ii->c.remove = (netsnmp_container_op*)_iterator_remove; ii->c.release = (netsnmp_container_op*)_iterator_release; ii->c.find = (netsnmp_container_rtn*)_iterator_find; ii->c.find_next = (netsnmp_container_rtn*)_iterator_find_next; ii->c.get_subset = NULL; ii->c.get_iterator = NULL; ii->c.for_each = (netsnmp_container_func*)_iterator_for_each; ii->c.clear = _iterator_clear; /* * init iterator structure with user functions */ ii->get_first = get_first; ii->get_next = get_next; ii->get_data = get_data; ii->save_pos = save_pos; ii->init_loop_ctx = init_loop_ctx; ii->cleanup_loop_ctx = cleanup_loop_ctx; ii->free_user_ctx = free_user_ctx; ii->sorted = sorted; ii->user_ctx = iterator_user_ctx; return (netsnmp_container*)ii; }
/** Initialize the cpqSasPhyDrvTable table by defining its contents and how it's structured */ void initialize_table_cpqSasPhyDrvTable(void) { netsnmp_handler_registration *reg = NULL; netsnmp_mib_handler *handler = NULL; netsnmp_container *container = NULL; netsnmp_table_registration_info *table_info = NULL; netsnmp_cache *cache = NULL; int reg_tbl_ret = SNMPERR_SUCCESS; DEBUGMSGTL(("cpqSasPhyDrvTable:init", "initializing table cpqSasPhyDrvTable\n")); reg = netsnmp_create_handler_registration("cpqSasPhyDrvTable", cpqSasPhyDrvTable_handler, cpqSasPhyDrvTable_oid, cpqSasPhyDrvTable_oid_len, HANDLER_CAN_RONLY); if (NULL == reg) { snmp_log(LOG_ERR, "error creating handler registration for cpqSasPhyDrvTable\n"); goto bail; } container = netsnmp_container_find("cpqSasPhyDrvTable:table_container"); if (NULL == container) { snmp_log(LOG_ERR, "error creating container for cpqSasPhyDrvTable\n"); goto bail; } table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); if (NULL == table_info) { snmp_log(LOG_ERR, "error allocating table registration for cpqSasPhyDrvTable\n"); goto bail; } netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, /* index: cpqSasPhyDrvHbaIndex */ ASN_INTEGER, /* index: cpqSasPhyDrvIndex */ 0); table_info->min_column = COLUMN_CPQSASPHYDRVHBAINDEX; table_info->max_column = COLUMN_CPQSASPHYDRVTEMPERATURETHRESHOLD; /************************************************* * * inject container_table helper */ handler = netsnmp_container_table_handler_get(table_info, container, TABLE_CONTAINER_KEY_NETSNMP_INDEX); if (NULL == handler) { snmp_log(LOG_ERR, "error allocating table registration for cpqSasPhyDrvTable\n"); goto bail; } if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) { snmp_log(LOG_ERR, "error injecting container_table handler for cpqSasPhyDrvTable\n"); goto bail; } handler = NULL; /* reg has it, will reuse below */ /************************************************* * * inject cache helper */ cache = netsnmp_cache_create(300, /* timeout in seconds */ _cache_load, _cache_free, cpqSasPhyDrvTable_oid, cpqSasPhyDrvTable_oid_len); if (NULL == cache) { snmp_log(LOG_ERR, "error creating cache for cpqSasPhyDrvTable\n"); goto bail; } cache->flags = NETSNMP_CACHE_PRELOAD | NETSNMP_CACHE_DONT_FREE_BEFORE_LOAD | NETSNMP_CACHE_DONT_FREE_EXPIRED | NETSNMP_CACHE_DONT_AUTO_RELEASE | NETSNMP_CACHE_DONT_INVALIDATE_ON_SET; cache->magic = container; handler = netsnmp_cache_handler_get(cache); if (NULL == handler) { snmp_log(LOG_ERR, "error creating cache handler for cpqSasPhyDrvTable\n"); goto bail; } if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) { snmp_log(LOG_ERR, "error injecting cache handler for cpqSasPhyDrvTable\n"); goto bail; } handler = NULL; /* reg has it */ /* * register the table */ reg_tbl_ret = netsnmp_register_table(reg, table_info); if (reg_tbl_ret != SNMPERR_SUCCESS) { snmp_log(LOG_ERR, "error registering table handler for cpqSasPhyDrvTable\n"); goto bail; } /* * Initialise the contents of the table here */ return; /* ok */ /* * Some error occurred during registration. Clean up and bail. */ bail: /* not ok */ if (handler) netsnmp_handler_free(handler); if (cache) netsnmp_cache_free(cache); if (table_info) netsnmp_table_registration_info_free(table_info); if (container) CONTAINER_FREE(container); if (reg_tbl_ret == SNMPERR_SUCCESS) if (reg) netsnmp_handler_registration_free(reg); }
int perl_trapd_handler( netsnmp_pdu *pdu, netsnmp_transport *transport, netsnmp_trapd_handler *handler) { trapd_cb_data *cb_data; SV *pcallback; netsnmp_variable_list *vb; netsnmp_oid *o; SV *arg; SV *rarg; SV **tmparray; int i, c = 0; u_char *outbuf; size_t ob_len = 0, oo_len = 0; AV *varbinds; HV *pduinfo; dSP; ENTER; SAVETMPS; if (!pdu || !handler) return 0; /* nuke v1 PDUs */ if (pdu->command == SNMP_MSG_TRAP) pdu = convert_v1pdu_to_v2(pdu); cb_data = handler->handler_data; if (!cb_data || !cb_data->perl_cb) return 0; pcallback = cb_data->perl_cb; /* get PDU related info */ pduinfo = newHV(); #define STOREPDU(n, v) hv_store(pduinfo, n, strlen(n), v, 0) #define STOREPDUi(n, v) STOREPDU(n, newSViv(v)) #define STOREPDUs(n, v) STOREPDU(n, newSVpv(v, 0)) STOREPDUi("version", pdu->version); STOREPDUs("notificationtype", ((pdu->command == SNMP_MSG_INFORM) ? "INFORM":"TRAP")); STOREPDUi("requestid", pdu->reqid); STOREPDUi("messageid", pdu->msgid); STOREPDUi("transactionid", pdu->transid); STOREPDUi("errorstatus", pdu->errstat); STOREPDUi("errorindex", pdu->errindex); if (pdu->version == 3) { STOREPDUi("securitymodel", pdu->securityModel); STOREPDUi("securitylevel", pdu->securityLevel); STOREPDU("contextName", newSVpv(pdu->contextName, pdu->contextNameLen)); STOREPDU("contextEngineID", newSVpv(pdu->contextEngineID, pdu->contextEngineIDLen)); STOREPDU("securityEngineID", newSVpv(pdu->securityEngineID, pdu->securityEngineIDLen)); STOREPDU("securityName", newSVpv(pdu->securityName, pdu->securityNameLen)); } else { STOREPDU("community", newSVpv(pdu->community, pdu->community_len)); } if (transport && transport->f_fmtaddr) { char *tstr = transport->f_fmtaddr(transport, pdu->transport_data, pdu->transport_data_length); STOREPDUs("receivedfrom", tstr); free(tstr); } /* * collect OID objects in a temp array first */ /* get VARBIND related info */ i = count_varbinds(pdu->variables); tmparray = malloc(sizeof(*tmparray) * i); for(vb = pdu->variables; vb; vb = vb->next_variable) { /* get the oid */ o = SNMP_MALLOC_TYPEDEF(netsnmp_oid); o->name = o->namebuf; o->len = vb->name_length; memcpy(o->name, vb->name, vb->name_length * sizeof(oid)); #undef CALL_EXTERNAL_OID_NEW #ifdef CALL_EXTERNAL_OID_NEW PUSHMARK(sp); rarg = sv_2mortal(newSViv((IV) 0)); arg = sv_2mortal(newSVrv(rarg, "netsnmp_oidPtr")); sv_setiv(arg, (IV) o); XPUSHs(rarg); PUTBACK; i = perl_call_pv("NetSNMP::OID::newwithptr", G_SCALAR); SPAGAIN; if (i != 1) { snmp_log(LOG_ERR, "unhandled OID error.\n"); /* ack XXX */ } /* get the value */ tmparray[c++] = POPs; SvREFCNT_inc(tmparray[c-1]); PUTBACK; #else /* build it and bless ourselves */ { HV *hv = newHV(); SV *rv = newRV_noinc((SV *) hv); SV *rvsub = newRV_noinc((SV *) newSViv((UV) o)); SV *sv; rvsub = sv_bless(rvsub, gv_stashpv("netsnmp_oidPtr", 1)); hv_store(hv, "oidptr", 6, rvsub, 0); rv = sv_bless(rv, gv_stashpv("NetSNMP::OID", 1)); tmparray[c++] = rv; } #endif /* build oid ourselves */ } /* * build the varbind lists */ varbinds = newAV(); for(vb = pdu->variables, i = 0; vb; vb = vb->next_variable, i++) { /* push the oid */ AV *vba; vba = newAV(); /* get the value */ outbuf = NULL; ob_len = 0; oo_len = 0; sprint_realloc_by_type(&outbuf, &ob_len, &oo_len, 1, vb, 0, 0, 0); av_push(vba,tmparray[i]); av_push(vba,newSVpvn(outbuf, oo_len)); free(outbuf); av_push(vba,newSViv(vb->type)); av_push(varbinds, (SV *) newRV_noinc((SV *) vba)); } PUSHMARK(sp); /* store the collected information on the stack */ XPUSHs(sv_2mortal(newRV_noinc((SV*) pduinfo))); XPUSHs(sv_2mortal(newRV_noinc((SV*) varbinds))); /* put the stack back in order */ PUTBACK; /* actually call the callback function */ if (SvTYPE(pcallback) == SVt_PVCV) { perl_call_sv(pcallback, G_DISCARD); /* XXX: it discards the results, which isn't right */ } else if (SvROK(pcallback) && SvTYPE(SvRV(pcallback)) == SVt_PVCV) { /* reference to code */ perl_call_sv(SvRV(pcallback), G_DISCARD); } else { snmp_log(LOG_ERR, " tried to call a perl function but failed to understand its type: (ref = %x, svrok: %lu, SVTYPE: %lu)\n", (uintptr_t)pcallback, SvROK(pcallback), SvTYPE(pcallback)); } #ifdef DUMPIT fprintf(stderr, "DUMPDUMPDUMPDUMPDUMPDUMP\n"); sv_dump(pduinfo); fprintf(stderr, "--------------------\n"); sv_dump(varbinds); #endif /* svREFCNT_dec((SV *) pduinfo); */ #ifdef NOT_THIS { SV *vba; while(vba = av_pop(varbinds)) { av_undef((AV *) vba); } } av_undef(varbinds); #endif free(tmparray); /* Not needed because of the G_DISCARD flag (I think) */ /* SPAGAIN; */ /* PUTBACK; */ #ifndef __x86_64__ FREETMPS; /* FIXME: known to cause a segfault on x86-64 */ #endif LEAVE; return NETSNMPTRAPD_HANDLER_OK; }
static int _ssll_insert(netsnmp_container *c, const void *data) { sl_container *sl = (sl_container*)c; sl_node *new_node, *curr = sl->head; if(NULL == c) return -1; new_node = SNMP_MALLOC_TYPEDEF(sl_node); if(NULL == new_node) return -1; new_node->data = NETSNMP_REMOVE_CONST(void *, data); ++sl->count; ++c->sync; /* * first node? */ if(NULL == sl->head) { sl->head = new_node; return 0; } /* * sorted or unsorted insert? */ if (1 == sl->unsorted) { /* * unsorted: fifo, or lifo? */ if (1 == sl->fifo) { /* * fifo: insert at tail */ while(NULL != curr->next) curr = curr->next; curr->next = new_node; } else { /* * lifo: insert at head */ new_node->next = sl->head; sl->head = new_node; } } else { /* * sorted */ sl_node *last = NULL; for( ; curr; last = curr, curr = curr->next) { if(sl->c.compare(curr->data, data) > 0) break; } if(NULL == last) { new_node->next = sl->head; sl->head = new_node; } else { new_node->next = last->next; last->next = new_node; } } return 0; }
void init_testhandler(void) { /* * we're registering at .1.2.3.4 */ netsnmp_handler_registration *my_test; netsnmp_table_registration_info *table_info; u_long ind1; netsnmp_table_data *table; netsnmp_table_data_set *table_set; netsnmp_table_row *row; DEBUGMSGTL(("testhandler", "initializing\n")); /* * basic handler test */ netsnmp_register_handler(netsnmp_create_handler_registration ("myTest", my_test_handler, my_test_oid, 4, HANDLER_CAN_RONLY)); /* * instance handler test */ netsnmp_register_instance(netsnmp_create_handler_registration ("myInstance", my_test_instance_handler, my_instance_oid, 5, HANDLER_CAN_RWRITE)); netsnmp_register_ulong_instance("myulong", my_data_ulong_instance, 4, &my_ulong, NULL); /* * table helper test */ my_test = netsnmp_create_handler_registration("myTable", my_test_table_handler, my_table_oid, 4, HANDLER_CAN_RONLY); if (!my_test) return; table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); if (table_info == NULL) return; netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, ASN_INTEGER, 0); table_info->min_column = 3; table_info->max_column = 3; netsnmp_register_table(my_test, table_info); /* * data table helper test */ /* * we'll construct a simple table here with two indexes: an * integer and a string (why not). It'll contain only one * column so the data pointer is merely the data in that * column. */ table = netsnmp_create_table_data("data_table_test"); netsnmp_table_data_add_index(table, ASN_INTEGER); netsnmp_table_data_add_index(table, ASN_OCTET_STR); /* * 1 partridge in a pear tree */ row = netsnmp_create_table_data_row(); ind1 = 1; netsnmp_table_row_add_index(row, ASN_INTEGER, &ind1, sizeof(ind1)); netsnmp_table_row_add_index(row, ASN_OCTET_STR, "partridge", strlen("partridge")); row->data = (void *) "pear tree"; netsnmp_table_data_add_row(table, row); /* * 2 turtle doves */ row = netsnmp_create_table_data_row(); ind1 = 2; netsnmp_table_row_add_index(row, ASN_INTEGER, &ind1, sizeof(ind1)); netsnmp_table_row_add_index(row, ASN_OCTET_STR, "turtle", strlen("turtle")); row->data = (void *) "doves"; netsnmp_table_data_add_row(table, row); /* * we're going to register it as a normal table too, so we get the * automatically parsed column and index information */ table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); if (table_info == NULL) return; netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, ASN_OCTET_STR, 0); table_info->min_column = 3; table_info->max_column = 3; netsnmp_register_read_only_table_data (netsnmp_create_handler_registration ("12days", my_data_table_handler, my_data_table_oid, 4, HANDLER_CAN_RONLY), table, table_info); }
/** Initialize the cpqLinOsProcessorTable table by defining its contents * and how it's structured */ void initialize_table_cpqLinOsProcessorTable(void) { netsnmp_handler_registration *reg = NULL; netsnmp_mib_handler *handler = NULL; netsnmp_container *container = NULL; netsnmp_table_registration_info *table_info = NULL; netsnmp_cache *cache = NULL; DEBUGMSGTL(("cpqLinOsProcessorTable:init", "initializing table cpqLinOsProcessorTable\n")); reg = netsnmp_create_handler_registration("cpqLinOsProcessorTable", cpqLinOsProcessorTable_handler, cpqLinOsProcessorTable_oid, cpqLinOsProcessorTable_oid_len, HANDLER_CAN_RONLY); if (NULL == reg) { snmp_log(LOG_ERR, "error creating handler registration for cpqLinOsProcessorTable\n"); goto bail; } container = netsnmp_container_find("cpqLinOsProcessorTable:table_container"); if (NULL == container) { snmp_log(LOG_ERR, "error creating container for cpqLinOsProcessorTable\n"); goto bail; } container->container_name = strdup("cpqLinOsProcessorTable container"); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); if (NULL == table_info) { snmp_log(LOG_ERR, "error allocating table registration for cpqLinOsProcessorTable\n"); goto bail; } netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, /* index: cpqLinOsCpuIndex */ 0); table_info->min_column = COLUMN_CPQLINOSCPUINDEX; table_info->max_column = COLUMN_CPQLINOSCPUPRIVILEGEDTIMEPERCENT; /************************************************* * * inject container_table helper */ handler = netsnmp_container_table_handler_get(table_info, container, TABLE_CONTAINER_KEY_NETSNMP_INDEX); if (NULL == handler) { snmp_log(LOG_ERR, "error allocating table registration for cpqLinOsProcessorTable\n"); goto bail; } if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) { snmp_log(LOG_ERR, "error injecting container_table handler for cpqLinOsProcessorTable\n"); goto bail; } handler = NULL; /* reg has it, will reuse below */ /************************************************* * * inject cache helper */ cache = netsnmp_cache_create(5, /* timeout in seconds */ _cache_load, _cache_free, cpqLinOsProcessorTable_oid, cpqLinOsProcessorTable_oid_len); if (NULL == cache) { snmp_log(LOG_ERR, "error creating cache for cpqLinOsProcessorTable\n"); goto bail; } cache->flags = NETSNMP_CACHE_PRELOAD | NETSNMP_CACHE_DONT_FREE_EXPIRED | NETSNMP_CACHE_DONT_AUTO_RELEASE | NETSNMP_CACHE_DONT_FREE_BEFORE_LOAD | NETSNMP_CACHE_DONT_INVALIDATE_ON_SET; cache->magic = container; handler = netsnmp_cache_handler_get(cache); if (NULL == handler) { snmp_log(LOG_ERR, "error creating cache handler for cpqLinOsProcessorTable\n"); goto bail; } if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) { snmp_log(LOG_ERR, "error injecting cache handler for cpqLinOsProcessorTable\n"); goto bail; } handler = NULL; /* reg has it */ /* * register the table */ if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) { snmp_log(LOG_ERR, "error registering table handler for cpqLinOsProcessorTable\n"); reg = NULL; /* it was freed inside netsnmp_register_table */ goto bail; } return; /* ok */ /* * Some error occurred during registration. Clean up and bail. */ bail: /* not ok */ if (handler) netsnmp_handler_free(handler); if (cache) netsnmp_cache_free(cache); if (table_info) netsnmp_table_registration_info_free(table_info); if (container) CONTAINER_FREE(container); if (reg) netsnmp_handler_registration_free(reg); }
/** creates and returns a pointer to table data set */ netsnmp_table_row * netsnmp_create_table_data_row(void) { netsnmp_table_row *row = SNMP_MALLOC_TYPEDEF(netsnmp_table_row); return row; }
/** Initialize the sctpLookupLocalPortTable table by defining its contents and how it's structured */ void initialize_table_sctpLookupLocalPortTable(void) { static oid sctpLookupLocalPortTable_oid[] = { 1, 3, 6, 1, 2, 1, 104, 1, 6 }; size_t sctpLookupLocalPortTable_oid_len = OID_LENGTH(sctpLookupLocalPortTable_oid); netsnmp_handler_registration *reg = NULL; netsnmp_mib_handler *handler = NULL; netsnmp_container *container = NULL; reg = netsnmp_create_handler_registration("sctpLookupLocalPortTable", sctpLookupLocalPortTable_handler, sctpLookupLocalPortTable_oid, sctpLookupLocalPortTable_oid_len, HANDLER_CAN_RONLY); if (NULL == reg) { snmp_log(LOG_ERR, "error creating handler registration for sctpLookupLocalPortTable\n"); goto bail; } container = netsnmp_container_find("sctpLookupLocalPortTable:table_container"); if (NULL == container) { snmp_log(LOG_ERR, "error creating container for sctpLookupLocalPortTable\n"); goto bail; } sctpLookupLocalPortTable_container = container; table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); if (NULL == table_info) { snmp_log(LOG_ERR, "error allocating table registration for sctpLookupLocalPortTable\n"); goto bail; } netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* index: sctpAssocLocalPort */ ASN_UNSIGNED, /* index: sctpAssocId */ 0); table_info->min_column = COLUMN_SCTPLOOKUPLOCALPORTSTARTTIME; table_info->max_column = COLUMN_SCTPLOOKUPLOCALPORTSTARTTIME; /************************************************* * * inject container_table helper */ handler = netsnmp_container_table_handler_get(table_info, container, TABLE_CONTAINER_KEY_NETSNMP_INDEX); if (NULL == handler) { snmp_log(LOG_ERR, "error allocating table registration for sctpLookupLocalPortTable\n"); goto bail; } if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) { snmp_log(LOG_ERR, "error injecting container_table handler for sctpLookupLocalPortTable\n"); goto bail; } handler = NULL; /* reg has it, will reuse below */ /* * register the table */ if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) { snmp_log(LOG_ERR, "error registering table handler for sctpLookupLocalPortTable\n"); goto bail; } /* * Initialise the contents of the table here */ return; /* ok */ /* * Some error occurred during registration. Clean up and bail. */ bail: /* not ok */ if (handler) netsnmp_handler_free(handler); if (table_info) netsnmp_table_registration_info_free(table_info); if (container) CONTAINER_FREE(container); if (reg) netsnmp_handler_registration_free(reg); }
/************************************************************ * * Initialize the saHpiSensorThdPosHysteresisTable table by defining its contents and how it's structured */ void initialize_table_saHpiSensorThdPosHysteresisTable (void) { netsnmp_table_registration_info *table_info; if (my_handler) { snmp_log (LOG_ERR, "initialize_table_saHpiSensorThdPosHysteresisTable_handler called again\n"); return; } memset (&cb, 0x00, sizeof (cb)); /** create the table structure itself */ table_info = SNMP_MALLOC_TYPEDEF (netsnmp_table_registration_info); /* * if your table is read only, it's easiest to change the * HANDLER_CAN_RWRITE definition below to HANDLER_CAN_RONLY */ my_handler = netsnmp_create_handler_registration ("saHpiSensorThdPosHysteresisTable", netsnmp_table_array_helper_handler, saHpiSensorThdPosHysteresisTable_oid, saHpiSensorThdPosHysteresisTable_oid_len, HANDLER_CAN_RWRITE); if (!my_handler || !table_info) { snmp_log (LOG_ERR, "malloc failed in " "initialize_table_saHpiSensorThdPosHysteresisTable_handler\n"); return; /** mallocs failed */ } /*************************************************** * Setting up the table's definition */ /* * internal indexes */ /** index: saHpiDomainID */ netsnmp_table_helper_add_index (table_info, ASN_UNSIGNED); /** index: saHpiResourceID */ netsnmp_table_helper_add_index (table_info, ASN_UNSIGNED); /** index: saHpiSensorIndex */ netsnmp_table_helper_add_index (table_info, ASN_UNSIGNED); table_info->min_column = saHpiSensorThdPosHysteresisTable_COL_MIN; table_info->max_column = saHpiSensorThdPosHysteresisTable_COL_MAX; /*************************************************** * registering the table with the master agent */ cb.get_value = saHpiSensorThdPosHysteresisTable_get_value; cb.container = netsnmp_container_find ("saHpiSensorThdPosHysteresisTable_primary:" "saHpiSensorThdPosHysteresisTable:" "table_container"); cb.create_row = (UserRowMethod *) saHpiSensorThdPosHysteresisTable_create_row; cb.duplicate_row = (UserRowMethod *) saHpiSensorThdPosHysteresisTable_duplicate_row; cb.delete_row = (UserRowMethod *) saHpiSensorThdPosHysteresisTable_delete_row; cb.row_copy = (Netsnmp_User_Row_Operation *) saHpiSensorThdPosHysteresisTable_row_copy; cb.can_delete = (Netsnmp_User_Row_Action *) saHpiSensorThdPosHysteresisTable_can_delete; cb.set_reserve1 = saHpiSensorThdPosHysteresisTable_set_reserve1; cb.set_reserve2 = saHpiSensorThdPosHysteresisTable_set_reserve2; cb.set_action = saHpiSensorThdPosHysteresisTable_set_action; cb.set_commit = saHpiSensorThdPosHysteresisTable_set_commit; cb.set_free = saHpiSensorThdPosHysteresisTable_set_free; cb.set_undo = saHpiSensorThdPosHysteresisTable_set_undo; DEBUGMSGTL (("initialize_table_saHpiSensorThdPosHysteresisTable", "Registering table saHpiSensorThdPosHysteresisTable " "as a table array\n")); netsnmp_table_container_register (my_handler, table_info, &cb, cb.container, 1); }
/** Initialize the hrSWRunTable table by defining its contents and how it's structured */ void initialize_table_hrSWRunTable(void) { netsnmp_handler_registration *reg; netsnmp_mib_handler *handler = NULL; #ifndef NETSNMP_NO_WRITE_SUPPORT #ifdef NETSNMP_INCLUDE_HRSWRUN_WRITE_SUPPORT # define SWRUN_ACCESS_LEVEL HANDLER_CAN_RWRITE #else # define SWRUN_ACCESS_LEVEL HANDLER_CAN_RONLY #endif #else /* !NETSNMP_NO_WRITE_SUPPORT */ # define SWRUN_ACCESS_LEVEL HANDLER_CAN_RONLY #endif /* !NETSNMP_NO_WRITE_SUPPORT */ reg = netsnmp_create_handler_registration(MYTABLE, hrSWRunTable_handler, hrSWRunTable_oid, hrSWRunTable_oid_len, SWRUN_ACCESS_LEVEL); if (NULL == reg) { snmp_log(LOG_ERR,"error creating handler registration for " MYTABLE "\n"); goto bail; } reg->modes |= HANDLER_CAN_NOT_CREATE; table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); if (NULL == table_info) { snmp_log(LOG_ERR,"error allocating table registration for " MYTABLE "\n"); goto bail; } netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, /* index: hrSWRunIndex */ 0); table_info->min_column = COLUMN_HRSWRUNINDEX; table_info->max_column = COLUMN_HRSWRUNSTATUS; /************************************************* * * inject container_table helper */ handler = netsnmp_container_table_handler_get(table_info, netsnmp_swrun_container(), TABLE_CONTAINER_KEY_NETSNMP_INDEX); if (NULL == handler) { snmp_log(LOG_ERR,"error allocating table registration for " MYTABLE "\n"); goto bail; } if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) { snmp_log(LOG_ERR,"error injecting container_table handler for " MYTABLE "\n"); goto bail; } handler = NULL; /* reg has it, will reuse below */ /************************************************* * * inject cache helper */ handler = netsnmp_cache_handler_get(netsnmp_swrun_cache()); if (NULL == handler) { snmp_log(LOG_ERR, "error creating cache handler for " MYTABLE "\n"); goto bail; } if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) { snmp_log(LOG_ERR,"error injecting cache handler for " MYTABLE "\n"); goto bail; } handler = NULL; /* reg has it*/ if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) { snmp_log(LOG_ERR,"error registering table handler for " MYTABLE "\n"); reg = NULL; /* it was freed inside netsnmp_register_table */ goto bail; } return; /* ok */ bail: /* not ok */ if (handler) netsnmp_handler_free(handler); if (table_info) netsnmp_table_registration_info_free(table_info); if (reg) netsnmp_handler_registration_free(reg); }
/** Initialize the sctpAssocTable table by defining its contents and how it's structured */ void initialize_table_sctpAssocTable(void) { static oid sctpAssocTable_oid[] = { 1, 3, 6, 1, 2, 1, 104, 1, 3 }; size_t sctpAssocTable_oid_len = OID_LENGTH(sctpAssocTable_oid); netsnmp_handler_registration *reg = NULL; netsnmp_mib_handler *handler = NULL; netsnmp_container *container = NULL; netsnmp_table_registration_info *table_info = NULL; netsnmp_cache *cache = NULL; reg = netsnmp_create_handler_registration("sctpAssocTable", sctpAssocTable_handler, sctpAssocTable_oid, sctpAssocTable_oid_len, HANDLER_CAN_RWRITE); if (NULL == reg) { snmp_log(LOG_ERR, "error creating handler registration for sctpAssocTable\n"); goto bail; } /** should a set on a non-existent row create a new one? */ /** reg->modes |= HANDLER_CAN_NOT_CREATE; */ container = netsnmp_container_find("sctpAssocTable:table_container"); if (NULL == container) { snmp_log(LOG_ERR, "error creating container for sctpAssocTable\n"); goto bail; } sctpAssocTable_container = container; table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); if (NULL == table_info) { snmp_log(LOG_ERR, "error allocating table registration for sctpAssocTable\n"); goto bail; } netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED, /* index: sctpAssocId */ 0); table_info->min_column = COLUMN_SCTPASSOCREMHOSTNAME; table_info->max_column = COLUMN_SCTPASSOCDISCONTINUITYTIME; /************************************************* * * inject container_table helper */ handler = netsnmp_container_table_handler_get(table_info, container, TABLE_CONTAINER_KEY_NETSNMP_INDEX); if (NULL == handler) { snmp_log(LOG_ERR, "error allocating table registration for sctpAssocTable\n"); goto bail; } if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) { snmp_log(LOG_ERR, "error injecting container_table handler for sctpAssocTable\n"); goto bail; } handler = NULL; /* reg has it, will reuse below */ /************************************************* * * inject cache helper */ cache = netsnmp_cache_create(SCTP_TABLES_CACHE_TIMEOUT, /* timeout in seconds */ _cache_load, _cache_free, sctpAssocTable_oid, sctpAssocTable_oid_len); if (NULL == cache) { snmp_log(LOG_ERR, "error creating cache for sctpAssocTable\n"); goto bail; } cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET | NETSNMP_CACHE_AUTO_RELOAD | NETSNMP_CACHE_PRELOAD; cache->magic = container; handler = netsnmp_cache_handler_get(cache); if (NULL == handler) { snmp_log(LOG_ERR, "error creating cache handler for sctpAssocTable\n"); goto bail; } if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) { snmp_log(LOG_ERR, "error injecting cache handler for sctpAssocTable\n"); goto bail; } handler = NULL; /* reg has it */ /* * register the table */ if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) { snmp_log(LOG_ERR, "error registering table handler for sctpAssocTable\n"); goto bail; } /* * Initialise the contents of the table here */ return; /* ok */ /* * Some error occurred during registration. Clean up and bail. */ bail: /* not ok */ if (handler) netsnmp_handler_free(handler); if (container) CONTAINER_FREE(container); if (reg) netsnmp_handler_registration_free(reg); }
/** * update entry stats (checking for counter wrap) * * @retval 0 : success * @retval <0 : error */ int netsnmp_access_systemstats_entry_update_stats(netsnmp_systemstats_entry * prev_vals, netsnmp_systemstats_entry * new_vals) { DEBUGMSGTL(("access:systemstats", "check_wrap\n")); /* * sanity checks */ if ((NULL == prev_vals) || (NULL == new_vals) || (prev_vals->index[0] != new_vals->index[0]) || (prev_vals->index[1] != new_vals->index[1])) return -1; /* * if we've determined that we have 64 bit counters, just copy them. */ if (0 == need_wrap_check) { memcpy(&prev_vals->stats, &new_vals->stats, sizeof(new_vals->stats)); _calculate_entries(prev_vals); return 0; } if (NULL == prev_vals->old_stats) { /* * if we don't have old stats, they can't have wrapped, so just copy */ prev_vals->old_stats = SNMP_MALLOC_TYPEDEF(netsnmp_ipstats); if (NULL == prev_vals->old_stats) { return -2; } } else { /* * update straight 32 bit counters */ memcpy(&prev_vals->stats.columnAvail[0], &new_vals->stats.columnAvail[0], sizeof(new_vals->stats.columnAvail)); prev_vals->stats.InHdrErrors = new_vals->stats.InHdrErrors; prev_vals->stats.InAddrErrors = new_vals->stats.InAddrErrors; prev_vals->stats.InUnknownProtos = new_vals->stats.InUnknownProtos; prev_vals->stats.InTruncatedPkts = new_vals->stats.InTruncatedPkts; prev_vals->stats.ReasmReqds = new_vals->stats.ReasmReqds; prev_vals->stats.ReasmOKs = new_vals->stats.ReasmOKs; prev_vals->stats.ReasmFails = new_vals->stats.ReasmFails; prev_vals->stats.InDiscards = new_vals->stats.InDiscards; /* * update 64bit counters */ if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInNoRoutes, &new_vals->stats.HCInNoRoutes, &prev_vals->old_stats->HCInNoRoutes, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCInNoRoutes to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutNoRoutes, &new_vals->stats.HCOutNoRoutes, &prev_vals->old_stats->HCOutNoRoutes, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutNoRoutes to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutDiscards, &new_vals->stats.HCOutDiscards, &prev_vals->old_stats->HCOutDiscards, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutDiscards to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutFragReqds, &new_vals->stats.HCOutFragReqds, &prev_vals->old_stats->HCOutFragReqds, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutFragReqds to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutFragOKs, &new_vals->stats.HCOutFragOKs, &prev_vals->old_stats->HCOutFragOKs, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutFragOKs to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutFragFails, &new_vals->stats.HCOutFragFails, &prev_vals->old_stats->HCOutFragFails, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutFragFails to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutFragCreates, &new_vals->stats.HCOutFragCreates, &prev_vals->old_stats->HCOutFragCreates, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutFragCreates to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInReceives, &new_vals->stats.HCInReceives, &prev_vals->old_stats->HCInReceives, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCInReceives to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInOctets, &new_vals->stats.HCInOctets, &prev_vals->old_stats->HCInOctets, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCInOctets to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInForwDatagrams, &new_vals->stats.HCInForwDatagrams, &prev_vals->old_stats->HCInForwDatagrams, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCInForwDatagrams to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInDelivers, &new_vals->stats.HCInDelivers, &prev_vals->old_stats->HCInDelivers, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCInDelivers to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutRequests, &new_vals->stats.HCOutRequests, &prev_vals->old_stats->HCOutRequests, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutRequests to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutForwDatagrams, &new_vals->stats.HCOutForwDatagrams, &prev_vals->old_stats->HCOutForwDatagrams, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutForwDatagrams to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutTransmits, &new_vals->stats.HCOutTransmits, &prev_vals->old_stats->HCOutTransmits, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutTransmits to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutOctets, &new_vals->stats.HCOutOctets, &prev_vals->old_stats->HCOutOctets, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutOctets to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInMcastPkts, &new_vals->stats.HCInMcastPkts, &prev_vals->old_stats->HCInMcastPkts, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCInMcastPkts to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInMcastOctets, &new_vals->stats.HCInMcastOctets, &prev_vals->old_stats->HCInMcastOctets, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCInMcastOctets to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutMcastPkts, &new_vals->stats.HCOutMcastPkts, &prev_vals->old_stats->HCOutMcastPkts, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutMcastPkts to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutMcastOctets, &new_vals->stats.HCOutMcastOctets, &prev_vals->old_stats->HCOutMcastOctets, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutMcastOctets to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInBcastPkts, &new_vals->stats.HCInBcastPkts, &prev_vals->old_stats->HCInBcastPkts, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCInBcastPkts to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutBcastPkts, &new_vals->stats.HCOutBcastPkts, &prev_vals->old_stats->HCOutBcastPkts, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutBcastPkts to 64bits in %s\n", prev_vals->tableName)); } /* * if we've decided we no longer need to check wraps, free old stats */ if (0 == need_wrap_check) { SNMP_FREE(prev_vals->old_stats); } else { /* * update old stats from new stats. * careful - old_stats is a pointer to stats... */ memcpy(prev_vals->old_stats, &new_vals->stats, sizeof(new_vals->stats)); } _calculate_entries(prev_vals); return 0; }
/** Initialize the dot1dBasePortTable table by defining its contents and how it's structured */ void initialize_table_dot1dBasePortTable(void) { static oid dot1dBasePortTable_oid[] = {1,3,6,1,2,1,17,1,4}; netsnmp_table_registration_info *table_info; netsnmp_handler_registration *my_handler; netsnmp_iterator_info *iinfo; /** create the table registration information structures */ table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); my_handler = netsnmp_create_handler_registration("dot1dBasePortTable", dot1dBasePortTable_handler, dot1dBasePortTable_oid, OID_LENGTH(dot1dBasePortTable_oid), HANDLER_CAN_RONLY ); if (!my_handler || !table_info || !iinfo) { snmp_log(LOG_ERR, "malloc failed in initialize_table_dot1dBasePortTable"); if (my_handler != NULL) { SNMP_FREE(my_handler); } if (table_info != NULL) { SNMP_FREE(table_info); } if (iinfo != NULL) { SNMP_FREE(iinfo); } return; /** Serious error. */ } /*************************************************** * Setting up the table's definition */ netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, /** index: dot1dBasePort */ 0); /** Define the minimum and maximum accessible columns. This optimizes retrival. */ table_info->min_column = 1; table_info->max_column = 5; /** iterator access routines */ iinfo->get_first_data_point = dot1dBasePortTable_get_first_data_point; iinfo->get_next_data_point = dot1dBasePortTable_get_next_data_point; /* iinfo->make_data_context = dot1dBasePortTable_context_convert_function; */ iinfo->free_data_context = dot1dBasePortTable_data_free; /** pick *only* one of these if you use them */ /* iinfo->free_loop_context = dot1dBasePortTable_loop_free; */ iinfo->free_loop_context_at_end = dot1dBasePortTable_loop_free; /** tie the two structures together */ iinfo->table_reginfo = table_info; /*************************************************** * registering the table with the master agent */ DEBUGMSGTL(("initialize_table_dot1dBasePortTable", "Registering table dot1dBasePortTable as a table iterator\n")); netsnmp_register_table_iterator(my_handler, iinfo); }
void init_nsDebug(void) { /* * OIDs for the debugging control scalar objects * * Note that these we're registering the full object rather * than the (sole) valid instance in each case, in order * to handle requests for invalid instances properly. */ const oid nsDebugEnabled_oid[] = { nsConfigDebug, 1}; const oid nsDebugOutputAll_oid[] = { nsConfigDebug, 2}; const oid nsDebugDumpPdu_oid[] = { nsConfigDebug, 3}; /* * ... and for the token table. */ #define DBGTOKEN_PREFIX 2 #define DBGTOKEN_ENABLED 3 #define DBGTOKEN_STATUS 4 const oid nsDebugTokenTable_oid[] = { nsConfigDebug, 4}; netsnmp_table_registration_info *table_info; netsnmp_iterator_info *iinfo; /* * Register the scalar objects... */ DEBUGMSGTL(("nsDebugScalars", "Initializing\n")); netsnmp_register_scalar( netsnmp_create_handler_registration( "nsDebugEnabled", handle_nsDebugEnabled, nsDebugEnabled_oid, OID_LENGTH(nsDebugEnabled_oid), HANDLER_CAN_RWRITE) ); netsnmp_register_scalar( netsnmp_create_handler_registration( "nsDebugOutputAll", handle_nsDebugOutputAll, nsDebugOutputAll_oid, OID_LENGTH(nsDebugOutputAll_oid), HANDLER_CAN_RWRITE) ); netsnmp_register_scalar( netsnmp_create_handler_registration( "nsDebugDumpPdu", handle_nsDebugDumpPdu, nsDebugDumpPdu_oid, OID_LENGTH(nsDebugDumpPdu_oid), HANDLER_CAN_RWRITE) ); /* * ... and the table. * We need to define the column structure and indexing.... */ table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); if (!table_info) { return; } netsnmp_table_helper_add_indexes(table_info, ASN_PRIV_IMPLIED_OCTET_STR, 0); table_info->min_column = DBGTOKEN_STATUS; table_info->max_column = DBGTOKEN_STATUS; /* * .... and the iteration information .... */ iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); if (!iinfo) { return; } iinfo->get_first_data_point = get_first_debug_entry; iinfo->get_next_data_point = get_next_debug_entry; iinfo->table_reginfo = table_info; /* * .... and register the table with the agent. */ netsnmp_register_table_iterator2( netsnmp_create_handler_registration( "tzDebugTable", handle_nsDebugTable, nsDebugTokenTable_oid, OID_LENGTH(nsDebugTokenTable_oid), HANDLER_CAN_RWRITE), iinfo); }
/** * update stats * * @retval 0 : success * @retval -1 : error */ int netsnmp_access_interface_entry_update_stats(netsnmp_interface_entry * prev_vals, netsnmp_interface_entry * new_vals) { DEBUGMSGTL(("access:interface", "check_wrap\n")); /* * sanity checks */ if ((NULL == prev_vals) || (NULL == new_vals) || (NULL == prev_vals->name) || (NULL == new_vals->name) || (0 != strncmp(prev_vals->name, new_vals->name, strlen(prev_vals->name)))) return -1; /* * if we've determined that we have 64 bit counters, just copy them. */ if (0 == need_wrap_check) { memcpy(&prev_vals->stats, &new_vals->stats, sizeof(new_vals->stats)); return 0; } if (NULL == prev_vals->old_stats) { /* * if we don't have old stats, copy previous stats */ prev_vals->old_stats = SNMP_MALLOC_TYPEDEF(netsnmp_interface_stats); if (NULL == prev_vals->old_stats) { return -2; } memcpy(prev_vals->old_stats, &prev_vals->stats, sizeof(prev_vals->stats)); } if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.ibytes, &new_vals->stats.ibytes, &prev_vals->old_stats->ibytes, &need_wrap_check)) DEBUGMSGTL(("access:interface", "Error expanding ifHCInOctets to 64bits\n")); if (new_vals->ns_flags & NETSNMP_INTERFACE_FLAGS_CALCULATE_UCAST) { if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.iall, &new_vals->stats.iall, &prev_vals->old_stats->iall, &need_wrap_check)) DEBUGMSGTL(("access:interface", "Error expanding packet count to 64bits\n")); } else { if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.iucast, &new_vals->stats.iucast, &prev_vals->old_stats->iucast, &need_wrap_check)) DEBUGMSGTL(("access:interface", "Error expanding ifHCInUcastPkts to 64bits\n")); } if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.iucast, &new_vals->stats.iucast, &prev_vals->old_stats->iucast, &need_wrap_check)) DEBUGMSGTL(("access:interface", "Error expanding ifHCInUcastPkts to 64bits\n")); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.imcast, &new_vals->stats.imcast, &prev_vals->old_stats->imcast, &need_wrap_check)) DEBUGMSGTL(("access:interface", "Error expanding ifHCInMulticastPkts to 64bits\n")); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.ibcast, &new_vals->stats.ibcast, &prev_vals->old_stats->ibcast, &need_wrap_check)) DEBUGMSGTL(("access:interface", "Error expanding ifHCInBroadcastPkts to 64bits\n")); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.obytes, &new_vals->stats.obytes, &prev_vals->old_stats->obytes, &need_wrap_check)) DEBUGMSGTL(("access:interface", "Error expanding ifHCOutOctets to 64bits\n")); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.oucast, &new_vals->stats.oucast, &prev_vals->old_stats->oucast, &need_wrap_check)) DEBUGMSGTL(("access:interface", "Error expanding ifHCOutUcastPkts to 64bits\n")); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.omcast, &new_vals->stats.omcast, &prev_vals->old_stats->omcast, &need_wrap_check)) DEBUGMSGTL(("access:interface", "Error expanding ifHCOutMulticastPkts to 64bits\n")); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.obcast, &new_vals->stats.obcast, &prev_vals->old_stats->obcast, &need_wrap_check)) DEBUGMSGTL(("access:interface", "Error expanding ifHCOutBroadcastPkts to 64bits\n")); /* * Copy 32 bit counters */ prev_vals->stats.ierrors = new_vals->stats.ierrors; prev_vals->stats.idiscards = new_vals->stats.idiscards; prev_vals->stats.iunknown_protos = new_vals->stats.iunknown_protos; prev_vals->stats.inucast = new_vals->stats.inucast; prev_vals->stats.oerrors = new_vals->stats.oerrors; prev_vals->stats.odiscards = new_vals->stats.odiscards; prev_vals->stats.oqlen = new_vals->stats.oqlen; prev_vals->stats.collisions = new_vals->stats.collisions; prev_vals->stats.onucast = new_vals->stats.onucast; /* * if we've decided we no longer need to check wraps, free old stats */ if (0 == need_wrap_check) { SNMP_FREE(prev_vals->old_stats); } else { /* * update old stats from new stats. * careful - old_stats is a pointer to stats... */ memcpy(prev_vals->old_stats, &new_vals->stats, sizeof(new_vals->stats)); } return 0; }
void mteTrigger_run( unsigned int reg, void *clientarg) { struct mteTrigger *entry = (struct mteTrigger *)clientarg; netsnmp_variable_list *var, *vtmp; netsnmp_variable_list *vp1, *vp1_prev; netsnmp_variable_list *vp2, *vp2_prev; netsnmp_variable_list *dvar = NULL; netsnmp_variable_list *dv1 = NULL, *dv2 = NULL; netsnmp_variable_list sysUT_var; int cmp = 0, n, n2; long value; const char *reason; if (!entry) { snmp_alarm_unregister( reg ); return; } if (!(entry->flags & MTE_TRIGGER_FLAG_ENABLED ) || !(entry->flags & MTE_TRIGGER_FLAG_ACTIVE ) || !(entry->flags & MTE_TRIGGER_FLAG_VALID )) { return; } { extern netsnmp_agent_session *netsnmp_processing_set; if (netsnmp_processing_set) { /* * netsnmp_handle_request will not be responsive to our efforts to * Retrieve the requested MIB value(s)... * so we will skip it. * https://sourceforge.net/tracker/ * index.php?func=detail&aid=1557406&group_id=12694&atid=112694 */ DEBUGMSGTL(("disman:event:trigger:monitor", "Skipping trigger (%s) while netsnmp_processing_set\n", entry->mteTName)); return; } } /* * Retrieve the requested MIB value(s)... */ DEBUGMSGTL(( "disman:event:trigger:monitor", "Running trigger (%s)\n", entry->mteTName)); var = (netsnmp_variable_list *)SNMP_MALLOC_TYPEDEF( netsnmp_variable_list ); if (!var) { _mteTrigger_failure("failed to create mteTrigger query varbind"); return; } snmp_set_var_objid( var, entry->mteTriggerValueID, entry->mteTriggerValueID_len ); if ( entry->flags & MTE_TRIGGER_FLAG_VWILD ) { n = netsnmp_query_walk( var, entry->session ); } else { n = netsnmp_query_get( var, entry->session ); } if ( n != SNMP_ERR_NOERROR ) { DEBUGMSGTL(( "disman:event:trigger:monitor", "Trigger query (%s) failed: %d\n", (( entry->flags & MTE_TRIGGER_FLAG_VWILD ) ? "walk" : "get"), n)); _mteTrigger_failure( "failed to run mteTrigger query" ); snmp_free_varbind(var); return; } /* * ... canonicalise the results (to simplify later comparisons)... */ vp1 = var; vp1_prev = NULL; vp2 = entry->old_results; vp2_prev = NULL; entry->count=0; while (vp1) { /* * Flatten various missing values/exceptions into a single form */ switch (vp1->type) { case SNMP_NOSUCHINSTANCE: case SNMP_NOSUCHOBJECT: case ASN_PRIV_RETRY: /* Internal only ? */ vp1->type = ASN_NULL; } /* * Keep track of how many entries have been retrieved. */ entry->count++; /* * Ensure previous and current result match * (with corresponding entries in both lists) * and set the flags indicating which triggers are armed */ if (vp2) { cmp = snmp_oid_compare(vp1->name, vp1->name_length, vp2->name, vp2->name_length); if ( cmp < 0 ) { /* * If a new value has appeared, insert a matching * dummy entry into the previous result list. * * XXX - check how this is best done. */ vtmp = SNMP_MALLOC_TYPEDEF( netsnmp_variable_list ); if (!vtmp) { _mteTrigger_failure( "failed to create mteTrigger temp varbind"); snmp_free_varbind(var); return; } vtmp->type = ASN_NULL; snmp_set_var_objid( vtmp, vp1->name, vp1->name_length ); vtmp->next_variable = vp2; if (vp2_prev) { vp2_prev->next_variable = vtmp; } else { entry->old_results = vtmp; } vp2_prev = vtmp; vp1->index = MTE_ARMED_ALL; /* XXX - plus a new flag */ vp1_prev = vp1; vp1 = vp1->next_variable; } else if ( cmp == 0 ) { /* * If it's a continuing entry, just copy across the armed flags */ vp1->index = vp2->index; vp1_prev = vp1; vp1 = vp1->next_variable; vp2_prev = vp2; vp2 = vp2->next_variable; } else { /* * If a value has just disappeared, insert a * matching dummy entry into the current result list. * * XXX - check how this is best done. * */ if ( vp2->type != ASN_NULL ) { vtmp = SNMP_MALLOC_TYPEDEF( netsnmp_variable_list ); if (!vtmp) { _mteTrigger_failure( "failed to create mteTrigger temp varbind"); snmp_free_varbind(var); return; } vtmp->type = ASN_NULL; snmp_set_var_objid( vtmp, vp2->name, vp2->name_length ); vtmp->next_variable = vp1; if (vp1_prev) { vp1_prev->next_variable = vtmp; } else { var = vtmp; } vp1_prev = vtmp; vp2_prev = vp2; vp2 = vp2->next_variable; } else { /* * But only if this entry has *just* disappeared. If the * entry from the last run was a dummy too, then remove it. * (leaving vp2_prev unchanged) */ vtmp = vp2; if (vp2_prev) { vp2_prev->next_variable = vp2->next_variable; } else { entry->old_results = vp2->next_variable; } vp2 = vp2->next_variable; vtmp->next_variable = NULL; snmp_free_varbind( vtmp ); } } } else { /* * No more old results to compare. * Either all remaining values have only just been created ... * (and we need to create dummy 'old' entries for them) */ if ( vp2_prev ) { vtmp = SNMP_MALLOC_TYPEDEF( netsnmp_variable_list ); if (!vtmp) { _mteTrigger_failure( "failed to create mteTrigger temp varbind"); snmp_free_varbind(var); return; } vtmp->type = ASN_NULL; snmp_set_var_objid( vtmp, vp1->name, vp1->name_length ); vtmp->next_variable = vp2_prev->next_variable; vp2_prev->next_variable = vtmp; vp2_prev = vtmp; } /* * ... or this is the first run through * (and there were no old results at all) * * In either case, mark the current entry as armed and new. * Note that we no longer need to maintain 'vp1_prev' */ vp1->index = MTE_ARMED_ALL; /* XXX - plus a new flag */ vp1 = vp1->next_variable; } } /* * ... and then work through these result(s), deciding * whether or not to trigger the corresponding event. * * Note that there's no point in evaluating Existence or * Boolean tests if there's no corresponding event. * (Even if the trigger matched, nothing would be done anyway). */ if ((entry->mteTriggerTest & MTE_TRIGGER_EXISTENCE) && (entry->mteTExEvent[0] != '\0' )) { /* * If we don't have a record of previous results, * this must be the first time through, so consider * the mteTriggerExistenceStartup tests. */ if ( !entry->old_results ) { /* * With the 'present(0)' test, the trigger should fire * for each value in the varbind list returned * (whether the monitored value is wildcarded or not). */ if (entry->mteTExTest & entry->mteTExStartup & MTE_EXIST_PRESENT) { for (vp1 = var; vp1; vp1=vp1->next_variable) { DEBUGMSGTL(( "disman:event:trigger:fire", "Firing initial existence test: ")); DEBUGMSGOID(("disman:event:trigger:fire", vp1->name, vp1->name_length)); DEBUGMSG(( "disman:event:trigger:fire", " (present)\n"));; entry->mteTriggerXOwner = entry->mteTExObjOwner; entry->mteTriggerXObjects = entry->mteTExObjects; entry->mteTriggerFired = vp1; n = entry->mteTriggerValueID_len; mteEvent_fire(entry->mteTExEvOwner, entry->mteTExEvent, entry, vp1->name+n, vp1->name_length-n); } } /* * An initial 'absent(1)' test only makes sense when * monitoring a non-wildcarded OID (how would we know * which rows of the table "ought" to exist, but don't?) */ if (entry->mteTExTest & entry->mteTExStartup & MTE_EXIST_ABSENT) { if (!(entry->flags & MTE_TRIGGER_FLAG_VWILD) && var->type == ASN_NULL ) { DEBUGMSGTL(( "disman:event:trigger:fire", "Firing initial existence test: ")); DEBUGMSGOID(("disman:event:trigger:fire", var->name, var->name_length)); DEBUGMSG(( "disman:event:trigger:fire", " (absent)\n"));; entry->mteTriggerXOwner = entry->mteTExObjOwner; entry->mteTriggerXObjects = entry->mteTExObjects; /* * It's unclear what value the 'mteHotValue' payload * should take when a monitored instance does not * exist on startup. The only sensible option is * to report a NULL value, but this clashes with * the syntax of the mteHotValue MIB object. */ entry->mteTriggerFired = var; n = entry->mteTriggerValueID_len; mteEvent_fire(entry->mteTExEvOwner, entry->mteTExEvent, entry, var->name+n, var->name_length-n); } } } /* !old_results */ /* * Otherwise, compare the current set of results with * the previous ones, looking for changes. We can * assume that the two lists match (see above). */ else { for (vp1 = var, vp2 = entry->old_results; vp1; vp1=vp1->next_variable, vp2=vp2->next_variable) { /* Use this field to indicate that the trigger should fire */ entry->mteTriggerFired = NULL; reason = NULL; if ((entry->mteTExTest & MTE_EXIST_PRESENT) && (vp1->type != ASN_NULL) && (vp2->type == ASN_NULL)) { /* A new instance has appeared */ entry->mteTriggerFired = vp1; reason = "(present)"; } else if ((entry->mteTExTest & MTE_EXIST_ABSENT) && (vp1->type == ASN_NULL) && (vp2->type != ASN_NULL)) { /* * A previous instance has disappeared. * * It's unclear what value the 'mteHotValue' payload * should take when this happens - the previous * value (vp2), or a NULL value (vp1) ? * NULL makes more sense logically, but clashes * with the syntax of the mteHotValue MIB object. */ entry->mteTriggerFired = vp2; reason = "(absent)"; } else if ((entry->mteTExTest & MTE_EXIST_CHANGED) && ((vp1->val_len != vp2->val_len) || (memcmp( vp1->val.string, vp2->val.string, vp1->val_len) != 0 ))) { /* * This comparison detects changes in *any* type * of value, numeric or string (or even OID). * * Unfortunately, the default 'mteTriggerFired' * notification payload can't report non-numeric * changes properly (see syntax of 'mteHotValue') */ entry->mteTriggerFired = vp1; reason = "(changed)"; } if ( entry->mteTriggerFired ) { /* * One of the above tests has matched, * so fire the trigger. */ DEBUGMSGTL(( "disman:event:trigger:fire", "Firing existence test: ")); DEBUGMSGOID(("disman:event:trigger:fire", vp1->name, vp1->name_length)); DEBUGMSG(( "disman:event:trigger:fire", " %s\n", reason));; entry->mteTriggerXOwner = entry->mteTExObjOwner; entry->mteTriggerXObjects = entry->mteTExObjects; n = entry->mteTriggerValueID_len; mteEvent_fire(entry->mteTExEvOwner, entry->mteTExEvent, entry, vp1->name+n, vp1->name_length-n); } } } /* !old_results - end of else block */ } /* MTE_TRIGGER_EXISTENCE */ if (( entry->mteTriggerTest & MTE_TRIGGER_BOOLEAN ) || ( entry->mteTriggerTest & MTE_TRIGGER_THRESHOLD )) { /* * Although Existence tests can work with any syntax values, * Boolean and Threshold tests are integer-only. Ensure that * the returned value(s) are appropriate. * * Note that we only need to check the first value, since all * instances of a given object should have the same syntax. */ switch (var->type) { case ASN_INTEGER: case ASN_COUNTER: case ASN_GAUGE: case ASN_TIMETICKS: case ASN_UINTEGER: case ASN_COUNTER64: #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES case ASN_OPAQUE_COUNTER64: case ASN_OPAQUE_U64: case ASN_OPAQUE_I64: #endif /* OK */ break; default: /* * Other syntax values can't be used for Boolean/Theshold * tests. Report this as an error, and then rotate the * results ready for the next run, (which will presumably * also detect this as an error once again!) */ DEBUGMSGTL(( "disman:event:trigger:fire", "Returned non-integer result(s): ")); DEBUGMSGOID(("disman:event:trigger:fire", var->name, var->name_length)); DEBUGMSG(( "disman:event:trigger:fire", " (boolean/threshold) %d\n", var->type));; snmp_free_varbind( entry->old_results ); entry->old_results = var; return; } /* * Retrieve the discontinuity markers for delta-valued samples. * (including sysUpTime.0 if not specified explicitly). */ if ( entry->flags & MTE_TRIGGER_FLAG_DELTA ) { /* * We'll need sysUpTime.0 regardless... */ DEBUGMSGTL(("disman:event:delta", "retrieve sysUpTime.0\n")); memset( &sysUT_var, 0, sizeof( netsnmp_variable_list )); snmp_set_var_objid( &sysUT_var, _sysUpTime_instance, _sysUpTime_inst_len ); netsnmp_query_get( &sysUT_var, entry->session ); if (!(entry->flags & MTE_TRIGGER_FLAG_SYSUPT)) { /* * ... but only retrieve the configured discontinuity * marker(s) if they refer to something different. */ DEBUGMSGTL(( "disman:event:delta", "retrieve discontinuity marker(s): ")); DEBUGMSGOID(("disman:event:delta", entry->mteDeltaDiscontID, entry->mteDeltaDiscontID_len )); DEBUGMSG(( "disman:event:delta", " %s\n", (entry->flags & MTE_TRIGGER_FLAG_DWILD ? " (wild)" : ""))); dvar = (netsnmp_variable_list *) SNMP_MALLOC_TYPEDEF( netsnmp_variable_list ); if (!dvar) { _mteTrigger_failure( "failed to create mteTrigger delta query varbind"); return; } snmp_set_var_objid( dvar, entry->mteDeltaDiscontID, entry->mteDeltaDiscontID_len ); if ( entry->flags & MTE_TRIGGER_FLAG_DWILD ) { n = netsnmp_query_walk( dvar, entry->session ); } else { n = netsnmp_query_get( dvar, entry->session ); } if ( n != SNMP_ERR_NOERROR ) { _mteTrigger_failure( "failed to run mteTrigger delta query" ); snmp_free_varbind( dvar ); return; } } /* * We can't calculate delta values the first time through, * so there's no point in evaluating the remaining tests. * * Save the results (and discontinuity markers), * ready for the next run. */ if ( !entry->old_results ) { entry->old_results = var; entry->old_deltaDs = dvar; entry->sysUpTime = *sysUT_var.val.integer; return; } /* * If the sysUpTime marker has been reset (or strictly, * has advanced by less than the monitor frequency), * there's no point in trying the remaining tests. */ if (*sysUT_var.val.integer < entry->sysUpTime) { DEBUGMSGTL(( "disman:event:delta", "single discontinuity: (sysUT)\n")); snmp_free_varbind( entry->old_results ); snmp_free_varbind( entry->old_deltaDs ); entry->old_results = var; entry->old_deltaDs = dvar; entry->sysUpTime = *sysUT_var.val.integer; return; } /* * Similarly if a separate (non-wildcarded) discontinuity * marker has changed, then there's no * point in trying to evaluate these tests either. */ if (!(entry->flags & MTE_TRIGGER_FLAG_DWILD) && !(entry->flags & MTE_TRIGGER_FLAG_SYSUPT) && (!entry->old_deltaDs || (entry->old_deltaDs->val.integer != dvar->val.integer))) { DEBUGMSGTL(( "disman:event:delta", "single discontinuity: (")); DEBUGMSGOID(( "disman:event:delta", entry->mteDeltaDiscontID, entry->mteDeltaDiscontID_len)); DEBUGMSG(( "disman:event:delta", ")\n")); snmp_free_varbind( entry->old_results ); snmp_free_varbind( entry->old_deltaDs ); entry->old_results = var; entry->old_deltaDs = dvar; entry->sysUpTime = *sysUT_var.val.integer; return; } /* * Ensure that the list of (wildcarded) discontinuity * markers matches the list of monitored values * (inserting/removing discontinuity varbinds as needed) * * XXX - An alternative approach would be to use the list * of monitored values (instance subidentifiers) to build * the exact list of delta markers to retrieve earlier. */ if (entry->flags & MTE_TRIGGER_FLAG_DWILD) { vp1 = var; vp2 = dvar; vp2_prev = NULL; n = entry->mteTriggerValueID_len; n2 = entry->mteDeltaDiscontID_len; while (vp1) { /* * For each monitored instance, check whether * there's a matching discontinuity entry. */ cmp = snmp_oid_compare(vp1->name+n, vp1->name_length-n, vp2->name+n2, vp2->name_length-n2 ); if ( cmp < 0 ) { /* * If a discontinuity entry is missing, * insert a (dummy) varbind. * The corresponding delta calculation will * fail, but this simplifies the later code. */ vtmp = (netsnmp_variable_list *) SNMP_MALLOC_TYPEDEF( netsnmp_variable_list ); if (!vtmp) { _mteTrigger_failure( "failed to create mteTrigger discontinuity varbind"); snmp_free_varbind(dvar); return; } snmp_set_var_objid(vtmp, entry->mteDeltaDiscontID, entry->mteDeltaDiscontID_len); /* XXX - append instance subids */ vtmp->next_variable = vp2; vp2_prev->next_variable = vtmp; vp2_prev = vtmp; vp1 = vp1->next_variable; } else if ( cmp == 0 ) { /* * Matching discontinuity entry - all OK. */ vp2_prev = vp2; vp2 = vp2->next_variable; vp1 = vp1->next_variable; } else { /* * Remove unneeded discontinuity entry */ vtmp = vp2; vp2_prev->next_variable = vp2->next_variable; vp2 = vp2->next_variable; vtmp->next_variable = NULL; snmp_free_varbind( vtmp ); } } /* * XXX - Now need to ensure that the old list of * delta discontinuity markers matches as well. */ } } /* delta samples */ } /* Boolean/Threshold test checks */ /* * Only run the Boolean tests if there's an event to be triggered */ if ((entry->mteTriggerTest & MTE_TRIGGER_BOOLEAN) && (entry->mteTBoolEvent[0] != '\0' )) { if (entry->flags & MTE_TRIGGER_FLAG_DELTA) { vp2 = entry->old_results; if (entry->flags & MTE_TRIGGER_FLAG_DWILD) { dv1 = dvar; dv2 = entry->old_deltaDs; } } for ( vp1 = var; vp1; vp1=vp1->next_variable ) { /* * Determine the value to be monitored... */ if ( !vp1->val.integer ) { /* No value */ if ( vp2 ) vp2 = vp2->next_variable; continue; } if (entry->flags & MTE_TRIGGER_FLAG_DELTA) { if (entry->flags & MTE_TRIGGER_FLAG_DWILD) { /* * We've already checked any non-wildcarded * discontinuity markers (inc. sysUpTime.0). * Validate this particular sample against * the relevant wildcarded marker... */ if ((dv1->type == ASN_NULL) || (dv1->type != dv2->type) || (*dv1->val.integer != *dv2->val.integer)) { /* * Bogus or changed discontinuity marker. * Need to skip this sample. */ DEBUGMSGTL(( "disman:event:delta", "discontinuity occurred: ")); DEBUGMSGOID(("disman:event:delta", vp1->name, vp1->name_length )); DEBUGMSG(( "disman:event:delta", " \n" )); vp2 = vp2->next_variable; continue; } } /* * ... and check there is a previous sample to calculate * the delta value against (regardless of whether the * discontinuity marker was wildcarded or not). */ if (vp2->type == ASN_NULL) { DEBUGMSGTL(( "disman:event:delta", "missing sample: ")); DEBUGMSGOID(("disman:event:delta", vp1->name, vp1->name_length )); DEBUGMSG(( "disman:event:delta", " \n" )); vp2 = vp2->next_variable; continue; } value = (*vp1->val.integer - *vp2->val.integer); DEBUGMSGTL(( "disman:event:delta", "delta sample: ")); DEBUGMSGOID(("disman:event:delta", vp1->name, vp1->name_length )); DEBUGMSG(( "disman:event:delta", " (%ld - %ld) = %ld\n", *vp1->val.integer, *vp2->val.integer, value)); vp2 = vp2->next_variable; } else { value = *vp1->val.integer; } /* * ... evaluate the comparison ... */ switch (entry->mteTBoolComparison) { case MTE_BOOL_UNEQUAL: cmp = ( value != entry->mteTBoolValue ); break; case MTE_BOOL_EQUAL: cmp = ( value == entry->mteTBoolValue ); break; case MTE_BOOL_LESS: cmp = ( value < entry->mteTBoolValue ); break; case MTE_BOOL_LESSEQUAL: cmp = ( value <= entry->mteTBoolValue ); break; case MTE_BOOL_GREATER: cmp = ( value > entry->mteTBoolValue ); break; case MTE_BOOL_GREATEREQUAL: cmp = ( value >= entry->mteTBoolValue ); break; } DEBUGMSGTL(( "disman:event:delta", "Bool comparison: (%ld %s %ld) %d\n", value, _ops[entry->mteTBoolComparison], entry->mteTBoolValue, cmp)); /* * ... and decide whether to trigger the event. * (using the 'index' field of the varbind structure * to remember whether the trigger has already fired) */ if ( cmp ) { if (vp1->index & MTE_ARMED_BOOLEAN ) { vp1->index &= ~MTE_ARMED_BOOLEAN; /* * NB: Clear the trigger armed flag even if the * (starting) event dosn't actually fire. * Otherwise initially true (but suppressed) * triggers will fire on the *second* probe. */ if ( entry->old_results || (entry->flags & MTE_TRIGGER_FLAG_BSTART)) { DEBUGMSGTL(( "disman:event:trigger:fire", "Firing boolean test: ")); DEBUGMSGOID(("disman:event:trigger:fire", vp1->name, vp1->name_length)); DEBUGMSG(( "disman:event:trigger:fire", "%s\n", (entry->old_results ? "" : " (startup)"))); entry->mteTriggerXOwner = entry->mteTBoolObjOwner; entry->mteTriggerXObjects = entry->mteTBoolObjects; /* * XXX - when firing a delta-based trigger, should * 'mteHotValue' report the actual value sampled * (as here), or the delta that triggered the event ? */ entry->mteTriggerFired = vp1; n = entry->mteTriggerValueID_len; mteEvent_fire(entry->mteTBoolEvOwner, entry->mteTBoolEvent, entry, vp1->name+n, vp1->name_length-n); } } } else { vp1->index |= MTE_ARMED_BOOLEAN; } } } /* * Only run the basic threshold tests if there's an event to * be triggered. (Either rising or falling will do) */ if (( entry->mteTriggerTest & MTE_TRIGGER_THRESHOLD ) && ((entry->mteTThRiseEvent[0] != '\0' ) || (entry->mteTThFallEvent[0] != '\0' ))) { /* * The same delta-sample validation from Boolean * tests also applies here too. */ if (entry->flags & MTE_TRIGGER_FLAG_DELTA) { vp2 = entry->old_results; if (entry->flags & MTE_TRIGGER_FLAG_DWILD) { dv1 = dvar; dv2 = entry->old_deltaDs; } } for ( vp1 = var; vp1; vp1=vp1->next_variable ) { /* * Determine the value to be monitored... */ if ( !vp1->val.integer ) { /* No value */ if ( vp2 ) vp2 = vp2->next_variable; continue; } if (entry->flags & MTE_TRIGGER_FLAG_DELTA) { if (entry->flags & MTE_TRIGGER_FLAG_DWILD) { /* * We've already checked any non-wildcarded * discontinuity markers (inc. sysUpTime.0). * Validate this particular sample against * the relevant wildcarded marker... */ if ((dv1->type == ASN_NULL) || (dv1->type != dv2->type) || (*dv1->val.integer != *dv2->val.integer)) { /* * Bogus or changed discontinuity marker. * Need to skip this sample. */ vp2 = vp2->next_variable; continue; } } /* * ... and check there is a previous sample to calculate * the delta value against (regardless of whether the * discontinuity marker was wildcarded or not). */ if (vp2->type == ASN_NULL) { vp2 = vp2->next_variable; continue; } value = (*vp1->val.integer - *vp2->val.integer); vp2 = vp2->next_variable; } else { value = *vp1->val.integer; } /* * ... evaluate the single-value comparisons, * and decide whether to trigger the event. */ cmp = vp1->index; /* working copy of 'armed' flags */ if ( value >= entry->mteTThRiseValue ) { if (cmp & MTE_ARMED_TH_RISE ) { cmp &= ~MTE_ARMED_TH_RISE; cmp |= MTE_ARMED_TH_FALL; /* * NB: Clear the trigger armed flag even if the * (starting) event dosn't actually fire. * Otherwise initially true (but suppressed) * triggers will fire on the *second* probe. * Similarly for falling thresholds (see below). */ if ( entry->old_results || (entry->mteTThStartup & MTE_THRESH_START_RISE)) { DEBUGMSGTL(( "disman:event:trigger:fire", "Firing rising threshold test: ")); DEBUGMSGOID(("disman:event:trigger:fire", vp1->name, vp1->name_length)); DEBUGMSG(( "disman:event:trigger:fire", "%s\n", (entry->old_results ? "" : " (startup)"))); /* * If no riseEvent is configured, we need still to * set the armed flags appropriately, but there's * no point in trying to fire the (missing) event. */ if (entry->mteTThRiseEvent[0] != '\0' ) { entry->mteTriggerXOwner = entry->mteTThObjOwner; entry->mteTriggerXObjects = entry->mteTThObjects; entry->mteTriggerFired = vp1; n = entry->mteTriggerValueID_len; mteEvent_fire(entry->mteTThRiseOwner, entry->mteTThRiseEvent, entry, vp1->name+n, vp1->name_length-n); } } } } if ( value <= entry->mteTThFallValue ) { if (cmp & MTE_ARMED_TH_FALL ) { cmp &= ~MTE_ARMED_TH_FALL; cmp |= MTE_ARMED_TH_RISE; /* Clear the trigger armed flag (see above) */ if ( entry->old_results || (entry->mteTThStartup & MTE_THRESH_START_FALL)) { DEBUGMSGTL(( "disman:event:trigger:fire", "Firing falling threshold test: ")); DEBUGMSGOID(("disman:event:trigger:fire", vp1->name, vp1->name_length)); DEBUGMSG(( "disman:event:trigger:fire", "%s\n", (entry->old_results ? "" : " (startup)"))); /* * Similarly, if no fallEvent is configured, * there's no point in trying to fire it either. */ if (entry->mteTThRiseEvent[0] != '\0' ) { entry->mteTriggerXOwner = entry->mteTThObjOwner; entry->mteTriggerXObjects = entry->mteTThObjects; entry->mteTriggerFired = vp1; n = entry->mteTriggerValueID_len; mteEvent_fire(entry->mteTThFallOwner, entry->mteTThFallEvent, entry, vp1->name+n, vp1->name_length-n); } } } } vp1->index = cmp; } } /* * The same processing also works for delta-threshold tests (if configured) */ if (( entry->mteTriggerTest & MTE_TRIGGER_THRESHOLD ) && ((entry->mteTThDRiseEvent[0] != '\0' ) || (entry->mteTThDFallEvent[0] != '\0' ))) { /* * Delta-threshold tests can only be used with * absolute valued samples. */ vp2 = entry->old_results; if (entry->flags & MTE_TRIGGER_FLAG_DELTA) { DEBUGMSGTL(( "disman:event:trigger", "Delta-threshold on delta-sample\n")); } else if ( vp2 != NULL ) { for ( vp1 = var; vp1; vp1=vp1->next_variable ) { /* * Determine the value to be monitored... * (similar to previous delta-sample processing, * but without the discontinuity marker checks) */ if (!vp2) { break; /* Run out of 'old' values */ } if (( !vp1->val.integer ) || (vp2->type == ASN_NULL)) { vp2 = vp2->next_variable; continue; } value = (*vp1->val.integer - *vp2->val.integer); vp2 = vp2->next_variable; /* * ... evaluate the single-value comparisons, * and decide whether to trigger the event. */ cmp = vp1->index; /* working copy of 'armed' flags */ if ( value >= entry->mteTThDRiseValue ) { if (vp1->index & MTE_ARMED_TH_DRISE ) { DEBUGMSGTL(( "disman:event:trigger:fire", "Firing rising delta threshold test: ")); DEBUGMSGOID(("disman:event:trigger:fire", vp1->name, vp1->name_length)); DEBUGMSG(( "disman:event:trigger:fire", "\n")); cmp &= ~MTE_ARMED_TH_DRISE; cmp |= MTE_ARMED_TH_DFALL; /* * If no riseEvent is configured, we need still to * set the armed flags appropriately, but there's * no point in trying to fire the (missing) event. */ if (entry->mteTThDRiseEvent[0] != '\0' ) { entry->mteTriggerXOwner = entry->mteTThObjOwner; entry->mteTriggerXObjects = entry->mteTThObjects; entry->mteTriggerFired = vp1; n = entry->mteTriggerValueID_len; mteEvent_fire(entry->mteTThDRiseOwner, entry->mteTThDRiseEvent, entry, vp1->name+n, vp1->name_length-n); } } } if ( value <= entry->mteTThDFallValue ) { if (vp1->index & MTE_ARMED_TH_DFALL ) { DEBUGMSGTL(( "disman:event:trigger:fire", "Firing falling delta threshold test: ")); DEBUGMSGOID(("disman:event:trigger:fire", vp1->name, vp1->name_length)); DEBUGMSG(( "disman:event:trigger:fire", "\n")); cmp &= ~MTE_ARMED_TH_DFALL; cmp |= MTE_ARMED_TH_DRISE; /* * Similarly, if no fallEvent is configured, * there's no point in trying to fire it either. */ if (entry->mteTThDRiseEvent[0] != '\0' ) { entry->mteTriggerXOwner = entry->mteTThObjOwner; entry->mteTriggerXObjects = entry->mteTThObjects; entry->mteTriggerFired = vp1; n = entry->mteTriggerValueID_len; mteEvent_fire(entry->mteTThDFallOwner, entry->mteTThDFallEvent, entry, vp1->name+n, vp1->name_length-n); } } } vp1->index = cmp; } } } /* * Finally, rotate the results - ready for the next run. */ snmp_free_varbind( entry->old_results ); entry->old_results = var; if ( entry->flags & MTE_TRIGGER_FLAG_DELTA ) { snmp_free_varbind( entry->old_deltaDs ); entry->old_deltaDs = dvar; entry->sysUpTime = *sysUT_var.val.integer; } }
/** Initialize the LHANodeTable table by defining its contents and how it's structured */ void initialize_table_LHANodeTable(void) { static oid LHANodeTable_oid[] = {1,3,6,1,4,1,4682,2}; netsnmp_table_registration_info *table_info; netsnmp_handler_registration *my_handler; netsnmp_iterator_info *iinfo; /** create the table registration information structures */ table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); /** if your table is read only, it's easiest to change the HANDLER_CAN_RWRITE definition below to HANDLER_CAN_RONLY */ my_handler = netsnmp_create_handler_registration("LHANodeTable", LHANodeTable_handler, LHANodeTable_oid, OID_LENGTH(LHANodeTable_oid), HANDLER_CAN_RONLY); if (!my_handler || !table_info || !iinfo) { snmp_log(LOG_ERR, "malloc failed in initialize_table_LHANodeTable"); SNMP_FREE(iinfo); SNMP_FREE(table_info); return; /* Serious error. */ } /*************************************************** * Setting up the table's definition */ netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, /* index: LHANodeIndex */ 0); /** Define the minimum and maximum accessible columns. This optimizes retrival. */ table_info->min_column = 2; table_info->max_column = 6; /* iterator access routines */ iinfo->get_first_data_point = LHANodeTable_get_first_data_point; iinfo->get_next_data_point = LHANodeTable_get_next_data_point; /** tie the two structures together */ iinfo->table_reginfo = table_info; /*************************************************** * registering the table with the master agent */ DEBUGMSGTL(("initialize_table_LHANodeTable", "Registering table LHANodeTable as a table iterator\n")); netsnmp_register_table_iterator(my_handler, iinfo); /* * .... with a local cache */ netsnmp_inject_handler(my_handler, netsnmp_get_cache_handler(snmp_cache_time_out, LHANodeTable_load, LHANodeTable_free, LHANodeTable_oid, OID_LENGTH(LHANodeTable_oid))); }
/** Initialize the hrSWInstalledTable table by defining its contents and how it's structured */ void initialize_table_hrSWInstalledTable(void) { static oid hrSWInstalledTable_oid[] = { 1, 3, 6, 1, 2, 1, 25, 6, 3 }; size_t hrSWInstalledTable_oid_len = OID_LENGTH(hrSWInstalledTable_oid); netsnmp_handler_registration *reg; netsnmp_mib_handler *handler = NULL; netsnmp_container *container = NULL; netsnmp_cache *cache = NULL; DEBUGMSGTL(("hrSWInstalled", "initialize\n")); reg = netsnmp_create_handler_registration("hrSWInstalledTable", hrSWInstalledTable_handler, hrSWInstalledTable_oid, hrSWInstalledTable_oid_len, HANDLER_CAN_RONLY); if (NULL == reg) { snmp_log(LOG_ERR,"error creating handler registration for " MYTABLE "\n"); goto bail; } container = netsnmp_container_find("hrSWInstalledTable:table_container"); if (NULL == container) { snmp_log(LOG_ERR,"error creating container for " MYTABLE "\n"); goto bail; } table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); if (NULL == table_info) { snmp_log(LOG_ERR,"error allocating table registration for " MYTABLE "\n"); goto bail; } netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, /* index: hrSWInstalledIndex */ 0); table_info->min_column = COLUMN_HRSWINSTALLEDINDEX; table_info->max_column = COLUMN_HRSWINSTALLEDDATE; /************************************************* * * inject container_table helper */ handler = netsnmp_container_table_handler_get(table_info, container, TABLE_CONTAINER_KEY_NETSNMP_INDEX); if (NULL == handler) { snmp_log(LOG_ERR,"error allocating table registration for " MYTABLE "\n"); goto bail; } if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) { snmp_log(LOG_ERR,"error injecting container_table handler for " MYTABLE "\n"); goto bail; } handler = NULL; /* reg has it, will reuse below */ /************************************************* * * inject cache helper */ cache = netsnmp_cache_create(30, /* timeout in seconds */ _cache_load, _cache_free, hrSWInstalledTable_oid, hrSWInstalledTable_oid_len); if (NULL == cache) { snmp_log(LOG_ERR, "error creating cache for " MYTABLE "\n"); goto bail; } cache->magic = container; handler = netsnmp_cache_handler_get(cache); if (NULL == handler) { snmp_log(LOG_ERR, "error creating cache handler for " MYTABLE "\n"); goto bail; } if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) { snmp_log(LOG_ERR,"error injecting cache handler for " MYTABLE "\n"); goto bail; } handler = NULL; /* reg has it*/ if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) { snmp_log(LOG_ERR,"error registering table handler for " MYTABLE "\n"); reg = NULL; /* it was freed inside netsnmp_register_table */ goto bail; } return; /* ok */ bail: /* not ok */ if (handler) netsnmp_handler_free(handler); if (cache) netsnmp_cache_free(cache); if (table_info) netsnmp_table_registration_info_free(table_info); if (container) CONTAINER_FREE(container); if (reg) netsnmp_handler_registration_free(reg); }
void netsnmp_parse_override(const char *token, char *line) { char *cp; char buf[SNMP_MAXBUF], namebuf[SNMP_MAXBUF]; int readwrite = 0; oid oidbuf[MAX_OID_LEN]; size_t oidbuf_len = MAX_OID_LEN; int type; override_data *thedata; netsnmp_handler_registration *the_reg; cp = copy_nword(line, namebuf, sizeof(namebuf) - 1); if (strcmp(namebuf, "-rw") == 0) { readwrite = 1; cp = copy_nword(cp, namebuf, sizeof(namebuf) - 1); } if (!cp) { config_perror("no oid specified"); return; } if (!snmp_parse_oid(namebuf, oidbuf, &oidbuf_len)) { config_perror("illegal oid"); return; } cp = copy_nword(cp, buf, sizeof(buf) - 1); if (!cp && strcmp(buf, "null") != 0) { config_perror("no variable value specified"); return; } { struct { const char* key; int value; } const strings[] = { { "counter", ASN_COUNTER }, { "counter64", ASN_COUNTER64 }, { "integer", ASN_INTEGER }, { "ipaddress", ASN_IPADDRESS }, { "nsap", ASN_NSAP }, { "null", ASN_NULL }, { "object_id", ASN_OBJECT_ID }, { "octet_str", ASN_OCTET_STR }, { "opaque", ASN_OPAQUE }, #ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES { "opaque_counter64", ASN_OPAQUE_COUNTER64 }, { "opaque_double", ASN_OPAQUE_DOUBLE }, { "opaque_float", ASN_OPAQUE_FLOAT }, { "opaque_i64", ASN_OPAQUE_I64 }, { "opaque_u64", ASN_OPAQUE_U64 }, #endif { "timeticks", ASN_TIMETICKS }, { "uinteger", ASN_GAUGE }, { "unsigned", ASN_UNSIGNED }, { NULL, 0 } }, * run; for(run = strings; run->key && strcasecmp(run->key, buf) < 0; ++run); if(run->key && strcasecmp(run->key, buf) == 0) type = run->value; else { config_perror("unknown type specified"); return; } } if (cp) copy_nword(cp, buf, sizeof(buf) - 1); else buf[0] = 0; thedata = SNMP_MALLOC_TYPEDEF(override_data); if (!thedata) { config_perror("memory allocation failure"); return; } thedata->type = type; switch (type) { case ASN_INTEGER: MALLOC_OR_DIE(sizeof(long)); *((long *) thedata->value) = strtol(buf, NULL, 0); break; case ASN_COUNTER: case ASN_TIMETICKS: case ASN_UNSIGNED: MALLOC_OR_DIE(sizeof(u_long)); *((u_long *) thedata->value) = strtoul(buf, NULL, 0); break; case ASN_OCTET_STR: case ASN_BIT_STR: if (buf[0] == '0' && buf[1] == 'x') { /* * hex */ thedata->value_len = hex_to_binary2((u_char *)(buf + 2), strlen(buf) - 2, (char **) &thedata->value); } else { thedata->value = strdup(buf); thedata->value_len = strlen(buf); } break; case ASN_OBJECT_ID: read_config_read_objid(buf, (oid **) & thedata->value, &thedata->value_len); break; case ASN_NULL: thedata->value_len = 0; break; default: SNMP_FREE(thedata); config_perror("illegal/unsupported type specified"); return; } if (!thedata->value && thedata->type != ASN_NULL) { config_perror("memory allocation failure"); free(thedata); return; } the_reg = SNMP_MALLOC_TYPEDEF(netsnmp_handler_registration); if (!the_reg) { config_perror("memory allocation failure"); free(thedata); return; } the_reg->handlerName = strdup(namebuf); the_reg->priority = 255; the_reg->modes = (readwrite) ? HANDLER_CAN_RWRITE : HANDLER_CAN_RONLY; the_reg->handler = netsnmp_create_handler("override", override_handler); the_reg->rootoid = snmp_duplicate_objid(oidbuf, oidbuf_len); the_reg->rootoid_len = oidbuf_len; if (!the_reg->rootoid || !the_reg->handler || !the_reg->handlerName) { if (the_reg->handler) SNMP_FREE(the_reg->handler->handler_name); SNMP_FREE(the_reg->handler); SNMP_FREE(the_reg->handlerName); SNMP_FREE(the_reg); config_perror("memory allocation failure"); free(thedata); return; } the_reg->handler->myvoid = thedata; if (netsnmp_register_instance(the_reg)) { config_perror("oid registration failed within the agent"); SNMP_FREE(thedata->value); free(thedata); return; } }
void init_tcpTable(void) { const oid tcpTable_oid[] = { SNMP_OID_MIB2, 6, 13 }; netsnmp_table_registration_info *table_info; netsnmp_iterator_info *iinfo; netsnmp_handler_registration *reginfo; int rc; DEBUGMSGTL(("mibII/tcpTable", "Initialising TCP Table\n")); /* * Create the table data structure, and define the indexing.... */ table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); if (!table_info) { return; } netsnmp_table_helper_add_indexes(table_info, ASN_IPADDRESS, ASN_INTEGER, ASN_IPADDRESS, ASN_INTEGER, 0); table_info->min_column = TCPCONNSTATE; table_info->max_column = TCPCONNREMOTEPORT; /* * .... and iteration information .... */ iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); if (!iinfo) { return; } iinfo->get_first_data_point = tcpTable_first_entry; iinfo->get_next_data_point = tcpTable_next_entry; iinfo->table_reginfo = table_info; #if defined (WIN32) || defined (cygwin) iinfo->flags |= NETSNMP_ITERATOR_FLAG_SORTED; #endif /* WIN32 || cygwin */ /* * .... and register the table with the agent. */ reginfo = netsnmp_create_handler_registration("tcpTable", tcpTable_handler, tcpTable_oid, OID_LENGTH(tcpTable_oid), HANDLER_CAN_RONLY), rc = netsnmp_register_table_iterator2(reginfo, iinfo); if (rc != SNMPERR_SUCCESS) return; /* * .... with a local cache * (except for Solaris, which uses a different approach) */ netsnmp_inject_handler( reginfo, netsnmp_get_cache_handler(TCP_STATS_CACHE_TIMEOUT, tcpTable_load, tcpTable_free, tcpTable_oid, OID_LENGTH(tcpTable_oid))); }
/** implements the table data helper. This is the routine that takes * care of all SNMP requests coming into the table. */ int netsnmp_table_data_set_helper_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_table_data_set_storage *data = NULL; newrow_stash *newrowstash = NULL; netsnmp_table_row *row, *newrow = NULL; netsnmp_table_request_info *table_info; netsnmp_request_info *request; oid *suffix; size_t suffix_len; netsnmp_oid_stash_node **stashp = NULL; if (!handler) return SNMPERR_GENERR; DEBUGMSGTL(("netsnmp_table_data_set", "handler starting\n")); for (request = requests; request; request = request->next) { netsnmp_table_data_set *datatable = (netsnmp_table_data_set *) handler->myvoid; if (request->processed) continue; /* * extract our stored data and table info */ row = netsnmp_extract_table_row(request); table_info = netsnmp_extract_table_info(request); suffix = requests->requestvb->name + reginfo->rootoid_len + 2; suffix_len = requests->requestvb->name_length - (reginfo->rootoid_len + 2); if (MODE_IS_SET(reqinfo->mode)) { char buf[256]; /* is this reasonable size?? */ int rc; size_t len; /* * use a cached copy of the row for modification */ /* * cache location: may have been created already by other * SET requests in the same master request. */ rc = snprintf(buf, sizeof(buf), "dataset_row_stash:%s:", datatable->table->name); if ((-1 == rc) || (rc >= sizeof(buf))) { snmp_log(LOG_ERR,"%s handler name too long\n", datatable->table->name); netsnmp_set_request_error(reqinfo, request, SNMP_ERR_GENERR); continue; } len = sizeof(buf) - rc; rc = snprint_objid(&buf[rc], len, table_info->index_oid, table_info->index_oid_len); if (-1 == rc) { snmp_log(LOG_ERR,"%s oid or name too long\n", datatable->table->name); netsnmp_set_request_error(reqinfo, request, SNMP_ERR_GENERR); continue; } stashp = (netsnmp_oid_stash_node **) netsnmp_table_get_or_create_row_stash(reqinfo, buf); newrowstash = netsnmp_oid_stash_get_data(*stashp, suffix, suffix_len); if (!newrowstash) { if (!row) { if (datatable->allow_creation) { /* * entirely new row. Create the row from the template */ newrowstash = netsnmp_table_data_set_create_newrowstash( datatable, table_info); newrow = newrowstash->newrow; } else if (datatable->rowstatus_column == 0) { /* * A RowStatus object may be used to control the * creation of a new row. But if this object * isn't declared (and the table isn't marked as * 'auto-create'), then we can't create a new row. */ netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOCREATION); continue; } } else { /* * existing row that needs to be modified */ newrowstash = SNMP_MALLOC_TYPEDEF(newrow_stash); newrow = netsnmp_table_data_set_clone_row(row); newrowstash->newrow = newrow; } netsnmp_oid_stash_add_data(stashp, suffix, suffix_len, newrowstash); } else { newrow = newrowstash->newrow; } /* * all future SET data modification operations use this * temp pointer */ if (reqinfo->mode == MODE_SET_RESERVE1 || reqinfo->mode == MODE_SET_RESERVE2) row = newrow; } if (row) data = (netsnmp_table_data_set_storage *) row->data; if (!row || !table_info || !data) { if (!MODE_IS_SET(reqinfo->mode)) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } } data = netsnmp_table_data_set_find_column(data, table_info->colnum); switch (reqinfo->mode) { case MODE_GET: case MODE_GETNEXT: case MODE_GETBULK: /* XXXWWW */ if (data && data->data.voidp) netsnmp_table_data_build_result(reginfo, reqinfo, request, row, table_info->colnum, data->type, data->data.voidp, data->data_len); break; case MODE_SET_RESERVE1: if (data) { /* * Can we modify the existing row? */ if (!data->writable) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOTWRITABLE); } else if (request->requestvb->type != data->type) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE); } } else if (datatable->rowstatus_column == table_info->colnum) { /* * Otherwise, this is where we create a new row using * the RowStatus object (essentially duplicating the * steps followed earlier in the 'allow_creation' case) */ switch (*(request->requestvb->val.integer)) { case RS_CREATEANDGO: case RS_CREATEANDWAIT: newrowstash = netsnmp_table_data_set_create_newrowstash( datatable, table_info); newrow = newrowstash->newrow; row = newrow; netsnmp_oid_stash_add_data(stashp, suffix, suffix_len, newrowstash); } } break; case MODE_SET_RESERVE2: /* * If the agent receives a SET request for an object in a non-existant * row, then the RESERVE1 pass will create the row automatically. * * But since the row doesn't exist at that point, the test for whether * the object is writable or not will be skipped. So we need to check * for this possibility again here. * * Similarly, if row creation is under the control of the RowStatus * object (i.e. allow_creation == 0), but this particular request * doesn't include such an object, then the row won't have been created, * and the writable check will also have been skipped. Again - check here. */ if (data && data->writable == 0) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOTWRITABLE); continue; } if (datatable->rowstatus_column == table_info->colnum) { switch (*(request->requestvb->val.integer)) { case RS_ACTIVE: case RS_NOTINSERVICE: /* * Can only operate on pre-existing rows. */ if (!newrowstash || newrowstash->created) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_INCONSISTENTVALUE); continue; } break; case RS_CREATEANDGO: case RS_CREATEANDWAIT: /* * Can only operate on newly created rows. */ if (!(newrowstash && newrowstash->created)) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_INCONSISTENTVALUE); continue; } break; case RS_DESTROY: /* * Can operate on new or pre-existing rows. */ break; case RS_NOTREADY: default: /* * Not a valid value to Set */ netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE); continue; } } if (!data ) { netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOCREATION); continue; } /* * modify row and set new value */ SNMP_FREE(data->data.string); data->data.string = netsnmp_strdup_and_null(request->requestvb->val.string, request->requestvb->val_len); if (!data->data.string) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_RESOURCEUNAVAILABLE); } data->data_len = request->requestvb->val_len; if (datatable->rowstatus_column == table_info->colnum) { switch (*(request->requestvb->val.integer)) { case RS_CREATEANDGO: /* * XXX: check legality */ *(data->data.integer) = RS_ACTIVE; break; case RS_CREATEANDWAIT: /* * XXX: check legality */ *(data->data.integer) = RS_NOTINSERVICE; break; case RS_DESTROY: newrowstash->deleted = 1; break; } } break; case MODE_SET_ACTION: /* * Install the new row into the stored table. * Do this only *once* per row .... */ if (newrowstash->state != STATE_ACTION) { newrowstash->state = STATE_ACTION; if (newrowstash->created) { netsnmp_table_dataset_add_row(datatable, newrow); } else { netsnmp_table_dataset_replace_row(datatable, row, newrow); } } /* * ... but every (relevant) varbind in the request will * need to know about this new row, so update the * per-request row information regardless */ if (newrowstash->created) { netsnmp_request_add_list_data(request, netsnmp_create_data_list(TABLE_DATA_NAME, newrow, NULL)); } break; case MODE_SET_UNDO: /* * extract the new row, replace with the old or delete */ if (newrowstash->state != STATE_UNDO) { newrowstash->state = STATE_UNDO; if (newrowstash->created) { netsnmp_table_dataset_remove_and_delete_row(datatable, newrow); } else { netsnmp_table_dataset_replace_row(datatable, newrow, row); netsnmp_table_dataset_delete_row(newrow); } } break; case MODE_SET_COMMIT: if (newrowstash->state != STATE_COMMIT) { newrowstash->state = STATE_COMMIT; if (!newrowstash->created) { netsnmp_table_dataset_delete_row(row); } if (newrowstash->deleted) { netsnmp_table_dataset_remove_and_delete_row(datatable, newrow); } } break; case MODE_SET_FREE: if (newrowstash && newrowstash->state != STATE_FREE) { newrowstash->state = STATE_FREE; netsnmp_table_dataset_delete_row(newrow); } break; } } /* next handler called automatically - 'AUTO_NEXT' */ return SNMP_ERR_NOERROR; }
/* * Initialize the openserSIPStatusCodesTable table by defining how it is * structured. * * This function is mostly auto-generated. */ void initialize_table_openserSIPStatusCodesTable(void) { netsnmp_table_registration_info *table_info; if(my_handler) { snmp_log(LOG_ERR, "initialize_table_openserSIPStatusCodes" "Table_handler called again\n"); return; } memset(&cb, 0x00, sizeof(cb)); /** create the table structure itself */ table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); my_handler = netsnmp_create_handler_registration( "openserSIPStatusCodesTable", netsnmp_table_array_helper_handler, openserSIPStatusCodesTable_oid, openserSIPStatusCodesTable_oid_len, HANDLER_CAN_RWRITE); if (!my_handler || !table_info) { snmp_log(LOG_ERR, "malloc failed in initialize_table_openserSIP" "StatusCodesTable_handler\n"); return; /** mallocs failed */ } /** index: openserSIPStatusCodeMethod */ netsnmp_table_helper_add_index(table_info, ASN_UNSIGNED); /** index: openserSIPStatusCodeValue */ netsnmp_table_helper_add_index(table_info, ASN_UNSIGNED); table_info->min_column = openserSIPStatusCodesTable_COL_MIN; table_info->max_column = openserSIPStatusCodesTable_COL_MAX; /*************************************************** * registering the table with the master agent */ cb.get_value = openserSIPStatusCodesTable_get_value; cb.container = netsnmp_container_find("openserSIPStatusCodesTable_primary:" "openserSIPStatusCodesTable:" "table_container"); #ifdef openserSIPStatusCodesTable_CUSTOM_SORT netsnmp_container_add_index(cb.container, netsnmp_container_find( "openserSIPStatusCodesTable_custom:" "openserSIPStatusCodesTable:" "table_container")); cb.container->next->compare = openserSIPStatusCodesTable_cmp; #endif cb.can_set = 1; cb.create_row = (UserRowMethod*)openserSIPStatusCodesTable_create_row; cb.duplicate_row = (UserRowMethod*)openserSIPStatusCodesTable_duplicate_row; cb.delete_row = (UserRowMethod*)openserSIPStatusCodesTable_delete_row; cb.row_copy = (Netsnmp_User_Row_Operation *) openserSIPStatusCodesTable_row_copy; cb.can_activate = (Netsnmp_User_Row_Action *) openserSIPStatusCodesTable_can_activate; cb.can_deactivate = (Netsnmp_User_Row_Action *) openserSIPStatusCodesTable_can_deactivate; cb.can_delete = (Netsnmp_User_Row_Action *)openserSIPStatusCodesTable_can_delete; cb.set_reserve1 = openserSIPStatusCodesTable_set_reserve1; cb.set_reserve2 = openserSIPStatusCodesTable_set_reserve2; cb.set_action = openserSIPStatusCodesTable_set_action; cb.set_commit = openserSIPStatusCodesTable_set_commit; cb.set_free = openserSIPStatusCodesTable_set_free; cb.set_undo = openserSIPStatusCodesTable_set_undo; DEBUGMSGTL(("initialize_table_openserSIPStatusCodesTable", "Registering table openserSIPStatusCodesTable " "as a table array\n")); netsnmp_table_container_register(my_handler, table_info, &cb, cb.container, 1); }
/* General initialization */ void init_custom_queries(void) { netsnmp_table_registration_info *table_info; pgsnmpd_query *curquery; int i; PGresult *res; if (custom_query_config_file == NULL) return; /* ASN_INTEGER = 0 ASN_FLOAT = 1 ASN_BOOLEAN = 2 ASN_OCTET_STR = 3 */ res = PQprepare(dbconn, "TYPEQUERY", "SELECT CASE " "WHEN typname LIKE 'int%' OR typname = 'xid' OR typname = 'oid'" "THEN 0 " "WHEN typname LIKE 'float%' THEN 1 " "WHEN typname = 'bool' THEN 2 " "ELSE 3 " "END " "FROM pg_catalog.pg_type WHERE oid = $1", 1, NULL); if (PQresultStatus(res) != PGRES_COMMAND_OK) { snmp_log(LOG_ERR, "Failed to prepare statement (error: %s)\n", PQresStatus(PQresultStatus(res))); return; } PQclear(res); head = parse_config(custom_query_config_file); if (head == NULL) { snmp_log(LOG_INFO, "No custom queries initialized\n"); return; } for (curquery = head; curquery != NULL; curquery = curquery->next) { run_query(curquery); if (curquery->typeslen < curquery->colcount) curquery->types = realloc(curquery->types, sizeof(u_char) * curquery->colcount); if (curquery->types == NULL) { snmp_log(LOG_ERR, "Memory allocation problem"); return; } init_types_array(curquery->types, curquery->typeslen, curquery->colcount); fill_query_column_types(curquery); if (curquery->my_handler) { snmp_log(LOG_ERR, "init_custom_queries called again for query %s\n", curquery->table_name); return; } memset(&(curquery->cb), 0x00, sizeof(curquery->cb)); /** create the table structure itself */ snmp_log(LOG_INFO, "Initializing table name %s\n", curquery->table_name); table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); curquery->my_handler = netsnmp_create_handler_registration( curquery->table_name, netsnmp_table_array_helper_handler, curquery->table_oid, curquery->oid_len, HANDLER_CAN_RONLY ); if (!curquery->my_handler || !table_info) { snmp_log(LOG_ERR, "malloc failed in init_custom_queries\n"); return; /** mallocs failed */ } netsnmp_table_helper_add_index(table_info, ASN_INTEGER); /* pgsnmpdConnID */ netsnmp_table_helper_add_index(table_info, ASN_INTEGER); /* rdbmsDbIndex */ for (i = 0; i < curquery->num_indexes; i++) netsnmp_table_helper_add_index(table_info, curquery->types[i]); table_info->min_column = curquery->min_colnum; table_info->max_column = curquery->colcount; curquery->cb.get_value = custom_query_get_value; curquery->cb.container = netsnmp_container_find("table_container"); DEBUGMSGTL(("init_custom_queries", "Registering table for query " "as a table array\n")); switch (netsnmp_table_container_register(curquery->my_handler, table_info, &curquery->cb, curquery->cb.container, 1)) { case MIB_REGISTRATION_FAILED: snmp_log(LOG_INFO, "Failed to register table %s\n", curquery->table_name); break; case MIB_DUPLICATE_REGISTRATION: snmp_log(LOG_INFO, "Duplicate registration for table %s\n", curquery->table_name); break; case MIB_REGISTERED_OK: DEBUGMSGTL(("init_custom_queries", "Successfully registered table %s\n", curquery->table_name)); break; default: snmp_log(LOG_INFO, "Unknown registration result for table %s\n", curquery->table_name); } /* Having set everything up, fill the table's container with data */ fill_query_container(curquery); } snmp_log(LOG_DEBUG, "Finished intializing queries\n"); }
netsnmp_transport * netsnmp_std_transport(const char *instring, size_t instring_len, const char *default_target) { netsnmp_transport *t; t = (netsnmp_transport *) malloc(sizeof(netsnmp_transport)); if (t == NULL) { return NULL; } memset(t, 0, sizeof(netsnmp_transport)); t->domain = netsnmp_snmpSTDDomain; t->domain_length = sizeof(netsnmp_snmpSTDDomain) / sizeof(netsnmp_snmpSTDDomain[0]); t->sock = 0; t->flags = NETSNMP_TRANSPORT_FLAG_STREAM | NETSNMP_TRANSPORT_FLAG_TUNNELED; /* * Message size is not limited by this transport (hence msgMaxSize * is equal to the maximum legal size of an SNMP message). */ t->msgMaxSize = 0x7fffffff; t->f_recv = netsnmp_std_recv; t->f_send = netsnmp_std_send; t->f_close = netsnmp_std_close; t->f_accept = netsnmp_std_accept; t->f_fmtaddr = netsnmp_std_fmtaddr; /* * if instring is not null length, it specifies a path to a prog * XXX: plus args */ if (instring_len == 0 && default_target != NULL) { instring = default_target; instring_len = strlen(default_target); } if (instring_len != 0) { int infd[2], outfd[2]; /* sockets to and from the client */ int childpid; if (pipe(infd) || pipe(outfd)) { snmp_log(LOG_ERR, "Failed to create needed pipes for a STD transport"); netsnmp_transport_free(t); return NULL; } childpid = fork(); /* parentpid => childpid */ /* infd[1] => infd[0] */ /* outfd[0] <= outfd[1] */ if (childpid) { netsnmp_std_data *data; /* we're in the parent */ close(infd[0]); close(outfd[1]); data = SNMP_MALLOC_TYPEDEF(netsnmp_std_data); if (!data) { snmp_log(LOG_ERR, "snmpSTDDomain: memdup failed"); netsnmp_transport_free(t); return NULL; } t->data = data; t->data_length = sizeof(netsnmp_std_data); t->sock = outfd[0]; data->prog = strdup(instring); data->outfd = infd[1]; data->childpid = childpid; DEBUGMSGTL(("domain:std","parent. data=%x\n", t->data)); } else { /* we're in the child */ /* close stdin */ close(0); /* copy pipe output to stdout */ dup(infd[0]); /* close stdout */ close(1); /* copy pipe output to stdin */ dup(outfd[1]); /* close all the pipes themselves */ close(infd[0]); close(infd[1]); close(outfd[0]); close(outfd[1]); /* call exec */ system(instring); /* XXX: TODO: use exec form instead; needs args */ /* execv(instring, NULL); */ exit(0); /* ack... we should never ever get here */ snmp_log(LOG_ERR, "STD transport returned after execv()\n"); } } return t; }
void fill_query_container(pgsnmpd_query *query) { /* TODO: Make this work */ cust_query_row *row; int i, j, string_idx_count, string_idx_len; netsnmp_variable_list var_rdbmsDbIndex, var_pgsnmpdConnID, *var_otherIndexes; int err = SNMP_ERR_NOERROR; char *val; memset( &var_pgsnmpdConnID, 0x00, sizeof(var_pgsnmpdConnID) ); var_pgsnmpdConnID.type = ASN_INTEGER; memset( &var_rdbmsDbIndex, 0x00, sizeof(var_rdbmsDbIndex) ); var_rdbmsDbIndex.type = ASN_INTEGER; var_otherIndexes = malloc(sizeof(netsnmp_variable_list) * query->num_indexes); if (var_otherIndexes == NULL) { snmp_log(LOG_ERR, "Memory allocation error\n"); return; } memset(var_otherIndexes, 0, sizeof(netsnmp_variable_list) * query->num_indexes); string_idx_count = 0; for (i = 0; i < query->num_indexes; i++) { if (i < query->num_indexes - 1) var_otherIndexes[i].next_variable = &var_otherIndexes[i+1]; var_otherIndexes[i].type = query->types[i]; if (query->types[i] == ASN_OCTET_STR) string_idx_count++; } var_pgsnmpdConnID.next_variable = &var_rdbmsDbIndex; var_rdbmsDbIndex.next_variable = var_otherIndexes; snmp_set_var_typed_value(&var_rdbmsDbIndex, ASN_INTEGER, (u_char *) &rdbmsDbIndex, sizeof(int)); snmp_set_var_typed_value(&var_pgsnmpdConnID, ASN_INTEGER, (u_char *) &pgsnmpdConnID, sizeof(int)); for (i = 0; i < query->rowcount; i++) { string_idx_len = 0; for (j = 0; j < query->num_indexes; j++) { val = PQgetvalue(query->result, i, j); /* TODO: Floats and OIDs also need more than the usual memory. * Learn to handle them. Until then we can expect problems using * OIDs and Floats as indexes */ if (query->types[j] == ASN_OCTET_STR) string_idx_len += strlen(val); set_val_from_string(&var_otherIndexes[j], query->types[j], val); } row = SNMP_MALLOC_TYPEDEF(cust_query_row); row->myoids = malloc(sizeof(oid) * (query->num_indexes + extra_idx_count + string_idx_count + string_idx_len)); if (row->myoids == NULL) { snmp_log(LOG_ERR, "memory allocation problem \n"); return; } row->row_index.len = query->num_indexes + extra_idx_count + string_idx_len + string_idx_count; row->row_index.oids = row->myoids; err = build_oid_noalloc(row->row_index.oids, row->row_index.len, (size_t *) &(row->row_index.len), NULL, 0, &var_pgsnmpdConnID); if (err) snmp_log(LOG_ERR,"error %d converting index to oid, query %s\n", err, query->table_name); row->query = query; row->rownum = i; CONTAINER_INSERT(query->cb.container, row); } }
/* * Gather the data necessary for evaluating an expression. * * This will retrieve *all* the data relevant for all * instances of this expression, rather than just the * just the values needed for expanding a given instance. */ void expExpression_getData( unsigned int reg, void *clientarg ) { struct expExpression *entry = (struct expExpression *)clientarg; netsnmp_tdata_row *row; netsnmp_variable_list *var; int ret; if ( !entry && reg ) { snmp_alarm_unregister( reg ); return; } if (( entry->expExpression[0] == '\0' ) || !(entry->flags & EXP_FLAG_ACTIVE) || !(entry->flags & EXP_FLAG_VALID)) return; DEBUGMSGTL(("disman:expr:run", "Gathering expression data (%s, %s)\n", entry->expOwner, entry->expName)); /* * This routine can be called in two situations: * - regularly by 'snmp_alarm' (reg != 0) * (as part of ongoing delta-value sampling) * - on-demand (reg == 0) * (for evaluating a particular entry) * * If a regularly sampled expression (entry->alarm != 0) * is invoked on-demand (reg == 0), then use the most * recent sampled values, rather than retrieving them again. */ if ( !reg && entry->alarm ) return; /* * XXX - may want to implement caching for on-demand evaluation * of non-regularly sampled expressions. */ /* * For a wildcarded expression, expExpressionPrefix is used * to determine which object instances to retrieve. * (For a non-wildcarded expression, we already know * explicitly which object instances will be needed). * * If we walk this object here, then the results can be * used to build the necessary GET requests for each * individual parameter object (within expObject_getData) * * This will probably be simpler (and definitely more efficient) * than walking the object instances separately and merging * merging the results). * * NB: Releasing any old results is handled by expObject_getData. * Assigning to 'entry->pvars' without first releasing the * previous contents does *not* introduce a memory leak. */ if ( entry->expPrefix_len ) { var = (netsnmp_variable_list *) SNMP_MALLOC_TYPEDEF( netsnmp_variable_list ); snmp_set_var_objid( var, entry->expPrefix, entry->expPrefix_len); ret = netsnmp_query_walk( var, entry->session ); DEBUGMSGTL(("disman:expr:run", "Walk returned %d\n", ret )); entry->pvars = var; } /* XXX - retrieve sysUpTime.0 value, and check for discontinuity */ /* entry->flags &= ~EXP_FLAG_SYSUT; var = (netsnmp_variable_list *) SNMP_MALLOC_TYPEDEF( netsnmp_variable_list ); snmp_set_var_objid( var, sysUT_oid, sysUT_oid_len ); netsnmp_query_get( var, entry->session ); if ( *var->val.integer != entry->sysUpTime ) { entry->flags |= EXP_FLAG_SYSUT; entry->sysUpTime = *var->val.integer; } snmp_free_varbind(var); */ /* * Loop through the list of relevant objects, * and retrieve the corresponding values. */ for ( row = expObject_getFirst( entry->expOwner, entry->expName ); row; row = expObject_getNext( row )) { /* XXX - may need to check whether owner/name still match */ expObject_getData( entry, (struct expObject *)row->data); } }
/* * Make a deep copy of an netsnmp_transport. */ netsnmp_transport * netsnmp_transport_copy(netsnmp_transport *t) { netsnmp_transport *n = NULL; if (t == NULL) { return NULL; } n = SNMP_MALLOC_TYPEDEF(netsnmp_transport); if (n == NULL) { return NULL; } if (t->domain != NULL) { n->domain = t->domain; n->domain_length = t->domain_length; } else { n->domain = NULL; n->domain_length = 0; } if (t->local != NULL) { n->local = (u_char *) malloc(t->local_length); if (n->local == NULL) { netsnmp_transport_free(n); return NULL; } n->local_length = t->local_length; memcpy(n->local, t->local, t->local_length); } else { n->local = NULL; n->local_length = 0; } if (t->remote != NULL) { n->remote = (u_char *) malloc(t->remote_length); if (n->remote == NULL) { netsnmp_transport_free(n); return NULL; } n->remote_length = t->remote_length; memcpy(n->remote, t->remote, t->remote_length); } else { n->remote = NULL; n->remote_length = 0; } if (t->data != NULL && t->data_length > 0) { n->data = malloc(t->data_length); if (n->data == NULL) { netsnmp_transport_free(n); return NULL; } n->data_length = t->data_length; memcpy(n->data, t->data, t->data_length); } else { n->data = NULL; n->data_length = 0; } n->msgMaxSize = t->msgMaxSize; n->f_accept = t->f_accept; n->f_recv = t->f_recv; n->f_send = t->f_send; n->f_close = t->f_close; n->f_copy = t->f_copy; n->f_config = t->f_config; n->f_fmtaddr = t->f_fmtaddr; n->sock = t->sock; n->flags = t->flags; n->base_transport = netsnmp_transport_copy(t->base_transport); /* give the transport a chance to do "special things" */ if (t->f_copy) t->f_copy(t, n); return n; }