int _mfd_ipv4InterfaceTable_get_values(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *agtreq_info, netsnmp_request_info *requests) { ipv4InterfaceTable_rowreq_ctx *rowreq_ctx = netsnmp_container_table_row_extract(requests); netsnmp_table_request_info *tri; u_char *old_string; void (*dataFreeHook) (void *); int rc; DEBUGMSGTL(("internal:ipv4InterfaceTable:_mfd_ipv4InterfaceTable_get_values", "called\n")); netsnmp_assert(NULL != rowreq_ctx); for (; requests; requests = requests->next) { /* * save old pointer, so we can free it if replaced */ old_string = requests->requestvb->val.string; dataFreeHook = requests->requestvb->dataFreeHook; if (NULL == requests->requestvb->val.string) { requests->requestvb->val.string = requests->requestvb->buf; requests->requestvb->val_len = sizeof(requests->requestvb->buf); } else if (requests->requestvb->buf == requests->requestvb->val.string) { if (requests->requestvb->val_len != sizeof(requests->requestvb->buf)) requests->requestvb->val_len = sizeof(requests->requestvb->buf); } /* * get column data */ tri = netsnmp_extract_table_info(requests); if (NULL == tri) continue; rc = _ipv4InterfaceTable_get_column(rowreq_ctx, requests->requestvb, tri->colnum); if (rc) { if (MFD_SKIP == rc) { requests->requestvb->type = SNMP_NOSUCHINSTANCE; rc = SNMP_ERR_NOERROR; } } else if (NULL == requests->requestvb->val.string) { snmp_log(LOG_ERR, "NULL varbind data pointer!\n"); rc = SNMP_ERR_GENERR; } if (rc) netsnmp_request_set_error(requests, SNMP_VALIDATE_ERR(rc)); /* * if the buffer wasn't used previously for the old data (i.e. it * was allcoated memory) and the get routine replaced the pointer, * we need to free the previous pointer. */ if (old_string && (old_string != requests->requestvb->buf) && (requests->requestvb->val.string != old_string)) { if (dataFreeHook) (*dataFreeHook) (old_string); else free(old_string); } } /* for results */ return SNMP_ERR_NOERROR; } /* _mfd_ipv4InterfaceTable_get_values */
/** * load initial data * * TODO:350:M: Implement cltproTable data load * This function will also be called by the cache helper to load * the container again (after the container free function has been * called to free the previous contents). * * @param container container to which items should be inserted * * @retval MFD_SUCCESS : success. * @retval MFD_RESOURCE_UNAVAILABLE : Can't access data source * @retval MFD_ERROR : other error. * * This function is called to load the index(es) (and data, optionally) * for the every row in the data set. * * @remark * While loading the data, the only important thing is the indexes. * If access to your data is cheap/fast (e.g. you have a pointer to a * structure in memory), it would make sense to update the data here. * If, however, the accessing the data invovles more work (e.g. parsing * some other existing data, or peforming calculations to derive the data), * then you can limit yourself to setting the indexes and saving any * information you will need later. Then use the saved information in * cltproTable_row_prep() for populating data. * * @note * If you need consistency between rows (like you want statistics * for each row to be from the same time frame), you should set all * data here. * */ int cltproTable_container_load(netsnmp_container *container) { cltproTable_rowreq_ctx *rowreq_ctx; long cltproTid; st_dbsCltConf row; DEBUGMSGTL(("verbose:cltproTable:cltproTable_container_load","called\n")); //printf("-->cltproTable_container_load()\n"); for( cltproTid=1; cltproTid<=MAX_CLT_AMOUNT_LIMIT; cltproTid++ ) { /* 从数据库获取数据*/ if( CMM_SUCCESS != dbsGetCltconf(dbsdev, cltproTid, &row) ) { dbs_sys_log(dbsdev, DBS_LOG_ERR, "cltproTable_container_load dbsGetCltconf failed"); return MFD_RESOURCE_UNAVAILABLE; } rowreq_ctx = cltproTable_allocate_rowreq_ctx(NULL); if (NULL == rowreq_ctx) { snmp_log(LOG_ERR, "memory allocation failed\n"); return MFD_RESOURCE_UNAVAILABLE; } if(MFD_SUCCESS != cltproTable_indexes_set(rowreq_ctx, cltproTid)) { snmp_log(LOG_ERR,"error setting index while loading " "cltproTable data.\n"); cltproTable_release_rowreq_ctx(rowreq_ctx); continue; } rowreq_ctx->data.cltproIndex = row.id; rowreq_ctx->data.cltproBase = row.col_base; rowreq_ctx->data.cltproMacLimit = row.col_macLimit; rowreq_ctx->data.cltproCuRate = row.col_curate; rowreq_ctx->data.cltproCdRate = row.col_cdrate; rowreq_ctx->data.cltproLoagTime = row.col_loagTime; rowreq_ctx->data.cltproReagTime = row.col_reagTime; rowreq_ctx->data.cltproIgmpPri = row.col_igmpPri; rowreq_ctx->data.cltproUnicastPri = row.col_unicastPri; rowreq_ctx->data.cltproAvsPri = row.col_avsPri; rowreq_ctx->data.cltproMcastPri = row.col_mcastPri; rowreq_ctx->data.cltproTbaPriSts = row.col_tbaPriSts?TRUTHVALUE_TRUE:TRUTHVALUE_FALSE; rowreq_ctx->data.cltproCosPriSts = row.col_cosPriSts?TRUTHVALUE_TRUE:TRUTHVALUE_FALSE; rowreq_ctx->data.cltproCos0pri = row.col_cos0pri; rowreq_ctx->data.cltproCos1pri = row.col_cos1pri; rowreq_ctx->data.cltproCos2pri = row.col_cos2pri; rowreq_ctx->data.cltproCos3pri = row.col_cos3pri; rowreq_ctx->data.cltproCos4pri = row.col_cos4pri; rowreq_ctx->data.cltproCos5pri = row.col_cos5pri; rowreq_ctx->data.cltproCos6pri = row.col_cos6pri; rowreq_ctx->data.cltproCos7pri = row.col_cos7pri; rowreq_ctx->data.cltproTosPriSts = row.col_tosPriSts?TRUTHVALUE_TRUE:TRUTHVALUE_FALSE; rowreq_ctx->data.cltproTos0pri = row.col_tos0pri; rowreq_ctx->data.cltproTos1pri = row.col_tos1pri; rowreq_ctx->data.cltproTos2pri = row.col_tos2pri; rowreq_ctx->data.cltproTos3pri = row.col_tos3pri; rowreq_ctx->data.cltproTos4pri = row.col_tos4pri; rowreq_ctx->data.cltproTos5pri = row.col_tos5pri; rowreq_ctx->data.cltproTos6pri = row.col_tos6pri; rowreq_ctx->data.cltproTos7pri = row.col_tos7pri; rowreq_ctx->data.cltproCommit = TRUTHVALUE_FALSE; rowreq_ctx->data.cltproRowStatus = row.col_row_sts?TRUTHVALUE_TRUE:TRUTHVALUE_FALSE; CONTAINER_INSERT(container, rowreq_ctx); } return MFD_SUCCESS; } /* cltproTable_container_load */
int netsnmp_instance_num_file_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_num_file_instance *nfi; u_long it; #ifndef NETSNMP_NO_WRITE_SUPPORT u_long *it_save; #endif /* NETSNMP_NO_WRITE_SUPPORT */ int rc; netsnmp_assert(NULL != handler); nfi = (netsnmp_num_file_instance *)handler->myvoid; netsnmp_assert(NULL != nfi); netsnmp_assert(NULL != nfi->file_name); DEBUGMSGTL(("netsnmp_instance_int_handler", "Got request: %d\n", reqinfo->mode)); switch (reqinfo->mode) { /* * data requests */ case MODE_GET: /* * Use a long here, otherwise on 64 bit use of an int would fail */ netsnmp_assert(NULL == nfi->filep); nfi->filep = fopen(nfi->file_name, "r"); if (NULL == nfi->filep) { netsnmp_set_request_error(reqinfo, requests, SNMP_NOSUCHINSTANCE); return SNMP_ERR_NOERROR; } rc = fscanf(nfi->filep, (nfi->type == ASN_INTEGER) ? "%ld" : "%lu", &it); fclose(nfi->filep); nfi->filep = NULL; if (rc != 1) { netsnmp_set_request_error(reqinfo, requests, SNMP_NOSUCHINSTANCE); return SNMP_ERR_NOERROR; } snmp_set_var_typed_value(requests->requestvb, nfi->type, (u_char *) &it, sizeof(it)); break; /* * SET requests. Should only get here if registered RWRITE */ #ifndef NETSNMP_NO_WRITE_SUPPORT case MODE_SET_RESERVE1: netsnmp_assert(NULL == nfi->filep); if (requests->requestvb->type != nfi->type) netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_WRONGTYPE); break; case MODE_SET_RESERVE2: netsnmp_assert(NULL == nfi->filep); nfi->filep = fopen(nfi->file_name, "w+"); if (NULL == nfi->filep) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_NOTWRITABLE); return SNMP_ERR_NOERROR; } /* * store old info for undo later */ if (fscanf(nfi->filep, (nfi->type == ASN_INTEGER) ? "%ld" : "%lu", &it) != 1) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_RESOURCEUNAVAILABLE); return SNMP_ERR_NOERROR; } it_save = netsnmp_memdup(&it, sizeof(u_long)); if (it_save == NULL) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_RESOURCEUNAVAILABLE); return SNMP_ERR_NOERROR; } netsnmp_request_add_list_data(requests, netsnmp_create_data_list (INSTANCE_HANDLER_NAME, it_save, &free_wrapper)); break; case MODE_SET_ACTION: /* * update current */ DEBUGMSGTL(("helper:instance", "updated %s -> %ld\n", nfi->file_name, *(requests->requestvb->val.integer))); it = *(requests->requestvb->val.integer); rewind(nfi->filep); /* rewind to make sure we are at the beginning */ rc = fprintf(nfi->filep, (nfi->type == ASN_INTEGER) ? "%ld" : "%lu", it); if (rc < 0) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR); return SNMP_ERR_NOERROR; } break; case MODE_SET_UNDO: it = *((u_int *) netsnmp_request_get_list_data(requests, INSTANCE_HANDLER_NAME)); rc = fprintf(nfi->filep, (nfi->type == ASN_INTEGER) ? "%ld" : "%lu", it); if (rc < 0) netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_UNDOFAILED); /* FALL THROUGH */ case MODE_SET_COMMIT: case MODE_SET_FREE: if (NULL != nfi->filep) { fclose(nfi->filep); nfi->filep = NULL; } break; #endif /* NETSNMP_NO_WRITE_SUPPORT */ default: snmp_log(LOG_ERR, "netsnmp_instance_num_file_handler: illegal mode\n"); netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR); return SNMP_ERR_NOERROR; } if (handler->next && handler->next->access_method) return netsnmp_call_next_handler(handler, reginfo, reqinfo, requests); return SNMP_ERR_NOERROR; }
/************************************************************ * * Initialize the saHpiSensorThdUpMinorTable table by defining its contents and how it's structured */ void initialize_table_saHpiSensorThdUpMinorTable(void) { netsnmp_table_registration_info *table_info; DEBUGMSGTL ((AGENT, "initialize_table_saHpiSensorThdUpMinorTable, called\n")); if (my_handler) { snmp_log(LOG_ERR, "initialize_table_saHpiSensorThdUpMinorTable_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("saHpiSensorThdUpMinorTable", netsnmp_table_array_helper_handler, saHpiSensorThdUpMinorTable_oid, saHpiSensorThdUpMinorTable_oid_len, HANDLER_CAN_RWRITE); if (!my_handler || !table_info) { snmp_log(LOG_ERR, "malloc failed in " "initialize_table_saHpiSensorThdUpMinorTable_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); /** index: saHpiSensorNum */ netsnmp_table_helper_add_index(table_info, ASN_UNSIGNED); table_info->min_column = saHpiSensorThdUpMinorTable_COL_MIN; table_info->max_column = saHpiSensorThdUpMinorTable_COL_MAX; /*************************************************** * registering the table with the master agent */ cb.get_value = saHpiSensorThdUpMinorTable_get_value; cb.container = netsnmp_container_find("saHpiSensorThdUpMinorTable_primary:" "saHpiSensorThdUpMinorTable:" "table_container"); netsnmp_container_add_index(cb.container, netsnmp_container_find("saHpiSensorThdUpMinorTable_secondary:" "saHpiSensorThdUpMinorTable:" "table_container")); cb.container->next->compare = saHpiSensorThdUpMinorTable_cmp; cb.can_set = 1; cb.create_row = (UserRowMethod*)saHpiSensorThdUpMinorTable_create_row; cb.duplicate_row = (UserRowMethod*)saHpiSensorThdUpMinorTable_duplicate_row; cb.delete_row = (UserRowMethod*)saHpiSensorThdUpMinorTable_delete_row; cb.row_copy = (Netsnmp_User_Row_Operation *)saHpiSensorThdUpMinorTable_row_copy; cb.can_activate = (Netsnmp_User_Row_Action *)saHpiSensorThdUpMinorTable_can_activate; cb.can_deactivate = (Netsnmp_User_Row_Action *)saHpiSensorThdUpMinorTable_can_deactivate; cb.can_delete = (Netsnmp_User_Row_Action *)saHpiSensorThdUpMinorTable_can_delete; cb.set_reserve1 = saHpiSensorThdUpMinorTable_set_reserve1; cb.set_reserve2 = saHpiSensorThdUpMinorTable_set_reserve2; cb.set_action = saHpiSensorThdUpMinorTable_set_action; cb.set_commit = saHpiSensorThdUpMinorTable_set_commit; cb.set_free = saHpiSensorThdUpMinorTable_set_free; cb.set_undo = saHpiSensorThdUpMinorTable_set_undo; DEBUGMSGTL(("initialize_table_saHpiSensorThdUpMinorTable", "Registering table saHpiSensorThdUpMinorTable " "as a table array\n")); netsnmp_table_container_register(my_handler, table_info, &cb, cb.container, 1); }
/* implements the table_iterator helper */ int netsnmp_table_iterator_helper_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_table_registration_info *tbl_info; netsnmp_table_request_info *table_info = NULL; oid coloid[MAX_OID_LEN]; size_t coloid_len; int ret = SNMP_ERR_NOERROR; static oid myname[MAX_OID_LEN]; size_t myname_len; int oldmode = 0; netsnmp_iterator_info *iinfo; int notdone; int hintok = 0; netsnmp_request_info *request, *reqtmp = NULL; netsnmp_variable_list *index_search = NULL; netsnmp_variable_list *free_this_index_search = NULL; void *callback_loop_context = NULL, *last_loop_context; void *callback_data_context = NULL; ti_cache_info *ti_info = NULL; int request_count = 0; netsnmp_oid_stash_node **cinfo = NULL; netsnmp_variable_list *old_indexes = NULL, *vb; netsnmp_table_registration_info *table_reg_info = NULL; int i; netsnmp_data_list *ldata = NULL; iinfo = (netsnmp_iterator_info *) handler->myvoid; if (!iinfo || !reginfo || !reqinfo) return SNMP_ERR_GENERR; tbl_info = iinfo->table_reginfo; /* * copy in the table registration oid for later use */ coloid_len = reginfo->rootoid_len + 2; memcpy(coloid, reginfo->rootoid, reginfo->rootoid_len * sizeof(oid)); coloid[reginfo->rootoid_len] = 1; /* table.entry node */ /* * illegally got here if these functions aren't defined */ if (iinfo->get_first_data_point == NULL || iinfo->get_next_data_point == NULL) { snmp_log(LOG_ERR, "table_iterator helper called without data accessor functions\n"); return SNMP_ERR_GENERR; } /* preliminary analysis */ switch (reqinfo->mode) { case MODE_GET_STASH: cinfo = netsnmp_extract_stash_cache(reqinfo); table_reg_info = netsnmp_find_table_registration_info(reginfo); /* XXX: move this malloc to stash_cache handler? */ reqtmp = SNMP_MALLOC_TYPEDEF(netsnmp_request_info); if (reqtmp == NULL) return SNMP_ERR_GENERR; reqtmp->subtree = requests->subtree; table_info = netsnmp_extract_table_info(requests); netsnmp_request_add_list_data(reqtmp, netsnmp_create_data_list (TABLE_HANDLER_NAME, (void *) table_info, NULL)); /* remember the indexes that were originally parsed. */ old_indexes = table_info->indexes; break; case MODE_GETNEXT: for(request = requests ; request; request = request->next) { if (request->processed) continue; table_info = netsnmp_extract_table_info(request); if (table_info == NULL) { /* * Cleanup */ if (free_this_index_search) snmp_free_varbind(free_this_index_search); return SNMP_ERR_GENERR; } if (table_info->colnum < tbl_info->min_column - 1) { /* XXX: optimize better than this */ /* for now, just increase to colnum-1 */ /* we need to jump to the lowest result of the min_column and take it, comparing to nothing from the request */ table_info->colnum = tbl_info->min_column - 1; } else if (table_info->colnum > tbl_info->max_column) { request->processed = TABLE_ITERATOR_NOTAGAIN; } ti_info = netsnmp_request_get_list_data(request, TI_REQUEST_CACHE); if (!ti_info) { ti_info = SNMP_MALLOC_TYPEDEF(ti_cache_info); if (ti_info == NULL) { /* * Cleanup */ if (free_this_index_search) snmp_free_varbind(free_this_index_search); return SNMP_ERR_GENERR; } netsnmp_request_add_list_data(request, netsnmp_create_data_list (TI_REQUEST_CACHE, ti_info, netsnmp_free_ti_cache)); } /* XXX: if no valid requests, don't even loop below */ } break; } /* * collect all information for each needed row */ if (reqinfo->mode == MODE_GET || reqinfo->mode == MODE_GETNEXT || reqinfo->mode == MODE_GET_STASH || reqinfo->mode == MODE_SET_RESERVE1) { /* * Count the number of request in the list, * so that we'll know when we're finished */ for(request = requests ; request; request = request->next) if (!request->processed) request_count++; notdone = 1; hintok = 1; while(notdone) { notdone = 0; /* find first data point */ if (!index_search) { if (free_this_index_search) { /* previously done */ index_search = free_this_index_search; } else { for(request=requests ; request; request=request->next) { table_info = netsnmp_extract_table_info(request); if (table_info) break; } if (!table_info) { snmp_log(LOG_WARNING, "no valid requests for iterator table %s\n", reginfo->handlerName); netsnmp_free_request_data_sets(reqtmp); SNMP_FREE(reqtmp); return SNMP_ERR_NOERROR; } index_search = snmp_clone_varbind(table_info->indexes); free_this_index_search = index_search; /* setup, malloc search data: */ if (!index_search) { /* * hmmm.... invalid table? */ snmp_log(LOG_WARNING, "invalid index list or failed malloc for table %s\n", reginfo->handlerName); netsnmp_free_request_data_sets(reqtmp); SNMP_FREE(reqtmp); return SNMP_ERR_NOERROR; } } } /* if sorted, pass in a hint */ if (hintok && (iinfo->flags & NETSNMP_ITERATOR_FLAG_SORTED)) { callback_loop_context = table_info; } index_search = (iinfo->get_first_data_point) (&callback_loop_context, &callback_data_context, index_search, iinfo); /* loop over each data point */ while(index_search) { /* remember to free this later */ free_this_index_search = index_search; /* compare against each request*/ for(request = requests ; request; request = request->next) { if (request->processed) continue; /* XXX: store in an array for faster retrival */ table_info = netsnmp_extract_table_info(request); if (table_info == NULL) { /* * Cleanup */ if (free_this_index_search) snmp_free_varbind(free_this_index_search); return SNMP_ERR_GENERR; } coloid[reginfo->rootoid_len + 1] = table_info->colnum; ti_info = netsnmp_request_get_list_data(request, TI_REQUEST_CACHE); switch(reqinfo->mode) { case MODE_GET: case MODE_SET_RESERVE1: /* looking for exact matches */ build_oid_noalloc(myname, MAX_OID_LEN, &myname_len, coloid, coloid_len, index_search); if (snmp_oid_compare(myname, myname_len, request->requestvb->name, request->requestvb->name_length) == 0) { /* * keep this */ if (netsnmp_iterator_remember(request, myname, myname_len, callback_data_context, callback_loop_context, iinfo) == NULL) { /* * Cleanup */ if (free_this_index_search) snmp_free_varbind (free_this_index_search); return SNMP_ERR_GENERR; } request_count--; /* One less to look for */ } else { if (iinfo->free_data_context && callback_data_context) { (iinfo->free_data_context)(callback_data_context, iinfo); } } break; case MODE_GET_STASH: /* collect data for each column for every row */ build_oid_noalloc(myname, MAX_OID_LEN, &myname_len, coloid, coloid_len, index_search); reqinfo->mode = MODE_GET; if (reqtmp) ldata = netsnmp_get_list_node(reqtmp->parent_data, TABLE_ITERATOR_NAME); if (!ldata) { netsnmp_request_add_list_data(reqtmp, netsnmp_create_data_list (TABLE_ITERATOR_NAME, callback_data_context, NULL)); } else { /* may have changed */ ldata->data = callback_data_context; } table_info->indexes = index_search; for(i = table_reg_info->min_column; i <= (int)table_reg_info->max_column; i++) { myname[reginfo->rootoid_len + 1] = i; table_info->colnum = i; vb = reqtmp->requestvb = SNMP_MALLOC_TYPEDEF(netsnmp_variable_list); if (vb == NULL) { /* * Cleanup */ if (free_this_index_search) snmp_free_varbind (free_this_index_search); return SNMP_ERR_GENERR; } vb->type = ASN_NULL; snmp_set_var_objid(vb, myname, myname_len); netsnmp_call_next_handler(handler, reginfo, reqinfo, reqtmp); reqtmp->requestvb = NULL; reqtmp->processed = 0; if (vb->type != ASN_NULL) { /* XXX, not all */ netsnmp_oid_stash_add_data(cinfo, myname, myname_len, vb); } else { snmp_free_var(vb); } } reqinfo->mode = MODE_GET_STASH; break; case MODE_GETNEXT: /* looking for "next" matches */ if (netsnmp_check_getnext_reply (request, coloid, coloid_len, index_search, &ti_info->results)) { if (netsnmp_iterator_remember(request, ti_info-> results->name, ti_info-> results-> name_length, callback_data_context, callback_loop_context, iinfo) == NULL) { /* * Cleanup */ if (free_this_index_search) snmp_free_varbind (free_this_index_search); return SNMP_ERR_GENERR; } /* * If we've been told that the rows are sorted, * then the first valid one we find * must be the right one. */ if (iinfo->flags & NETSNMP_ITERATOR_FLAG_SORTED) request_count--; } else { if (iinfo->free_data_context && callback_data_context) { (iinfo->free_data_context)(callback_data_context, iinfo); } } break; case MODE_SET_RESERVE2: case MODE_SET_FREE: case MODE_SET_UNDO: case MODE_SET_COMMIT: /* needed processing already done in RESERVE1 */ break; default: snmp_log(LOG_ERR, "table_iterator called with unsupported mode\n"); break; /* XXX return */ } } /* Is there any point in carrying on? */ if (!request_count) break; /* get the next search possibility */ last_loop_context = callback_loop_context; index_search = (iinfo->get_next_data_point) (&callback_loop_context, &callback_data_context, index_search, iinfo); if (iinfo->free_loop_context && last_loop_context && callback_data_context != last_loop_context) { (iinfo->free_loop_context) (last_loop_context, iinfo); last_loop_context = NULL; } } /* free loop context before going on */ if (callback_loop_context && iinfo->free_loop_context_at_end) { (iinfo->free_loop_context_at_end) (callback_loop_context, iinfo); callback_loop_context = NULL; } /* decide which (GETNEXT) requests are not yet filled */ if (reqinfo->mode == MODE_GETNEXT) { for(request = requests ; request; request = request->next) { if (request->processed) continue; ti_info = netsnmp_request_get_list_data(request, TI_REQUEST_CACHE); if (!ti_info->results) { int nc; table_info = netsnmp_extract_table_info(request); nc = netsnmp_table_next_column(table_info); if (0 == nc) { coloid[reginfo->rootoid_len+1] = table_info->colnum+1; snmp_set_var_objid(request->requestvb, coloid, reginfo->rootoid_len+2); request->processed = TABLE_ITERATOR_NOTAGAIN; break; } else { table_info->colnum = nc; hintok = 0; notdone = 1; } } } } } } if (reqinfo->mode == MODE_GET || reqinfo->mode == MODE_GETNEXT || reqinfo->mode == MODE_SET_RESERVE1) { /* per request last minute processing */ for(request = requests ; request; request = request->next) { if (request->processed) continue; ti_info = netsnmp_request_get_list_data(request, TI_REQUEST_CACHE); table_info = netsnmp_extract_table_info(request); if (!ti_info) continue; switch(reqinfo->mode) { case MODE_GETNEXT: if (ti_info->best_match_len) snmp_set_var_objid(request->requestvb, ti_info->best_match, ti_info->best_match_len); else { coloid[reginfo->rootoid_len+1] = netsnmp_table_next_column(table_info); if (0 == coloid[reginfo->rootoid_len+1]) { /* out of range. */ coloid[reginfo->rootoid_len+1] = tbl_info->max_column + 1; request->processed = TABLE_ITERATOR_NOTAGAIN; } snmp_set_var_objid(request->requestvb, coloid, reginfo->rootoid_len+2); request->processed = 1; } snmp_free_varbind(table_info->indexes); table_info->indexes = snmp_clone_varbind(ti_info->results); /* FALL THROUGH */ case MODE_GET: case MODE_SET_RESERVE1: if (ti_info->data_context) /* we don't add a free pointer, since it's in the TI_REQUEST_CACHE instead */ netsnmp_request_add_list_data(request, netsnmp_create_data_list (TABLE_ITERATOR_NAME, ti_info->data_context, NULL)); break; default: break; } } /* we change all GETNEXT operations into GET operations. why? because we're just so nice to the lower levels. maybe someday they'll pay us for it. doubtful though. */ oldmode = reqinfo->mode; if (reqinfo->mode == MODE_GETNEXT) { reqinfo->mode = MODE_GET; } } else if (reqinfo->mode == MODE_GET_STASH) { netsnmp_free_request_data_sets(reqtmp); SNMP_FREE(reqtmp); table_info->indexes = old_indexes; } /* Finally, we get to call the next handler below us. Boy, wasn't all that simple? They better be glad they don't have to do it! */ if (reqinfo->mode != MODE_GET_STASH) { DEBUGMSGTL(("table_iterator", "call subhandler for mode: %s\n", se_find_label_in_slist("agent_mode", oldmode))); ret = netsnmp_call_next_handler(handler, reginfo, reqinfo, requests); } /* reverse the previously saved mode if we were a getnext */ if (oldmode == MODE_GETNEXT) { reqinfo->mode = oldmode; } /* cleanup */ if (free_this_index_search) snmp_free_varbind(free_this_index_search); return ret; }
/************************************************************ * saHpiWatchdogTable_get_value * * This routine is called for get requests to copy the data * from the context to the varbind for the request. If the * context has been properly maintained, you don't need to * change in code in this fuction. */ int saHpiWatchdogTable_get_value( netsnmp_request_info *request, netsnmp_index *item, netsnmp_table_request_info *table_info ) { netsnmp_variable_list *var = request->requestvb; saHpiWatchdogTable_context *context = (saHpiWatchdogTable_context *)item; switch(table_info->colnum) { case COLUMN_SAHPIWATCHDOGNUM: /** SaHpiInstrumentId = ASN_UNSIGNED */ snmp_set_var_typed_value(var, ASN_UNSIGNED, (char*)&context->saHpiWatchdogNum, sizeof(context->saHpiWatchdogNum) ); break; case COLUMN_SAHPIWATCHDOGLOG: /** TruthValue = ASN_INTEGER */ snmp_set_var_typed_value(var, ASN_INTEGER, (char*)&context->saHpiWatchdogLog, sizeof(context->saHpiWatchdogLog) ); break; case COLUMN_SAHPIWATCHDOGRUNNING: /** TruthValue = ASN_INTEGER */ snmp_set_var_typed_value(var, ASN_INTEGER, (char*)&context->saHpiWatchdogRunning, sizeof(context->saHpiWatchdogRunning) ); break; case COLUMN_SAHPIWATCHDOGTIMERUSE: /** SaHpiWatchdogTimerUse = ASN_INTEGER */ snmp_set_var_typed_value(var, ASN_INTEGER, (char*)&context->saHpiWatchdogTimerUse, sizeof(context->saHpiWatchdogTimerUse) ); break; case COLUMN_SAHPIWATCHDOGTIMERACTION: /** INTEGER = ASN_INTEGER */ snmp_set_var_typed_value(var, ASN_INTEGER, (char*)&context->saHpiWatchdogTimerAction, sizeof(context->saHpiWatchdogTimerAction) ); break; case COLUMN_SAHPIWATCHDOGPRETIMERINTERRUPT: /** SaHpiWatchdogPreTimerAction = ASN_INTEGER */ snmp_set_var_typed_value(var, ASN_INTEGER, (char*)&context->saHpiWatchdogPretimerInterrupt, sizeof(context->saHpiWatchdogPretimerInterrupt) ); break; case COLUMN_SAHPIWATCHDOGPRETIMEOUTINTERVAL: /** UNSIGNED32 = ASN_UNSIGNED */ snmp_set_var_typed_value(var, ASN_UNSIGNED, (char*)&context->saHpiWatchdogPreTimeoutInterval, sizeof(context->saHpiWatchdogPreTimeoutInterval) ); break; case COLUMN_SAHPIWATCHDOGTIMERUSEEXPFLAGS: /** OCTETSTR = ASN_OCTET_STR */ snmp_set_var_typed_value(var, ASN_OCTET_STR, (char*)&context->saHpiWatchdogTimerUseExpFlags, context->saHpiWatchdogTimerUseExpFlags_len ); break; case COLUMN_SAHPIWATCHDOGTIMERINITIALCOUNT: /** UNSIGNED32 = ASN_UNSIGNED */ snmp_set_var_typed_value(var, ASN_UNSIGNED, (char*)&context->saHpiWatchdogTimerInitialCount, sizeof(context->saHpiWatchdogTimerInitialCount) ); break; case COLUMN_SAHPIWATCHDOGTIMERPRESENTCOUNT: /** UNSIGNED32 = ASN_UNSIGNED */ snmp_set_var_typed_value(var, ASN_UNSIGNED, (char*)&context->saHpiWatchdogTimerPresentCount, sizeof(context->saHpiWatchdogTimerPresentCount) ); break; case COLUMN_SAHPIWATCHDOGTIMERRESET: /** TruthValue = ASN_INTEGER */ snmp_set_var_typed_value(var, ASN_INTEGER, (char*)&context->saHpiWatchdogTimerReset, sizeof(context->saHpiWatchdogTimerReset) ); break; case COLUMN_SAHPIWATCHDOGOEM: /** UNSIGNED32 = ASN_UNSIGNED */ snmp_set_var_typed_value(var, ASN_UNSIGNED, (char*)&context->saHpiWatchdogOem, sizeof(context->saHpiWatchdogOem) ); break; case COLUMN_SAHPIWATCHDOGRDR: /** RowPointer = ASN_OBJECT_ID */ snmp_set_var_typed_value(var, ASN_OBJECT_ID, (char*)&context->saHpiWatchdogRDR, context->saHpiWatchdogRDR_len ); break; default: /** We shouldn't get here */ snmp_log(LOG_ERR, "unknown column in " "saHpiWatchdogTable_get_value\n"); return SNMP_ERR_GENERR; } return SNMP_ERR_NOERROR; }
/************************************************************ * RESERVE is used to check the syntax of all the variables * provided, that the values being set are sensible and consistent, * and to allocate any resources required for performing the SET. * After this stage, the expectation is that the set ought to * succeed, though this is not guaranteed. (In fact, with the UCD * agent, this is done in two passes - RESERVE1, and * RESERVE2, to allow for dependancies between variables). * * BEFORE calling this routine, the agent will call duplicate_row * to create a copy of the row (unless this is a new row; i.e. * row_created == 1). * * next state -> SET_RESERVE2 || SET_FREE */ void saHpiWatchdogTable_set_reserve1( netsnmp_request_group *rg ) { saHpiWatchdogTable_context *row_ctx = (saHpiWatchdogTable_context *)rg->existing_row; saHpiWatchdogTable_context *undo_ctx = (saHpiWatchdogTable_context *)rg->undo_info; netsnmp_variable_list *var; netsnmp_request_group_item *current; int rc; /* * TODO: loop through columns, check syntax and lengths. For * columns which have no dependencies, you could also move * the value/range checking here to attempt to catch error * cases as early as possible. */ for( current = rg->list; current; current = current->next ) { var = current->ri->requestvb; rc = SNMP_ERR_NOERROR; switch(current->tri->colnum) { case COLUMN_SAHPIWATCHDOGLOG: /** TruthValue = ASN_INTEGER */ rc = netsnmp_check_vb_type_and_size(var, ASN_INTEGER, sizeof(row_ctx->saHpiWatchdogLog)); break; case COLUMN_SAHPIWATCHDOGRUNNING: /** TruthValue = ASN_INTEGER */ rc = netsnmp_check_vb_type_and_size(var, ASN_INTEGER, sizeof(row_ctx->saHpiWatchdogRunning)); break; case COLUMN_SAHPIWATCHDOGTIMERUSE: /** SaHpiWatchdogTimerUse = ASN_INTEGER */ rc = netsnmp_check_vb_type_and_size(var, ASN_INTEGER, sizeof(row_ctx->saHpiWatchdogTimerUse)); break; case COLUMN_SAHPIWATCHDOGTIMERACTION: /** INTEGER = ASN_INTEGER */ rc = netsnmp_check_vb_type_and_size(var, ASN_INTEGER, sizeof(row_ctx->saHpiWatchdogTimerAction)); break; case COLUMN_SAHPIWATCHDOGPRETIMERINTERRUPT: /** SaHpiWatchdogPreTimerAction = ASN_INTEGER */ rc = netsnmp_check_vb_type_and_size(var, ASN_INTEGER, sizeof(row_ctx->saHpiWatchdogPretimerInterrupt)); break; case COLUMN_SAHPIWATCHDOGPRETIMEOUTINTERVAL: /** UNSIGNED32 = ASN_UNSIGNED */ rc = netsnmp_check_vb_type_and_size(var, ASN_UNSIGNED, sizeof(row_ctx->saHpiWatchdogPreTimeoutInterval)); break; case COLUMN_SAHPIWATCHDOGTIMERUSEEXPFLAGS: /** OCTETSTR = ASN_OCTET_STR */ rc = netsnmp_check_vb_type_and_size(var, ASN_OCTET_STR, sizeof(row_ctx->saHpiWatchdogTimerUseExpFlags)); break; case COLUMN_SAHPIWATCHDOGTIMERINITIALCOUNT: /** UNSIGNED32 = ASN_UNSIGNED */ rc = netsnmp_check_vb_type_and_size(var, ASN_UNSIGNED, sizeof(row_ctx->saHpiWatchdogTimerInitialCount)); break; case COLUMN_SAHPIWATCHDOGTIMERPRESENTCOUNT: /** UNSIGNED32 = ASN_UNSIGNED */ rc = netsnmp_check_vb_type_and_size(var, ASN_UNSIGNED, sizeof(row_ctx->saHpiWatchdogTimerPresentCount)); break; case COLUMN_SAHPIWATCHDOGTIMERRESET: /** TruthValue = ASN_INTEGER */ rc = netsnmp_check_vb_type_and_size(var, ASN_INTEGER, sizeof(row_ctx->saHpiWatchdogTimerReset)); break; default: /** We shouldn't get here */ rc = SNMP_ERR_GENERR; snmp_log(LOG_ERR, "unknown column in " "saHpiWatchdogTable_set_reserve1\n"); } if (rc) netsnmp_set_mode_request_error(MODE_SET_BEGIN, current->ri, rc ); rg->status = SNMP_MAX( rg->status, current->ri->status ); } /* * done with all the columns. Could check row related * requirements here. */ }
void parse_setEvent( const char *token, char *line ) { char ename[MTE_STR1_LEN+1]; char buf[SPRINT_MAX_LEN]; oid name_buf[MAX_OID_LEN]; size_t name_buf_len; long value; int wild = 1; struct mteEvent *entry; char *cp; DEBUGMSGTL(("disman:event:conf", "Parsing setEvent config... ")); memset( ename, 0, sizeof(ename)); cp = copy_nword(line, ename, MTE_STR1_LEN); if (!cp || ename[0] == '\0') { config_perror("syntax error: no event name"); return; } if (cp && *cp=='-' && *(cp+1)=='I') { wild = 0; /* an instance assignment */ cp = skip_token( cp ); } /* * Parse the SET assignment in the form "OID = value" */ cp = copy_nword(cp, buf, SPRINT_MAX_LEN); if ( buf[0] == '\0' ) { config_perror("syntax error: no set OID"); return; } name_buf_len = MAX_OID_LEN; if (!snmp_parse_oid(buf, name_buf, &name_buf_len)) { snmp_log(LOG_ERR, "setEvent OID: %s\n", buf); config_perror("unknown set OID"); return; } if (cp && *cp == '=') { cp = skip_token( cp ); /* skip the '=' assignment character */ } value = strtol( cp, NULL, 0); /* * If the entry has parsed successfully, then create, * populate and activate the new event entry. */ entry = _find_typed_mteEvent_entry("snmpd.conf", ename, MTE_EVENT_SET); if (!entry) { return; } memcpy( entry->mteSetOID, name_buf, name_buf_len*sizeof(oid)); entry->mteSetOID_len = name_buf_len; entry->mteSetValue = value; if (wild) entry->flags |= MTE_SET_FLAG_OBJWILD; entry->mteEventActions |= MTE_EVENT_SET; entry->flags |= MTE_EVENT_FLAG_ENABLED | MTE_EVENT_FLAG_ACTIVE | MTE_EVENT_FLAG_FIXED | MTE_EVENT_FLAG_VALID; return; }
/* * Load the latest memory usage statistics */ int netsnmp_mem_arch_load( netsnmp_cache *cache, void *magic ) { struct pst_static pst; struct pst_dynamic psd; netsnmp_memory_info *mem; long total_swap = 0; long free_swap = 0; long size = 0; /* * Retrieve the memory information from the underlying O/S... */ if (pstat_getstatic(&pst, sizeof(pst), (size_t) 1, 0) == -1) { snmp_log(LOG_ERR, "memory_hpux: pstat_getstatic failed!\n"); return -1; } if (pstat_getdynamic(&psd, sizeof(psd), (size_t) 1, 0) == -1) { snmp_log(LOG_ERR, "memory_hpux: pstat_getdynamic failed!\n"); return -1; } mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_PHYSMEM, 1 ); if (!mem) { snmp_log_perror("No Memory info entry"); } else { if (!mem->descr) mem->descr = strdup( "Physical memory" ); mem->units = pst.page_size; mem->size = pst.physical_memory; mem->free = psd.psd_free; mem->other = -1; } get_swapinfo(&total_swap, &free_swap, &size); mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_SWAP, 1 ); if (!mem) { snmp_log_perror("No Swap info entry"); } else { if (!mem->descr) mem->descr = strdup( "Swap space (total)" ); mem->units = size; mem->size = total_swap; mem->free = free_swap; mem->other = -1; } mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_STEXT, 1 ); if (!mem) { snmp_log_perror("No Swap text entry"); } else { if (!mem->descr) mem->descr = strdup( "Swapped text pages" ); mem->units = pst.page_size; mem->size = psd.psd_vmtxt; mem->free = psd.psd_avmtxt; mem->other = -1; } mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_RTEXT, 1 ); if (!mem) { snmp_log_perror("No real text entry"); } else { if (!mem->descr) mem->descr = strdup( "Real text pages" ); mem->units = pst.page_size; mem->size = psd.psd_rmtxt; mem->free = psd.psd_armtxt; mem->other = -1; } /* mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_MISC, 1 ); if (!mem) { snmp_log_perror("No Buffer, etc info entry"); } else { mem->units = 1024; mem->size = -1; mem->free = (pst.page_size/1024)*psd.psd_free + swap.free_swap; mem->other = -1; } */ return 0; }
/** handles requests for the pcapFilterTable table */ int pcapFilterTable_handler ( netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests ) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; netsnmp_variable_list *var = NULL; struct filter *filter = NULL; for (request = requests; request; request = request->next) { if (request->processed) continue; if (NULL == (filter = (struct filter*) netsnmp_extract_iterator_context (request))) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } if (NULL == (table_info = netsnmp_extract_table_info (request))) { continue; } /* // Sanity checking. if (*table_info->indexes->val.integer != *index) { snmp_log (LOG_ERR, "pcapFilterTable_handler(): very odd mismatch of indicies (%ld, %ld).\n", *table_info->indexes->val.integer, *index); continue; } */ var = request->requestvb; // caching for brevity. if (MODE_GET != reqinfo->mode) { snmp_log (LOG_ERR, "pcapFilterTable_handler(), unsupported mode '%d'\n", reqinfo->mode); continue; } // fprintf (stderr, "snmp GET for %s, %d\n", filter->name, table_info->colnum); struct device *device = filter->parent_device; // For brevity. switch (table_info->colnum) { case COLUMN_IFDESCR: netsnmp_set_var_string (var, device->dev_name); break; case COLUMN_FLTDESCR: netsnmp_set_var_string (var, filter->name); break; case COLUMN_FLTBPF: netsnmp_set_var_string (var, filter->bpf_text); break; case COLUMN_FLTPACKETS: netsnmp_set_var_counter64 (var, &(filter->packets)); break; case COLUMN_FLTBYTES: netsnmp_set_var_counter64 (var, &(filter->bytes)); break; case COLUMN_FLTTERMINAL: netsnmp_set_var_gauge (var, filter->terminal); break; default: netsnmp_set_request_error (reqinfo, request, SNMP_NOSUCHOBJECT); break; } } return SNMP_ERR_NOERROR; }
void parse_notificationEvent( const char *token, char *line ) { char ename[MTE_STR1_LEN+1]; char buf[SPRINT_MAX_LEN]; oid name_buf[MAX_OID_LEN]; size_t name_buf_len; struct mteEvent *entry; struct mteObject *object; int wild = 1; int idx = 0; char *cp; #ifndef NETSNMP_DISABLE_MIB_LOADING struct tree *tp; #endif struct varbind_list *var; DEBUGMSGTL(("disman:event:conf", "Parsing notificationEvent config\n")); /* * The event name could be used directly to index the mteObjectsTable. * But it's quite possible that the same name could also be used to * set up a mteTriggerTable entry (with trigger-specific objects). * * To avoid such a clash, we'll add a prefix ("_E"). */ memset(ename, 0, sizeof(ename)); ename[0] = '_'; ename[1] = 'E'; cp = copy_nword(line, ename+2, MTE_STR1_LEN-2); if (!cp || ename[2] == '\0') { config_perror("syntax error: no event name"); return; } /* * Parse the notification OID field ... */ cp = copy_nword(cp, buf, SPRINT_MAX_LEN); if ( buf[0] == '\0' ) { config_perror("syntax error: no notification OID"); return; } name_buf_len = MAX_OID_LEN; if (!snmp_parse_oid(buf, name_buf, &name_buf_len)) { snmp_log(LOG_ERR, "notificationEvent OID: %s\n", buf); config_perror("unknown notification OID"); return; } /* * ... and the relevant object/instances. */ if ( cp && *cp=='-' && *(cp+1)=='m' ) { #ifdef NETSNMP_DISABLE_MIB_LOADING config_perror("Can't use -m if MIB loading is disabled"); return; #else /* * Use the MIB definition to add the standard * notification payload to the mteObjectsTable. */ cp = skip_token( cp ); tp = get_tree( name_buf, name_buf_len, get_tree_head()); if (!tp) { config_perror("Can't locate notification payload info"); return; } for (var = tp->varbinds; var; var=var->next) { idx++; object = mteObjects_addOID( "snmpd.conf", ename, idx, var->vblabel, wild ); idx = object->mteOIndex; } #endif } while (cp) { if ( *cp == '-' ) { switch (*(cp+1)) { case 'm': config_perror("-m option must come first"); return; case 'i': /* exact instance */ case 'w': /* "not-wild" (backward compatability) */ wild = 0; break; case 'o': /* wildcarded object */ wild = 1; break; default: config_perror("unrecognised option"); return; } cp = skip_token( cp ); if (!cp) { config_perror("missing parameter"); return; } } idx++; cp = copy_nword(cp, buf, SPRINT_MAX_LEN); object = mteObjects_addOID( "snmpd.conf", ename, idx, buf, wild ); idx = object->mteOIndex; wild = 1; /* default to wildcarded objects */ } /* * If the entry has parsed successfully, then create, * populate and activate the new event entry. */ entry = _find_typed_mteEvent_entry("snmpd.conf", ename+2, MTE_EVENT_NOTIFICATION); if (!entry) { mteObjects_removeEntries( "snmpd.conf", ename ); return; } entry->mteNotification_len = name_buf_len; memcpy( entry->mteNotification, name_buf, name_buf_len*sizeof(oid)); memcpy( entry->mteNotifyOwner, "snmpd.conf", 10 ); memcpy( entry->mteNotifyObjects, ename, MTE_STR1_LEN ); entry->mteEventActions |= MTE_EVENT_NOTIFICATION; entry->flags |= MTE_EVENT_FLAG_ENABLED | MTE_EVENT_FLAG_ACTIVE | MTE_EVENT_FLAG_FIXED | MTE_EVENT_FLAG_VALID; return; }
int proxy_got_response(int operation, netsnmp_session * sess, int reqid, netsnmp_pdu *pdu, void *cb_data) { netsnmp_delegated_cache *cache = (netsnmp_delegated_cache *) cb_data; netsnmp_request_info *requests, *request; netsnmp_variable_list *vars, *var; struct simple_proxy *sp; oid myname[MAX_OID_LEN]; size_t myname_len = MAX_OID_LEN; cache = netsnmp_handler_check_cache(cache); if (!cache) { DEBUGMSGTL(("proxy", "a proxy request was no longer valid.\n")); return SNMP_ERR_NOERROR; } requests = cache->requests; sp = (struct simple_proxy *) cache->localinfo; if (!sp) { DEBUGMSGTL(("proxy", "a proxy request was no longer valid.\n")); return SNMP_ERR_NOERROR; } switch (operation) { case NETSNMP_CALLBACK_OP_TIMED_OUT: /* * WWWXXX: don't leave requests delayed if operation is * something like TIMEOUT */ DEBUGMSGTL(("proxy", "got timed out... requests = %08p\n", requests)); netsnmp_handler_mark_requests_as_delegated(requests, REQUEST_IS_NOT_DELEGATED); netsnmp_set_request_error(cache->reqinfo, requests, /* XXXWWW: should be index = 0 */ SNMP_ERR_GENERR); netsnmp_free_delegated_cache(cache); return 0; case NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE: vars = pdu->variables; /* * update the original request varbinds with the results */ for (var = vars, request = requests; request && var; request = request->next, var = var->next_variable) { snmp_set_var_typed_value(request->requestvb, var->type, var->val.string, var->val_len); DEBUGMSGTL(("proxy", "got response... ")); DEBUGMSGOID(("proxy", var->name, var->name_length)); DEBUGMSG(("proxy", "\n")); request->delegated = 0; /* * copy the oid it belongs to */ if (sp->base_len && (var->name_length < sp->base_len || snmp_oid_compare(var->name, sp->base_len, sp->base, sp->base_len) != 0)) { DEBUGMSGTL(("proxy", "out of registered range... ")); DEBUGMSGOID(("proxy", var->name, sp->base_len)); DEBUGMSG(("proxy", " (%d) != ", sp->base_len)); DEBUGMSGOID(("proxy", sp->base, sp->base_len)); DEBUGMSG(("proxy", "\n")); continue; } else if (!sp->base_len && (var->name_length < sp->name_len || snmp_oid_compare(var->name, sp->name_len, sp->name, sp->name_len) != 0)) { DEBUGMSGTL(("proxy", "out of registered base range...\n")); /* * or not if its out of our search range */ continue; } else { if (sp->base_len) { /* * XXX: oid size maxed? */ memcpy(myname, sp->name, sizeof(oid) * sp->name_len); myname_len = sp->name_len + var->name_length - sp->base_len; if (myname_len > MAX_OID_LEN) { snmp_log(LOG_WARNING, "proxy OID return length too long.\n"); netsnmp_set_request_error(cache->reqinfo, requests, SNMP_ERR_GENERR); if (pdu) snmp_free_pdu(pdu); netsnmp_free_delegated_cache(cache); return 1; } if (var->name_length > sp->base_len) memcpy(&myname[sp->name_len], &var->name[sp->base_len], sizeof(oid) * (var->name_length - sp->base_len)); snmp_set_var_objid(request->requestvb, myname, myname_len); } else { snmp_set_var_objid(request->requestvb, var->name, var->name_length); } } } if (request || var) { /* * ack, this is bad. The # of varbinds don't match and * there is no way to fix the problem */ if (pdu) snmp_free_pdu(pdu); snmp_log(LOG_ERR, "response to proxy request illegal. We're screwed.\n"); netsnmp_set_request_error(cache->reqinfo, requests, SNMP_ERR_GENERR); } /* fix bulk_to_next operations */ if (cache->reqinfo->mode == MODE_GETBULK) netsnmp_bulk_to_next_fix_requests(requests); /* * free the response */ if (pdu && 0) snmp_free_pdu(pdu); break; default: DEBUGMSGTL(("proxy", "no response received: op = %d\n", operation)); break; } netsnmp_free_delegated_cache(cache); return 1; }
int proxy_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_pdu *pdu; struct simple_proxy *sp; oid *ourname; size_t ourlength; netsnmp_request_info *request = requests; DEBUGMSGTL(("proxy", "proxy handler starting, mode = %d\n", reqinfo->mode)); switch (reqinfo->mode) { case MODE_GET: case MODE_GETNEXT: case MODE_GETBULK: /* WWWXXX */ pdu = snmp_pdu_create(reqinfo->mode); break; case MODE_SET_COMMIT: pdu = snmp_pdu_create(SNMP_MSG_SET); break; default: snmp_log(LOG_WARNING, "unsupported mode for proxy called\n"); return SNMP_ERR_NOERROR; } sp = (struct simple_proxy *) handler->myvoid; if (!pdu || !sp) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR); return SNMP_ERR_NOERROR; } while (request) { ourname = request->requestvb->name; ourlength = request->requestvb->name_length; if (sp->base_len > 0) { if ((ourlength - sp->name_len + sp->base_len) > MAX_OID_LEN) { /* * too large */ snmp_log(LOG_ERR, "proxy oid request length is too long\n"); return SNMP_ERR_NOERROR; } /* * suffix appended? */ DEBUGMSGTL(("proxy", "length=%d, base_len=%d, name_len=%d\n", ourlength, sp->base_len, sp->name_len)); if (ourlength > (int) sp->name_len) memcpy(&(sp->base[sp->base_len]), &(ourname[sp->name_len]), sizeof(oid) * (ourlength - sp->name_len)); ourlength = ourlength - sp->name_len + sp->base_len; ourname = sp->base; } snmp_pdu_add_variable(pdu, ourname, ourlength, request->requestvb->type, request->requestvb->val.string, request->requestvb->val_len); request->delegated = 1; request = request->next; } /* * send the request out */ DEBUGMSGTL(("proxy", "sending pdu\n")); snmp_async_send(sp->sess, pdu, proxy_got_response, netsnmp_create_delegated_cache(handler, reginfo, reqinfo, requests, (void *) sp)); return SNMP_ERR_NOERROR; }
/* * @internal * Check the syntax for a particular column */ NETSNMP_STATIC_INLINE int _ipv4InterfaceTable_check_column(ipv4InterfaceTable_rowreq_ctx * rowreq_ctx, netsnmp_variable_list * var, int column) { int rc = SNMPERR_SUCCESS; DEBUGMSGTL(("internal:ipv4InterfaceTable:_ipv4InterfaceTable_check_column", "called for %d\n", column)); netsnmp_assert(NULL != rowreq_ctx); switch (column) { /* * (INDEX) ipv4InterfaceIfIndex(1)/InterfaceIndex/ASN_INTEGER/long(long)//l/a/w/e/R/d/H */ case COLUMN_IPV4INTERFACEIFINDEX: rc = SNMP_ERR_NOTWRITABLE; /* can not change index of active row */ break; /* * ipv4InterfaceReasmMaxSize(2)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/R/d/h */ case COLUMN_IPV4INTERFACEREASMMAXSIZE: rc = SNMP_ERR_NOTWRITABLE; break; /* * ipv4InterfaceEnableStatus(3)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h */ case COLUMN_IPV4INTERFACEENABLESTATUS: rc = netsnmp_check_vb_type_and_size(var, ASN_INTEGER, sizeof(rowreq_ctx->data. ipv4InterfaceEnableStatus)); /* * check that the value is one of defined enums */ if ((SNMPERR_SUCCESS == rc) && (*var->val.integer != IPV4INTERFACEENABLESTATUS_UP) && (*var->val.integer != IPV4INTERFACEENABLESTATUS_DOWN) ) { rc = SNMP_ERR_WRONGVALUE; } if (SNMPERR_SUCCESS != rc) { DEBUGMSGTL(("ipv4InterfaceTable:_ipv4InterfaceTable_check_column:ipv4InterfaceEnableStatus", "varbind validation failed (eg bad type or size)\n")); } else { rc = ipv4InterfaceEnableStatus_check_value(rowreq_ctx, *((u_long *) var-> val.string)); if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc) && (MFD_NOT_VALID_NOW != rc)) { snmp_log(LOG_ERR, "bad rc %d from ipv4InterfaceEnableStatus_check_value\n", rc); rc = SNMP_ERR_GENERR; } } break; /* * ipv4InterfaceRetransmitTime(4)/UNSIGNED32/ASN_UNSIGNED/u_long(u_long)//l/A/w/e/r/D/h */ case COLUMN_IPV4INTERFACERETRANSMITTIME: rc = SNMP_ERR_NOTWRITABLE; break; default: /** We shouldn't get here */ rc = SNMP_ERR_GENERR; snmp_log(LOG_ERR, "unknown column %d in _ipv4InterfaceTable_check_column\n", column); } return rc; } /* _ipv4InterfaceTable_check_column */
int main (int argc, char **argv) { int agentx_subagent = AGENT_TRUE; int c; int rc = 0; SaErrorT rv = SA_OK; SaHpiVersionT hpiVer; SaHpiSessionIdT sessionid; SaHpiDomainInfoT domain_info; SaHpiBoolT run_threaded = TRUE; pid_t child; char * env; /* change this if you want to be a SNMP master agent */ debug_register_tokens (AGENT); snmp_enable_stderrlog (); snmp_set_do_debugging (1); while ((c = getopt (argc, argv, "fdsCx:h?")) != EOF) { switch (c) { case 'f': do_fork = AGENT_TRUE; break; case 'd': debug_register_tokens (AGENT); snmp_enable_stderrlog (); snmp_set_do_debugging (1); break; case 's': do_syslog = AGENT_FALSE; break; case 'C': netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_READ_CONFIGS, 1); break; case 'x': netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET, optarg); break; case 'h': default: usage(argv[0]); exit(1); break; } } if (do_syslog == AGENT_TRUE) { snmp_enable_calllog (); snmp_enable_syslog_ident (AGENT, LOG_DAEMON); } snmp_log (LOG_INFO, "Starting %s\n", version); /* we're an agentx subagent? */ if (agentx_subagent) { /* make us a agentx client. */ rc = netsnmp_ds_set_boolean (NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1); } /* initialize the agent library */ rc = init_agent (AGENT); if (rc != 0) { snmp_log (LOG_ERR, "Could not initialize connection to SNMP daemon. \n" "Perhaps you are running %s as non-root?\n", argv[0]); exit (rc); } /* Read configuration information here, before we initialize */ snmpd_register_config_handler (TRAPS_TOKEN, hpiSubagent_parse_config_traps, NULL, "hpiSubagent on/off switch for sending events upon startup"); snmpd_register_config_handler (MAX_EVENT_TOKEN, hpiSubagent_parse_config_max_event, NULL, "hpiSubagent MAX number of rows for Events."); init_snmp (AGENT); /* * Initialize HPI library */ hpiVer = saHpiVersionGet(); DEBUGMSGTL ((AGENT, "Hpi Version %d Implemented.\n", hpiVer)); rv = saHpiSessionOpen( SAHPI_UNSPECIFIED_DOMAIN_ID, &sessionid, NULL ); if (rv != SA_OK) { DEBUGMSGTL ((AGENT, "saHpiSessionOpen Error: returns %s\n", oh_lookup_error(rv))); exit(-1); } DEBUGMSGTL ((AGENT, "saHpiSessionOpen returns with SessionId %d\n", sessionid)); /* Get the DomainInfo structur, This is how we get theDomainId for this Session */ rv = saHpiDomainInfoGet(sessionid, &domain_info); if (rv != SA_OK) { DEBUGMSGTL ((AGENT, "saHpiSessionOpen Error: returns %s\n", oh_lookup_error(rv))); exit(-1); } /* store session numbers */ store_session_info(sessionid, domain_info.DomainId); /* subscribe all sessions/events */ subcsribe_all_sessions(); /* Resource discovery */ rv = saHpiDiscover(sessionid); if (rv != SA_OK) { DEBUGMSGTL ((AGENT, "saHpiDiscover Error: returns %s\n",oh_lookup_error(rv))); exit(-1); } DEBUGMSGTL ((AGENT, "saHpiDiscover Success!\n")); /* Initialize subagent tables */ init_saHpiAdministration(); init_saHpiDomainInfoTable(); init_saHpiDomainAlarmTable(); init_saHpiDomainReferenceTable(); init_saHpiResourceTable(); init_saHpiRdrTable(); init_saHpiCtrlDigitalTable(); init_saHpiCtrlDiscreteTable(); init_saHpiCtrlAnalogTable(); init_saHpiCtrlStreamTable(); init_saHpiCtrlTextTable(); init_saHpiCtrlOemTable(); init_saHpiSensorTable(); init_saHpiCurrentSensorStateTable(); init_saHpiSensorReadingMaxTable(); init_saHpiSensorReadingMinTable(); init_saHpiSensorReadingNominalTable(); init_saHpiSensorReadingNormalMaxTable(); init_saHpiSensorReadingNormalMinTable(); init_saHpiSensorThdLowCriticalTable(); init_saHpiSensorThdLowMajorTable(); init_saHpiSensorThdLowMinorTable(); init_saHpiSensorThdUpCriticalTable(); init_saHpiSensorThdUpMajorTable(); init_saHpiSensorThdUpMinorTable(); init_saHpiSensorThdPosHysteresisTable(); init_saHpiSensorThdNegHysteresisTable(); init_saHpiInventoryTable(); init_saHpiWatchdogTable(); init_saHpiAnnunciatorTable(); init_saHpiAreaTable(); init_saHpiFieldTable(); init_saHpiEventTable(); init_saHpiResourceEventTable(); init_saHpiDomainEventTable(); init_saHpiSensorEventTable(); init_saHpiOemEventTable(); init_saHpiHotSwapEventTable(); init_saHpiWatchdogEventTable(); init_saHpiSoftwareEventTable(); init_saHpiSensorEnableChangeEventTable(); init_saHpiUserEventTable(); init_saHpiEventLogInfoTable(); init_saHpiEventLogTable(); init_saHpiResourceEventLogTable(); init_saHpiSensorEventLogTable(); init_saHpiHotSwapEventLogTable(); init_saHpiWatchdogEventLogTable(); init_saHpiSoftwareEventLogTable(); init_saHpiOemEventLogTable(); init_saHpiUserEventLogTable(); init_saHpiSensorEnableChangeEventLogTable(); init_saHpiDomainEventLogTable(); init_saHpiHotSwapTable(); init_saHpiAutoInsertTimeoutTable(); init_saHpiAutoInsertTimeoutTable(); init_saHpiAnnouncementTable(); init_saHpiAnnouncementEventLogTable(); if (send_traps_on_startup == AGENT_TRUE) send_traps = AGENT_TRUE; /* after initialization populate tables */ populate_saHpiDomainInfoTable(sessionid); populate_saHpiDomainAlarmTable(sessionid); poplulate_saHpiDomainReferenceTable(sessionid); populate_saHpiResourceTable(sessionid); /* populate_saHpiResourceTable() calls: * populate_saHpiRdrTable(); calls: * populate_saHpiCtrlDigitalTable(); * populate_saHpiCtrlDiscreteTable(); * populate_saHpiCtrlAnalogTable(); * populate_saHpiCtrlStreamTable(); * populate_saHpiCtrlTextTable(); * populate_saHpiCtrlOemTable(); * populate_saHpiSensorTable(); * populate_saHpiSesnorReadingMaxTable(); * populate_saHpiSesnorReadingMinTable(); * populate_saHpiSesnorReadingNominalTable(); * populate_saHpiSesnorReadingNormalMaxTable(); * populate_saHpiSesnorReadingNormalMinTable(); * populate_saHpiSensorThdLowCriticalTable(); * populate_saHpiSensorThdLowMajorTable(); * populate_saHpiSensorThdLowMinorTable(); * populate_saHpiSensorThdUpCriticalTable(); * populate_saHpiSensorThdUpMajorTable(); * populate_saHpiSensorThdUpMinorTable(); * populate_saHpiSensorThdPosHysteresisTable(); * populate_saHpiSensorThdNegHysteresisTable(); * populate_saHpiCurrentSensorStateTable(); * populate_saHpiInventoryTable(); * populate_saHpiAreaTable(); * populate_saHpiFieldTable(); * populate_saHpiWatchdogTable(); * populate_saHpiAnnunciatorTable(); * populate_saHpiHotSwapTable(); * populate_saHpiAutoInsertTimeoutTable(); * populate_saHpiAnnouncementTable(); */ populate_saHpiEventTable(sessionid); /* populate_saHpiResourceEventTable(); * populate_saHpiDomainEventTable(); * populate_saHpiSensorEventTable(); * populate_saHpiOemEventTable(); * populate_saHpiHotSwapEventTable(); * populate_saHpiWatchdogEventTable(); * populate_saHpiSoftwareEventTable(); * populate_saHpiSensorEnableChangeEventTable(); * populate_saHpiUserEventTable(); */ populate_saHpiEventLogInfo(sessionid); /* populate_saHpiEventLog (sessionid); * populate_saHpiResourceEventLogTable(); * populate_saHpiSensorEventLogTable(); * populate_saHpiHotSwapEventLogTable(); * populate_saHpiWatchdogEventLogTable(); * populate_saHpiSoftwareEventLogTable(); * populate_saHpiOemEventLogTable(); * populate_saHpiUserEventLogTable(); * populate_saHpiSensorEnableChangeEventLogTable(); * populate_saHpiDomainEventLogTable(); */ /* Determine whether or not we're in threaded mode */ env = getenv("OPENHPI_THREADED"); if ((env == (char *)NULL) || (strcmp(env, "NO") == 0)) { DEBUGMSGTL ((AGENT, "Running in nonthreaded mode. Configuring polling mechanism\n")); run_threaded = SAHPI_FALSE; set_run_threaded(FALSE); if (init_alarm() != AGENT_ERR_NOERROR) { snmp_log (LOG_ERR, "Could not initialize polling mechanism. Exiting\n."); rc = -1; goto stop; } } else { DEBUGMSGTL ((AGENT, "Running in threaded mode. Spawing thread\n")); /* start event thread */ set_run_threaded(TRUE); if (start_event_thread(&sessionid) != AGENT_ERR_NOERROR) { snmp_log (LOG_ERR, "Could not start our internal loop . Exiting\n."); rc = -1; goto stop; } } send_traps = AGENT_TRUE; /* If we're going to be a snmp master agent, initial the ports */ if (!agentx_subagent) init_master_agent (); /* open the port to listen on (defaults to udp:161) */ if (do_fork == AGENT_TRUE) { if ((child = fork ()) < 0) { snmp_log (LOG_ERR, "Could not fork!\n"); exit (-1); } if (child != 0) exit (0); } /* In case we recevie a request to stop (kill -TERM or kill -INT) */ keep_running = 1; signal (SIGTERM, stop_server); signal (SIGINT, stop_server); /* you're main loop here... */ while (keep_running) { /* if you use select(), see snmp_select_info() in snmp_api(3) */ /* --- OR --- */ rc = agent_check_and_process (1); } stop: DEBUGMSGTL ((AGENT, "WARNING: closeSaHpiSession: hpiSubagent.c: nolong implemented!")); //closeSaHpiSession(); /* at shutdown time */ snmp_log (LOG_INFO, "Stopping %s\n", version); snmp_shutdown (AGENT); return rc; }
/************************************************************ * * Initialize the saHpiSensorTable table by defining its contents and how it's structured */ void initialize_table_saHpiSensorTable (void) { netsnmp_table_registration_info *table_info; if (my_handler) { snmp_log (LOG_ERR, "initialize_table_saHpiSensorTable_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 ("saHpiSensorTable", netsnmp_table_array_helper_handler, saHpiSensorTable_oid, saHpiSensorTable_oid_len, HANDLER_CAN_RWRITE); if (!my_handler || !table_info) { snmp_log (LOG_ERR, "malloc failed in " "initialize_table_saHpiSensorTable_handler\n"); return; /** mallocs failed */ } /*************************************************** * Setting up the table's definition */ /* * internal indexes */ /** index: saHpiSensorIndex */ netsnmp_table_helper_add_index (table_info, ASN_UNSIGNED); netsnmp_table_helper_add_index (table_info, ASN_UNSIGNED); netsnmp_table_helper_add_index (table_info, ASN_UNSIGNED); table_info->min_column = saHpiSensorTable_COL_MIN; table_info->max_column = saHpiSensorTable_COL_MAX; /*************************************************** * registering the table with the master agent */ cb.get_value = saHpiSensorTable_get_value; cb.container = netsnmp_container_find ("saHpiSensorTable_primary:" "saHpiSensorTable:" "table_container"); // cb.can_set = 1; cb.create_row = (UserRowMethod *) saHpiSensorTable_create_row; cb.duplicate_row = (UserRowMethod *) saHpiSensorTable_duplicate_row; cb.delete_row = (UserRowMethod *) saHpiSensorTable_delete_row; cb.row_copy = (Netsnmp_User_Row_Operation *) saHpiSensorTable_row_copy; cb.can_delete = (Netsnmp_User_Row_Action *) saHpiSensorTable_can_delete; cb.set_reserve1 = saHpiSensorTable_set_reserve1; cb.set_reserve2 = saHpiSensorTable_set_reserve2; cb.set_action = saHpiSensorTable_set_action; cb.set_commit = saHpiSensorTable_set_commit; cb.set_free = saHpiSensorTable_set_free; cb.set_undo = saHpiSensorTable_set_undo; DEBUGMSGTL (("initialize_table_saHpiSensorTable", "Registering table saHpiSensorTable " "as a table array\n")); netsnmp_table_container_register (my_handler, table_info, &cb, cb.container, 1); netsnmp_register_read_only_counter32_instance ("sensor_count", saHpiSensorCount_oid, OID_LENGTH (saHpiSensorCount_oid), &sensor_count, NULL); }
int didSaHpiChanged (int *answer, SaHpiRptInfoT * info) { int rc = AGENT_ERR_NOERROR; SaHpiRptInfoT rpt_info_new; SaErrorT err; DEBUGMSGTL ((AGENT, "--- didSaHpiChanged: Entry. ")); if (session_avail == AGENT_FALSE) { if ((rc = getSaHpiSession (NULL)) != AGENT_ERR_NOERROR) { // Something is screwy. Bail out return rc; } } /* err = saHpiResourcesDiscover (session_id); if (SA_OK != err) { snmp_log (LOG_ERR, "saHpiResourcesDiscover error: %s\n", oh_lookup_error(err)); return AGENT_ERR_DISCOVER; } */ err = saHpiRptInfoGet (session_id, &rpt_info_new); if (SA_OK != err) { snmp_log (LOG_ERR, "saHpiRptInfoGet error: %s\n", oh_lookup_error(err)); return AGENT_ERR_RPTGET; } if ((rpt_info_new.UpdateCount != rpt_info.UpdateCount) || (rpt_info_new.UpdateTimestamp != rpt_info.UpdateTimestamp)) { // Something new. if (answer) { *answer = AGENT_TRUE; DEBUGMSGTL ((AGENT, "New UpdateCount: %d, TimeStamp: %d\n ", rpt_info.UpdateCount, rpt_info.UpdateTimestamp)); } rpt_info = rpt_info_new; } else { if (answer) *answer = AGENT_FALSE; } // Change regardless of answer. if (info) *info = rpt_info; DEBUGMSGTL ((AGENT, "--- didSaHpiChanged: Exit.\n")); return rc; }
/************************************************************ * saHpiSensorTable_get_value */ int saHpiSensorTable_get_value (netsnmp_request_info * request, netsnmp_index * item, netsnmp_table_request_info * table_info) { netsnmp_variable_list *var = request->requestvb; saHpiSensorTable_context *context = (saHpiSensorTable_context *) item; switch (table_info->colnum) { case COLUMN_SAHPISENSORINDEX: /** UNSIGNED32 = ASN_UNSIGNED */ snmp_set_var_typed_value (var, ASN_UNSIGNED, (char *) &context->saHpiSensorIndex, sizeof (context->saHpiSensorIndex)); break; case COLUMN_SAHPISENSORTYPE: /** INTEGER = ASN_INTEGER */ snmp_set_var_typed_value (var, ASN_INTEGER, (char *) &context->saHpiSensorType, sizeof (context->saHpiSensorType)); break; case COLUMN_SAHPISENSORCATEGORY: /** INTEGER = ASN_INTEGER */ snmp_set_var_typed_value (var, ASN_INTEGER, (char *) &context->saHpiSensorCategory, sizeof (context->saHpiSensorCategory)); break; case COLUMN_SAHPISENSOREVENTSCATEGORYCONTROL: /** INTEGER = ASN_INTEGER */ snmp_set_var_typed_value (var, ASN_INTEGER, (char *) &context-> saHpiSensorEventsCategoryControl, sizeof (context-> saHpiSensorEventsCategoryControl)); break; case COLUMN_SAHPISENSOREVENTSSUPPORTED: /** OCTETSTR = ASN_OCTET_STR */ snmp_set_var_typed_value (var, ASN_OCTET_STR, (char *) &context-> saHpiSensorEventsSupported, context->saHpiSensorEventsSupported_len); break; case COLUMN_SAHPISENSORSTATUS: /** UNSIGNED32 = ASN_UNSIGNED */ snmp_set_var_typed_value (var, ASN_UNSIGNED, (char *) &context->saHpiSensorStatus, sizeof (context->saHpiSensorStatus)); break; case COLUMN_SAHPISENSORASSERTEVENTS: /** OCTETSTR = ASN_OCTET_STR */ snmp_set_var_typed_value (var, ASN_OCTET_STR, (char *) &context-> saHpiSensorAssertEvents, context->saHpiSensorAssertEvents_len); break; case COLUMN_SAHPISENSORDEASSERTEVENTS: /** OCTETSTR = ASN_OCTET_STR */ snmp_set_var_typed_value (var, ASN_OCTET_STR, (char *) &context-> saHpiSensorDeassertEvents, context->saHpiSensorDeassertEvents_len); break; case COLUMN_SAHPISENSORIGNORE: /** TruthValue = ASN_INTEGER */ snmp_set_var_typed_value (var, ASN_INTEGER, (char *) &context->saHpiSensorIgnore, sizeof (context->saHpiSensorIgnore)); break; case COLUMN_SAHPISENSORREADINGFORMATS: /** UNSIGNED32 = ASN_UNSIGNED */ snmp_set_var_typed_value (var, ASN_UNSIGNED, (char *) &context-> saHpiSensorReadingFormats, sizeof (context->saHpiSensorReadingFormats)); break; case COLUMN_SAHPISENSORISNUMERIC: /** TruthValue = ASN_INTEGER */ snmp_set_var_typed_value (var, ASN_INTEGER, (char *) &context->saHpiSensorIsNumeric, sizeof (context->saHpiSensorIsNumeric)); break; case COLUMN_SAHPISENSORSIGNFORMAT: /** INTEGER = ASN_INTEGER */ snmp_set_var_typed_value (var, ASN_INTEGER, (char *) &context->saHpiSensorSignFormat, sizeof (context->saHpiSensorSignFormat)); break; case COLUMN_SAHPISENSORBASEUNITS: /** INTEGER = ASN_INTEGER */ snmp_set_var_typed_value (var, ASN_INTEGER, (char *) &context->saHpiSensorBaseUnits, sizeof (context->saHpiSensorBaseUnits)); break; case COLUMN_SAHPISENSORMODIFIERUNITS: /** INTEGER = ASN_INTEGER */ snmp_set_var_typed_value (var, ASN_INTEGER, (char *) &context-> saHpiSensorModifierUnits, sizeof (context->saHpiSensorModifierUnits)); break; case COLUMN_SAHPISENSORMODIFIERUSE: /** INTEGER = ASN_INTEGER */ snmp_set_var_typed_value (var, ASN_INTEGER, (char *) &context->saHpiSensorModifierUse, sizeof (context->saHpiSensorModifierUse)); break; case COLUMN_SAHPISENSORFACTORSSTATIC: /** TruthValue = ASN_INTEGER */ snmp_set_var_typed_value (var, ASN_INTEGER, (char *) &context-> saHpiSensorFactorsStatic, sizeof (context->saHpiSensorFactorsStatic)); break; case COLUMN_SAHPISENSORFACTORS: /** OCTETSTR = ASN_OCTET_STR */ snmp_set_var_typed_value (var, ASN_OCTET_STR, (char *) &context->saHpiSensorFactors, context->saHpiSensorFactors_len); break; case COLUMN_SAHPISENSORFACTORSLINEARIZATION: /** INTEGER = ASN_INTEGER */ snmp_set_var_typed_value (var, ASN_INTEGER, (char *) &context-> saHpiSensorFactorsLinearization, sizeof (context-> saHpiSensorFactorsLinearization)); break; case COLUMN_SAHPISENSORPERCENTAGE: /** TruthValue = ASN_INTEGER */ snmp_set_var_typed_value (var, ASN_INTEGER, (char *) &context->saHpiSensorPercentage, sizeof (context->saHpiSensorPercentage)); break; case COLUMN_SAHPISENSORRANGEFLAGS: /** OCTETSTR = ASN_OCTET_STR */ snmp_set_var_typed_value (var, ASN_OCTET_STR, (char *) &context->saHpiSensorRangeFlags, context->saHpiSensorRangeFlags_len); break; case COLUMN_SAHPISENSORHASTHRESHOLDS: /** TruthValue = ASN_INTEGER */ snmp_set_var_typed_value (var, ASN_INTEGER, (char *) &context-> saHpiSensorHasThresholds, sizeof (context->saHpiSensorHasThresholds)); break; case COLUMN_SAHPISENSORTHRESHOLDCAPABILITIES: /** INTEGER = ASN_INTEGER */ snmp_set_var_typed_value (var, ASN_INTEGER, (char *) &context-> saHpiSensorThresholdCapabilities, sizeof (context-> saHpiSensorThresholdCapabilities)); break; case COLUMN_SAHPISENSOROEM: /** UNSIGNED32 = ASN_UNSIGNED */ snmp_set_var_typed_value (var, ASN_UNSIGNED, (char *) &context->saHpiSensorOEM, sizeof (context->saHpiSensorOEM)); break; case COLUMN_SAHPISENSORRDR: /** RowPointer = ASN_OBJECT_ID */ snmp_set_var_typed_value (var, ASN_OBJECT_ID, (char *) &context->saHpiSensorRDR, context->saHpiSensorRDR_len); break; default: /** We shouldn't get here */ snmp_log (LOG_ERR, "unknown column in " "saHpiSensorTable_get_value\n"); return SNMP_ERR_GENERR; } return SNMP_ERR_NOERROR; }
/** * the *_extract_index routine * * This routine is called when a set request is received for an index * that was not found in the table container. Here, we parse the oid * in the the individual index components and copy those indexes to the * context. Then we make sure the indexes for the new row are valid. */ int saHpiWatchdogTable_extract_index( saHpiWatchdogTable_context * ctx, netsnmp_index * hdr ) { /* * temporary local storage for extracting oid index * * extract index uses varbinds (netsnmp_variable_list) to parse * the index OID into the individual components for each index part. */ /** TODO: add storage for external index(s)! */ netsnmp_variable_list var_saHpiDomainId; netsnmp_variable_list var_saHpiResourceId; netsnmp_variable_list var_saHpiResourceIsHistorical; netsnmp_variable_list var_saHpiWatchdogNum; int err; /* * copy index, if provided */ if(hdr) { netsnmp_assert(ctx->index.oids == NULL); if(snmp_clone_mem( (void*)&ctx->index.oids, hdr->oids, hdr->len * sizeof(oid) )) { return -1; } ctx->index.len = hdr->len; } /* * initialize variable that will hold each component of the index. * If there are multiple indexes for the table, the variable_lists * need to be linked together, in order. */ /** TODO: add code for external index(s)! */ memset( &var_saHpiDomainId, 0x00, sizeof(var_saHpiDomainId) ); var_saHpiDomainId.type = ASN_UNSIGNED; /* type hint for parse_oid_indexes */ /** TODO: link this index to the next, or NULL for the last one */ #ifdef TABLE_CONTAINER_TODO snmp_log(LOG_ERR, "saHpiWatchdogTable_extract_index index list not implemented!\n" ); return 0; #else var_saHpiDomainId.next_variable = &var_XX; #endif memset( &var_saHpiResourceId, 0x00, sizeof(var_saHpiResourceId) ); var_saHpiResourceId.type = ASN_UNSIGNED; /* type hint for parse_oid_indexes */ /** TODO: link this index to the next, or NULL for the last one */ #ifdef TABLE_CONTAINER_TODO snmp_log(LOG_ERR, "saHpiWatchdogTable_extract_index index list not implemented!\n" ); return 0; #else var_saHpiResourceId.next_variable = &var_XX; #endif memset( &var_saHpiResourceIsHistorical, 0x00, sizeof(var_saHpiResourceIsHistorical) ); var_saHpiResourceIsHistorical.type = ASN_INTEGER; /* type hint for parse_oid_indexes */ /** TODO: link this index to the next, or NULL for the last one */ #ifdef TABLE_CONTAINER_TODO snmp_log(LOG_ERR, "saHpiWatchdogTable_extract_index index list not implemented!\n" ); return 0; #else var_saHpiResourceIsHistorical.next_variable = &var_XX; #endif memset( &var_saHpiWatchdogNum, 0x00, sizeof(var_saHpiWatchdogNum) ); var_saHpiWatchdogNum.type = ASN_UNSIGNED; /* type hint for parse_oid_indexes */ /** TODO: link this index to the next, or NULL for the last one */ #ifdef TABLE_CONTAINER_TODO snmp_log(LOG_ERR, "saHpiWatchdogTable_extract_index index list not implemented!\n" ); return 0; #else var_saHpiWatchdogNum.next_variable = &var_XX; #endif /* * parse the oid into the individual index components */ err = parse_oid_indexes( hdr->oids, hdr->len, &var_saHpiDomainId ); if (err == SNMP_ERR_NOERROR) { /* * copy index components into the context structure */ /** skipping external index saHpiDomainId */ /** skipping external index saHpiResourceId */ /** skipping external index saHpiResourceIsHistorical */ ctx->saHpiWatchdogNum = *var_saHpiWatchdogNum.val.integer; /* * TODO: check index for valid values. For EXAMPLE: * * if ( *var_saHpiDomainId.val.integer != XXX ) { * err = -1; * } */ /* * TODO: check index for valid values. For EXAMPLE: * * if ( *var_saHpiResourceId.val.integer != XXX ) { * err = -1; * } */ /* * TODO: check index for valid values. For EXAMPLE: * * if ( *var_saHpiResourceIsHistorical.val.integer != XXX ) { * err = -1; * } */ /* * TODO: check index for valid values. For EXAMPLE: * * if ( *var_saHpiWatchdogNum.val.integer != XXX ) { * err = -1; * } */ } /* * parsing may have allocated memory. free it. */ snmp_reset_var_buffers( &var_saHpiDomainId ); return err; }
int set_sensor_event (saHpiSensorTable_context * ctx) { SaHpiSessionIdT session_id; SaErrorT rc; SaHpiSensorEvtEnablesT enables; if (ctx) { memset (&enables, 0x00, sizeof (SaHpiSensorEvtEnablesT)); enables.SensorStatus = ctx->saHpiSensorStatus; rc = build_state_value (ctx->saHpiSensorAssertEvents, ctx->saHpiSensorAssertEvents_len, &enables.AssertEvents); if (rc != AGENT_ERR_NOERROR) { DEBUGMSGTL ((AGENT, "Call to build_state_value with [%s] failed with rc: %d.\n", ctx->saHpiSensorAssertEvents, rc)); return AGENT_ERR_WRONG_DELIM; } rc = build_state_value (ctx->saHpiSensorDeassertEvents, ctx->saHpiSensorDeassertEvents_len, &enables.DeassertEvents); if (rc != AGENT_ERR_NOERROR) { DEBUGMSGTL ((AGENT, "Call to build_state_value with [%s] failed with rc: %d.\n", ctx->saHpiSensorDeassertEvents, rc)); return AGENT_ERR_WRONG_DELIM; } DEBUGMSGTL ((AGENT, "enables.SensorStatus: %X\n" "enables.AssertEvents: %X[%s]\n" "enables.DeassertEvents: %X[%s]\n", enables.SensorStatus, enables.AssertEvents, ctx->saHpiSensorAssertEvents, enables.DeassertEvents, ctx->saHpiSensorDeassertEvents)); // Get the seesion_id rc = getSaHpiSession (&session_id); if (rc != AGENT_ERR_NOERROR) { DEBUGMSGTL ((AGENT, "Call to getSaHpiSession failed with rc: %d\n", rc)); return rc; } DEBUGMSGTL ((AGENT, "Calling 'saHpiSensorEventEnablesSet'\n")); rc = saHpiSensorEventEnablesSet (session_id, ctx->resource_id, ctx->saHpiSensorIndex, &enables); if (rc != SA_OK) { snmp_log (LOG_ERR, "Call to saHpiSensorEventEnablesSet failed wit return code %s.\n", get_error_string (rc)); DEBUGMSGTL ((AGENT, "Call to saHpiSensorEventEnablesSet failed wit return code %s.\n", get_error_string (rc))); return AGENT_ERR_OPERATION; } build_state_string (ctx->saHpiSensorCategory - 1, enables.AssertEvents, (char *) &ctx->saHpiSensorAssertEvents, &ctx->saHpiSensorAssertEvents_len, SENSOR_EVENTS_SUPPORTED_MAX); build_state_string (ctx->saHpiSensorCategory - 1, enables.DeassertEvents, (char *) &ctx->saHpiSensorDeassertEvents, &ctx->saHpiSensorDeassertEvents_len, SENSOR_EVENTS_SUPPORTED_MAX); return AGENT_ERR_NOERROR; } return AGENT_ERR_NULL_DATA; }
int main(int argc, char *argv[]) { int arg; char *current_name = NULL, *cp = NULL; oid name[MAX_OID_LEN]; size_t name_length; int description = 0; int print = 0; int find_all = 0; int width = 1000000; /* * usage: snmptranslate name */ while ((arg = getopt(argc, argv, "Vhm:M:w:D:P:T:O:I:L:")) != EOF) { switch (arg) { case 'h': usage(); exit(1); case 'm': setenv("MIBS", optarg, 1); break; case 'M': setenv("MIBDIRS", optarg, 1); break; case 'D': debug_register_tokens(optarg); snmp_set_do_debugging(1); break; case 'V': fprintf(stderr, "NET-SNMP version: %s\n", netsnmp_get_version()); exit(0); break; case 'w': width = atoi(optarg); if (width <= 0) { fprintf(stderr, "Invalid width specification: %s\n", optarg); exit (1); } break; #ifndef NETSNMP_DISABLE_MIB_LOADING case 'P': cp = snmp_mib_toggle_options(optarg); if (cp != NULL) { fprintf(stderr, "Unknown parser option to -P: %c.\n", *cp); usage(); exit(1); } break; #endif /* NETSNMP_DISABLE_MIB_LOADING */ case 'O': cp = snmp_out_toggle_options(optarg); if (cp != NULL) { fprintf(stderr, "Unknown OID option to -O: %c.\n", *cp); usage(); exit(1); } break; case 'I': cp = snmp_in_toggle_options(optarg); if (cp != NULL) { fprintf(stderr, "Unknown OID option to -I: %c.\n", *cp); usage(); exit(1); } break; case 'T': for (cp = optarg; *cp; cp++) { switch (*cp) { #ifndef NETSNMP_DISABLE_MIB_LOADING case 'l': print = 3; print_oid_report_enable_labeledoid(); break; case 'o': print = 3; print_oid_report_enable_oid(); break; case 's': print = 3; print_oid_report_enable_symbolic(); break; case 't': print = 3; print_oid_report_enable_suffix(); break; case 'z': print = 3; print_oid_report_enable_mibchildoid(); break; #endif /* NETSNMP_DISABLE_MIB_LOADING */ case 'd': description = 1; snmp_set_save_descriptions(1); break; case 'B': find_all = 1; break; case 'p': print = 1; break; case 'a': print = 2; break; default: fprintf(stderr, "Invalid -T<lostpad> character: %c\n", *cp); usage(); exit(1); break; } } break; case 'L': if (snmp_log_options(optarg, argc, argv) < 0) { return (-1); } break; default: fprintf(stderr, "invalid option: -%c\n", arg); usage(); exit(1); break; } } snmp_enable_stderrlog(); init_snmp("snmpapp"); if (optind < argc) current_name = argv[optind]; if (current_name == NULL) { switch (print) { default: usage(); exit(1); #ifndef NETSNMP_DISABLE_MIB_LOADING case 1: print_mib_tree(stdout, get_tree_head(), width); break; case 2: print_ascii_dump(stdout); break; case 3: print_oid_report(stdout); break; #endif /* NETSNMP_DISABLE_MIB_LOADING */ } exit(0); } do { name_length = MAX_OID_LEN; if (snmp_get_random_access()) { #ifndef NETSNMP_DISABLE_MIB_LOADING if (!get_node(current_name, name, &name_length)) { #endif /* NETSNMP_DISABLE_MIB_LOADING */ fprintf(stderr, "Unknown object identifier: %s\n", current_name); exit(2); #ifndef NETSNMP_DISABLE_MIB_LOADING } #endif /* NETSNMP_DISABLE_MIB_LOADING */ } else if (find_all) { if (0 == show_all_matched_objects(stdout, current_name, name, &name_length, description, width)) { fprintf(stderr, "Unable to find a matching object identifier for \"%s\"\n", current_name); exit(1); } exit(0); } else if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_REGEX_ACCESS)) { #ifndef NETSNMP_DISABLE_MIB_LOADING if (0 == get_wild_node(current_name, name, &name_length)) { #endif /* NETSNMP_DISABLE_MIB_LOADING */ fprintf(stderr, "Unable to find a matching object identifier for \"%s\"\n", current_name); exit(1); #ifndef NETSNMP_DISABLE_MIB_LOADING } #endif /* NETSNMP_DISABLE_MIB_LOADING */ } else { if (!read_objid(current_name, name, &name_length)) { snmp_perror(current_name); exit(2); } } if (print == 1) { #ifndef NETSNMP_DISABLE_MIB_LOADING struct tree *tp; tp = get_tree(name, name_length, get_tree_head()); if (tp == NULL) { #endif /* NETSNMP_DISABLE_MIB_LOADING */ snmp_log(LOG_ERR, "Unable to find a matching object identifier for \"%s\"\n", current_name); exit(1); #ifndef NETSNMP_DISABLE_MIB_LOADING } print_mib_tree(stdout, tp, width); #endif /* NETSNMP_DISABLE_MIB_LOADING */ } else { print_objid(name, name_length); if (description) { #ifndef NETSNMP_DISABLE_MIB_LOADING print_description(name, name_length, width); #endif /* NETSNMP_DISABLE_MIB_LOADING */ } } current_name = argv[++optind]; if (current_name != NULL) printf("\n"); } while (optind < argc); return (0); }
int populate_sensor (SaHpiEntryIdT rdr_id, SaHpiSensorRecT * sensor, SaHpiRptEntryT * rpt_entry, oid * rdr_entry_oid, size_t rdr_entry_oid_len, oid * sensor_oid, size_t * sensor_oid_len) { int rc = AGENT_ERR_NOERROR; oid index_oid[SENSOR_INDEX_NR]; oid column[2]; netsnmp_index sensor_index; #ifdef BUG_873961 int i = 0; netsnmp_void_array *array; saHpiSensorTable_context *ctx; #endif saHpiSensorTable_context *sensor_context; SaHpiSensorThresholdsT sensor_threshold; SaHpiSessionIdT session_id; SaHpiSensorEvtEnablesT enables; SaHpiSensorReadingT current_reading; DEBUGMSGTL ((AGENT, "\n\t--- populate_sensor: Entry.\n")); if (sensor) { sensor_index.len = SENSOR_INDEX_NR; // Look at the MIB to find out what the indexs are index_oid[0] = rpt_entry->DomainId; index_oid[1] = rpt_entry->ResourceId; index_oid[2] = sensor->Num; sensor_index.oids = (oid *) & index_oid; // We are re-populating. Check for existing entries sensor_context = NULL; sensor_context = CONTAINER_FIND (cb.container, &sensor_index); // If we don't find it - we create it. #ifdef BUG_873961 if (!sensor_context) { // Bug # 873961. We use the 'rdr_id' to check to see if // it is the context. To do so, we have to search for it first. sensor_index.len = 1; // re-using the index_oid. array = CONTAINER_GET_SUBSET (cb.container, &sensor_index); if (array != NULL) { if (array->size > 0) { for (i = 0; i < array->size; i++) { ctx = array->array[i]; if (ctx->rdr_id == rdr_id) { // Found the duplicate entry! sensor_context = ctx; index_oid[1] = ctx->resource_id; index_oid[2] = ctx->saHpiSensorIndex; DEBUGMSGTL ((AGENT, "duplicate sensor entry %d, %d, %d [rdr: %d] found.\n", rpt_entry->DomainId, rpt_entry->ResourceId, sensor->Num, rdr_id)); break; } } } free (array->array); free (array); array = NULL; } // restoree it to its previous glory. sensor_index.len = SENSOR_INDEX_NR; } #endif if (!sensor_context) { // New entry. Add it sensor_context = saHpiSensorTable_create_row (&sensor_index); } if (!sensor_context) { snmp_log (LOG_ERR, "Not enough memory for a sensor row!"); return AGENT_ERR_INTERNAL_ERROR; } // Generate our full OID column[0] = 1; column[1] = COLUMN_SAHPISENSORINDEX; build_full_oid (saHpiSensorTable_oid, saHpiSensorTable_oid_len, column, 2, &sensor_index, sensor_oid, MAX_OID_LEN, sensor_oid_len); // By this stage, sensor_context surely has something in it. // '*_modify_context' does a checksum check to see if // the record needs to be altered, and if so populates with // information from RDR and the OIDs passed. // Get Threshold Data rc = getSaHpiSession (&session_id); if (rc != AGENT_ERR_NOERROR) { DEBUGMSGTL ((AGENT, "Call to getSaHpiSession failed with rc: %d\n", rc)); return rc; } if (sensor->ThresholdDefn.IsThreshold == SAHPI_TRUE) { rc = saHpiSensorThresholdsGet (session_id, rpt_entry->ResourceId, sensor->Num, &sensor_threshold); if (rc != SA_OK) { snmp_log (LOG_ERR, "Call to saHpiSensorThresholdsGet fails with return code: %s.\n", get_error_string (rc)); DEBUGMSGTL ((AGENT, "Call to SensorThresholdGet fails with return code: %s.\n", get_error_string (rc))); return AGENT_ERR_OPERATION; } } /* * No need to call a plugin that does not support * events. */ if (sensor->EventCtrl != SAHPI_SEC_NO_EVENTS) { rc = saHpiSensorEventEnablesGet (session_id, rpt_entry->ResourceId, sensor->Num, &enables); if (rc != SA_OK) { snmp_log (LOG_ERR, "Call to saHpiSensorEventEnablesGet fails with return code: %s.\n", get_error_string (rc)); DEBUGMSGTL ((AGENT, "Call to saHpiSensorEventEnablesGet fails with return code: %s.\n", get_error_string (rc))); // We continue on working. No need to bail on that one - will just use 'undefined(0)' values. } } rc = saHpiSensorReadingGet (session_id, rpt_entry->ResourceId, sensor->Num, ¤t_reading); if (rc != SA_OK) { snmp_log (LOG_ERR, "Call to saHpiSensorReadingGet fails with return code: %s.\n", get_error_string (rc)); DEBUGMSGTL ((AGENT, "Call to saHpiSensorReadingGet fails with return code: %s.\n", get_error_string (rc))); } if (saHpiSensorTable_modify_context (rdr_id, sensor, &enables, rpt_entry, rdr_entry_oid, rdr_entry_oid_len, sensor_context) == AGENT_NEW_ENTRY) { CONTAINER_INSERT (cb.container, sensor_context); sensor_count = CONTAINER_SIZE (cb.container); } /* Update our child sensor tables */ rc = populate_ReadingCurrent (rpt_entry->DomainId, rpt_entry->ResourceId, sensor->Num, sensor->Category, ¤t_reading); if (rc != AGENT_ERR_NOERROR) DEBUGMSGTL ((AGENT, "call to populate_ReadingCurrent failed with rc: %d\n", rc)); if (sensor_context->flags & SAHPI_SRF_MIN) { rc = populate_ReadingMin (rpt_entry->DomainId, rpt_entry->ResourceId, sensor->Num, sensor->Category, &sensor->DataFormat.Range.Min); if (rc != AGENT_ERR_NOERROR) DEBUGMSGTL ((AGENT, "call to populate_ReadingMin failed with rc: %d\n", rc)); } if (sensor_context->flags & SAHPI_SRF_MAX) { rc = populate_ReadingMax (rpt_entry->DomainId, rpt_entry->ResourceId, sensor->Num, sensor->Category, &sensor->DataFormat.Range.Max); if (rc != AGENT_ERR_NOERROR) DEBUGMSGTL ((AGENT, "call to populate_ReadingMax failed with rc: %d\n", rc)); } if (sensor_context->flags & SAHPI_SRF_NOMINAL) { rc = populate_ReadingNominal (rpt_entry->DomainId, rpt_entry->ResourceId, sensor->Num, sensor->Category, &sensor->DataFormat.Range.Nominal); if (rc != AGENT_ERR_NOERROR) DEBUGMSGTL ((AGENT, "call to populate_ReadingNominal failed with rc: %d\n", rc)); } if (sensor_context->flags & SAHPI_SRF_NORMAL_MAX) { rc = populate_ReadingNormalMax (rpt_entry->DomainId, rpt_entry->ResourceId, sensor->Num, sensor->Category, &sensor->DataFormat.Range. NormalMax); if (rc != AGENT_ERR_NOERROR) DEBUGMSGTL ((AGENT, "call to populate_ReadingNormalMax failed with rc: %d\n", rc)); } if (sensor_context->flags & SAHPI_SRF_NORMAL_MIN) { rc = populate_ReadingNormalMin (rpt_entry->DomainId, rpt_entry->ResourceId, sensor->Num, sensor->Category, &sensor->DataFormat.Range. NormalMin); if (rc != AGENT_ERR_NOERROR) DEBUGMSGTL ((AGENT, "call to populate_ReadingNormalMin failed with rc: %d\n", rc)); } /* * Thresholds */ if (sensor_context->saHpiSensorHasThresholds == MIB_TRUE) { /* if (sensor_context->thd_capabilities & SAHPI_STM_LOW_CRIT) */ { rc = populate_ThdLowCritical (rpt_entry->DomainId, rpt_entry->ResourceId, sensor->Num, &sensor->ThresholdDefn, &sensor_threshold.LowCritical); if (rc != AGENT_ERR_NOERROR) DEBUGMSGTL ((AGENT, "call to populate_ThdLowCritical failed with rc: %d\n", rc)); } /* if (sensor_context->thd_capabilities & SAHPI_STM_LOW_MAJOR) */ { rc = populate_ThdLowMajor (rpt_entry->DomainId, rpt_entry->ResourceId, sensor->Num, &sensor->ThresholdDefn, &sensor_threshold.LowMajor); if (rc != AGENT_ERR_NOERROR) DEBUGMSGTL ((AGENT, "call to populate_ThdLowMajor failed with rc: %d\n", rc)); } /* if (sensor_context->thd_capabilities & SAHPI_STM_LOW_MINOR) */ { rc = populate_ThdLowMinor (rpt_entry->DomainId, rpt_entry->ResourceId, sensor->Num, &sensor->ThresholdDefn, &sensor_threshold.LowMinor); if (rc != AGENT_ERR_NOERROR) DEBUGMSGTL ((AGENT, "call to populate_ThdLowMinor failed with rc: %d\n", rc)); } /* if (sensor_context->thd_capabilities & SAHPI_STM_UP_CRIT) */ { rc = populate_ThdUpCritical (rpt_entry->DomainId, rpt_entry->ResourceId, sensor->Num, &sensor->ThresholdDefn, &sensor_threshold.UpCritical); if (rc != AGENT_ERR_NOERROR) DEBUGMSGTL ((AGENT, "call to populate_ThdUpCritical failed with rc: %d\n", rc)); } /* if (sensor_context->thd_capabilities & SAHPI_STM_UP_MAJOR) */ { rc = populate_ThdUpMajor (rpt_entry->DomainId, rpt_entry->ResourceId, sensor->Num, &sensor->ThresholdDefn, &sensor_threshold.UpMajor); if (rc != AGENT_ERR_NOERROR) DEBUGMSGTL ((AGENT, "call to populate_ThdUpMajor failed with rc: %d\n", rc)); } /* if (sensor_context->thd_capabilities & SAHPI_STM_UP_MINOR) */ { rc = populate_ThdUpMinor (rpt_entry->DomainId, rpt_entry->ResourceId, sensor->Num, &sensor->ThresholdDefn, &sensor_threshold.UpMinor); if (rc != AGENT_ERR_NOERROR) DEBUGMSGTL ((AGENT, "call to populate_ThdUpMinor failed with rc: %d\n", rc)); } /* if (sensor_context->thd_capabilities & SAHPI_STM_UP_HYSTERESIS) */ { rc = populate_ThdPosHysteresis (rpt_entry->DomainId, rpt_entry->ResourceId, sensor->Num, &sensor->ThresholdDefn, &sensor_threshold. PosThdHysteresis); if (rc != AGENT_ERR_NOERROR) DEBUGMSGTL ((AGENT, "call to populate_ThdPosHysteresis failed with rc: %d\n", rc)); } /* if (sensor_context->thd_capabilities & SAHPI_STM_LOW_HYSTERESIS) */ { rc = populate_ThdNegHysteresis (rpt_entry->DomainId, rpt_entry->ResourceId, sensor->Num, &sensor->ThresholdDefn, &sensor_threshold. NegThdHysteresis); if (rc != AGENT_ERR_NOERROR) DEBUGMSGTL ((AGENT, "call to populate_ThdNegHysteresis failed with rc: %d\n", rc)); } } rc = AGENT_ERR_NOERROR; } else rc = AGENT_ERR_OPERATION; DEBUGMSGTL ((AGENT, "\n\t--- populate_sensor. Exit\n")); return rc; }
/* * SaErrorT populate_sensor_max() */ SaErrorT populate_sen_thd_up_minor(SaHpiSessionIdT sessionid, SaHpiRdrT *rdr_entry, SaHpiRptEntryT *rpt_entry, SaHpiSensorThresholdsT *sensor_thresholds) { DEBUGMSGTL ((AGENT, "populate_sen_thd_up_minor, called\n")); SaErrorT rv = SA_OK; int new_row = MIB_FALSE; oid sen_thd_up_minor_oid[SEN_THD_UP_MINOR_IDX_NR]; netsnmp_index sen_thd_up_minor_idx; saHpiSensorThdUpMinorTable_context *sen_thd_up_minor_ctx; /* check for NULL pointers */ if (!rdr_entry) { DEBUGMSGTL ((AGENT, "ERROR: populate_sen_thd_up_minor() passed NULL rdr_entry pointer\n")); return AGENT_ERR_INTERNAL_ERROR; } if (!rpt_entry) { DEBUGMSGTL ((AGENT, "ERROR: populate_sen_thd_up_minor() passed NULL rdr_entry pointer\n")); return AGENT_ERR_INTERNAL_ERROR; } subagent_lock(&hpi_lock_data); /* BUILD oid for new row */ /* assign the number of indices */ sen_thd_up_minor_idx.len = SEN_THD_UP_MINOR_IDX_NR; /** Index saHpiDomainId is external */ sen_thd_up_minor_oid[0] = get_domain_id(sessionid); /** Index saHpiResourceId is external */ sen_thd_up_minor_oid[1] = rpt_entry->ResourceId; /** Index saHpiResourceIsHistorical is external */ sen_thd_up_minor_oid[2] = MIB_FALSE; /** Index saHpiSensorNum */ sen_thd_up_minor_oid[3] = rdr_entry->RdrTypeUnion.SensorRec.Num; /* assign the indices to the index */ sen_thd_up_minor_idx.oids = (oid *) & sen_thd_up_minor_oid; /* See if Row exists. */ sen_thd_up_minor_ctx = NULL; sen_thd_up_minor_ctx = CONTAINER_FIND(cb.container, &sen_thd_up_minor_idx); if (!sen_thd_up_minor_ctx) { // New entry. Add it sen_thd_up_minor_ctx = saHpiSensorThdUpMinorTable_create_row(&sen_thd_up_minor_idx); new_row = MIB_TRUE; } if (!sen_thd_up_minor_ctx) { snmp_log (LOG_ERR, "Not enough memory for a ThdUpMinor row!"); subagent_unlock(&hpi_lock_data); return AGENT_ERR_INTERNAL_ERROR; } /** TruthValue = ASN_INTEGER */ if (SAHPI_STM_UP_MINOR & rdr_entry->RdrTypeUnion.SensorRec.ThresholdDefn.ReadThold) { sen_thd_up_minor_ctx->saHpiSensorThdUpMinorIsReadable = MIB_TRUE; } else { sen_thd_up_minor_ctx->saHpiSensorThdUpMinorIsReadable = MIB_FALSE; } /** TruthValue = ASN_INTEGER */ if (SAHPI_STM_UP_MINOR & rdr_entry->RdrTypeUnion.SensorRec.ThresholdDefn.WriteThold) { sen_thd_up_minor_ctx->saHpiSensorThdUpMinorIsWritable = MIB_TRUE; } else { sen_thd_up_minor_ctx->saHpiSensorThdUpMinorIsWritable = MIB_FALSE; } /** SaHpiSensorReadingType = ASN_INTEGER */ sen_thd_up_minor_ctx->saHpiSensorThdUpMinorType = sensor_thresholds->UpMinor.Type + 1; /** SaHpiSensorReadingValue = ASN_OCTET_STR */ sen_thd_up_minor_ctx->saHpiSensorThdUpMinorValue_len = set_sensor_reading_value(&sensor_thresholds->UpMinor, sen_thd_up_minor_ctx->saHpiSensorThdUpMinorValue); /** TruthValue = ASN_INTEGER */ sen_thd_up_minor_ctx->saHpiSensorThdUpMinorNonLinear = (rdr_entry->RdrTypeUnion.SensorRec.ThresholdDefn.Nonlinear == SAHPI_TRUE) ? MIB_TRUE : MIB_FALSE; if (new_row == MIB_TRUE) CONTAINER_INSERT (cb.container, sen_thd_up_minor_ctx); subagent_unlock(&hpi_lock_data); return rv; }
/* * Configure special parameters on the session. * Currently takes the parameter configured and changes it if something * was configured. It becomes "-c" if the community string from the pdu * is placed on the session. */ int proxy_fill_in_session(netsnmp_mib_handler *handler, netsnmp_agent_request_info *reqinfo, void **configured) { netsnmp_session *session; struct simple_proxy *sp; sp = (struct simple_proxy *) handler->myvoid; if (!sp) { return 0; } session = sp->sess; if (!session) { return 0; } #if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C) #if defined(NETSNMP_DISABLE_SNMPV1) if (session->version == SNMP_VERSION_2c) { #else #if defined(NETSNMP_DISABLE_SNMPV2C) if (session->version == SNMP_VERSION_1) { #else if (session->version == SNMP_VERSION_1 || session->version == SNMP_VERSION_2c) { #endif #endif /* * Check if session has community string defined for it. * If not, need to extract community string from the pdu. * Copy to session and set 'configured' to indicate this. */ if (session->community_len == 0) { DEBUGMSGTL(("proxy", "session has no community string\n")); if (reqinfo->asp == NULL || reqinfo->asp->pdu == NULL || reqinfo->asp->pdu->community_len == 0) { return 0; } *configured = strdup("-c"); DEBUGMSGTL(("proxy", "pdu has community string\n")); session->community_len = reqinfo->asp->pdu->community_len; session->community = malloc(session->community_len + 1); sprintf((char *)session->community, "%.*s", (int) session->community_len, (const char *)reqinfo->asp->pdu->community); } } #endif return 1; } /* * Free any specially configured parameters used on the session. */ void proxy_free_filled_in_session_args(netsnmp_session *session, void **configured) { /* Only do comparisions, etc., if something was configured */ if (*configured == NULL) { return; } /* If used community string from pdu, release it from session now */ if (strcmp((const char *)(*configured), "-c") == 0) { free(session->community); session->community = NULL; session->community_len = 0; } free((u_char *)(*configured)); *configured = NULL; } void init_proxy(void) { snmpd_register_config_handler("proxy", proxy_parse_config, proxy_free_config, "[snmpcmd args] host oid [remoteoid]"); } void shutdown_proxy(void) { proxy_free_config(); } int proxy_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_pdu *pdu; struct simple_proxy *sp; oid *ourname; size_t ourlength; netsnmp_request_info *request = requests; u_char *configured = NULL; DEBUGMSGTL(("proxy", "proxy handler starting, mode = %d\n", reqinfo->mode)); switch (reqinfo->mode) { case MODE_GET: case MODE_GETNEXT: case MODE_GETBULK: /* WWWXXX */ pdu = snmp_pdu_create(reqinfo->mode); break; #ifndef NETSNMP_NO_WRITE_SUPPORT case MODE_SET_ACTION: pdu = snmp_pdu_create(SNMP_MSG_SET); break; case MODE_SET_UNDO: /* * If we set successfully (status == NOERROR), * we can't back out again, so need to report the fact. * If we failed to set successfully, then we're fine. */ for (request = requests; request; request=request->next) { if (request->status == SNMP_ERR_NOERROR) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_UNDOFAILED); return SNMP_ERR_UNDOFAILED; } } return SNMP_ERR_NOERROR; case MODE_SET_RESERVE1: case MODE_SET_RESERVE2: case MODE_SET_FREE: case MODE_SET_COMMIT: /* * Nothing to do in this pass */ return SNMP_ERR_NOERROR; #endif /* !NETSNMP_NO_WRITE_SUPPORT */ default: snmp_log(LOG_WARNING, "unsupported mode for proxy called (%d)\n", reqinfo->mode); return SNMP_ERR_NOERROR; } sp = (struct simple_proxy *) handler->myvoid; if (!pdu || !sp) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR); if (pdu) snmp_free_pdu(pdu); return SNMP_ERR_NOERROR; } while (request) { ourname = request->requestvb->name; ourlength = request->requestvb->name_length; if (sp->base_len && reqinfo->mode == MODE_GETNEXT && (snmp_oid_compare(ourname, ourlength, sp->name, sp->name_len) < 0)) { DEBUGMSGTL(( "proxy", "request is out of registered range\n")); /* * Create GETNEXT request with an OID so the * master returns the first OID in the registered range. */ memcpy(ourname, sp->base, sp->base_len * sizeof(oid)); ourlength = sp->base_len; if (ourname[ourlength-1] <= 1) { /* * The registered range ends with x.y.z.1 * -> ask for the next of x.y.z */ ourlength--; } else { /* * The registered range ends with x.y.z.A * -> ask for the next of x.y.z.A-1.MAX_SUBID */ ourname[ourlength-1]--; ourname[ourlength] = MAX_SUBID; ourlength++; } } else if (sp->base_len > 0) { if ((ourlength - sp->name_len + sp->base_len) > MAX_OID_LEN) { /* * too large */ if (pdu) snmp_free_pdu(pdu); snmp_log(LOG_ERR, "proxy oid request length is too long\n"); return SNMP_ERR_NOERROR; } /* * suffix appended? */ DEBUGMSGTL(("proxy", "length=%d, base_len=%d, name_len=%d\n", (int)ourlength, (int)sp->base_len, (int)sp->name_len)); if (ourlength > sp->name_len) memcpy(&(sp->base[sp->base_len]), &(ourname[sp->name_len]), sizeof(oid) * (ourlength - sp->name_len)); ourlength = ourlength - sp->name_len + sp->base_len; ourname = sp->base; } snmp_pdu_add_variable(pdu, ourname, ourlength, request->requestvb->type, request->requestvb->val.string, request->requestvb->val_len); request->delegated = 1; request = request->next; } /* * Customize session parameters based on request information */ if (!proxy_fill_in_session(handler, reqinfo, (void **)&configured)) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR); if (pdu) snmp_free_pdu(pdu); return SNMP_ERR_NOERROR; } /* * send the request out */ DEBUGMSGTL(("proxy", "sending pdu\n")); snmp_async_send(sp->sess, pdu, proxy_got_response, netsnmp_create_delegated_cache(handler, reginfo, reqinfo, requests, (void *) sp)); /* Free any special parameters generated on the session */ proxy_free_filled_in_session_args(sp->sess, (void **)&configured); return SNMP_ERR_NOERROR; }
static int binary_search(const void *val, netsnmp_container *c, int exact) { binary_array_table *t = (binary_array_table*)c->container_data; size_t len = t->count; size_t half; size_t middle = 0; size_t first = 0; int result = 0; if (!len) return -1; if (c->flags & CONTAINER_KEY_UNSORTED) { if (!exact) { snmp_log(LOG_ERR, "non-exact search on unsorted container %s?!?\n", c->container_name); return -1; } return linear_search(val, c); } while (len > 0) { half = len >> 1; middle = first; middle += half; if ((result = c->compare(t->data[middle], val)) < 0) { first = middle; ++first; len = len - half - 1; } else { if(result == 0) { first = middle; break; } len = half; } } if (first >= t->count) return -1; if(first != middle) { /* last compare wasn't against first, so get actual result */ result = c->compare(t->data[first], val); } if(result == 0) { if (!exact) { if (++first == t->count) first = -1; } } else { if(exact) first = -1; } return first; }
int proxy_got_response(int operation, netsnmp_session * sess, int reqid, netsnmp_pdu *pdu, void *cb_data) { netsnmp_delegated_cache *cache = (netsnmp_delegated_cache *) cb_data; netsnmp_request_info *requests, *request = NULL; netsnmp_variable_list *vars, *var = NULL; struct simple_proxy *sp; oid myname[MAX_OID_LEN]; size_t myname_len = MAX_OID_LEN; cache = netsnmp_handler_check_cache(cache); if (!cache) { DEBUGMSGTL(("proxy", "a proxy request was no longer valid.\n")); return SNMP_ERR_NOERROR; } requests = cache->requests; sp = (struct simple_proxy *) cache->localinfo; if (!sp) { DEBUGMSGTL(("proxy", "a proxy request was no longer valid.\n")); return SNMP_ERR_NOERROR; } switch (operation) { case NETSNMP_CALLBACK_OP_TIMED_OUT: /* * WWWXXX: don't leave requests delayed if operation is * something like TIMEOUT */ DEBUGMSGTL(("proxy", "got timed out... requests = %8p\n", requests)); netsnmp_handler_mark_requests_as_delegated(requests, REQUEST_IS_NOT_DELEGATED); if(cache->reqinfo->mode != MODE_GETNEXT) { DEBUGMSGTL(("proxy", " ignoring timeout\n")); netsnmp_set_request_error(cache->reqinfo, requests, /* XXXWWW: should be index = 0 */ SNMP_ERR_GENERR); } netsnmp_free_delegated_cache(cache); return 0; case NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE: vars = pdu->variables; if (pdu->errstat != SNMP_ERR_NOERROR) { /* * If we receive an error from the proxy agent, pass it on up. * The higher-level processing seems to Do The Right Thing. * * 2005/06 rks: actually, it doesn't do the right thing for * a get-next request that returns NOSUCHNAME. If we do nothing, * it passes that error back to the comman initiator. What it should * do is ignore the error and move on to the next tree. To * accomplish that, all we need to do is clear the delegated flag. * Not sure if any other error codes need the same treatment. Left * as an exercise to the reader... */ DEBUGMSGTL(("proxy", "got error response (%ld)\n", pdu->errstat)); if((cache->reqinfo->mode == MODE_GETNEXT) && (SNMP_ERR_NOSUCHNAME == pdu->errstat)) { DEBUGMSGTL(("proxy", " ignoring error response\n")); netsnmp_handler_mark_requests_as_delegated(requests, REQUEST_IS_NOT_DELEGATED); } #ifndef NETSNMP_NO_WRITE_SUPPORT else if (cache->reqinfo->mode == MODE_SET_ACTION) { /* * In order for netsnmp_wrap_up_request to consider the * SET request complete, * there must be no delegated requests pending. * https://sourceforge.net/tracker/ * ?func=detail&atid=112694&aid=1554261&group_id=12694 */ DEBUGMSGTL(("proxy", "got SET error %s, index %ld\n", snmp_errstring(pdu->errstat), pdu->errindex)); netsnmp_handler_mark_requests_as_delegated( requests, REQUEST_IS_NOT_DELEGATED); netsnmp_request_set_error_idx(requests, pdu->errstat, pdu->errindex); } #endif /* !NETSNMP_NO_WRITE_SUPPORT */ else { netsnmp_handler_mark_requests_as_delegated( requests, REQUEST_IS_NOT_DELEGATED); netsnmp_request_set_error_idx(requests, pdu->errstat, pdu->errindex); } /* * update the original request varbinds with the results */ } else for (var = vars, request = requests; request && var; request = request->next, var = var->next_variable) { /* * XXX - should this be done here? * Or wait until we know it's OK? */ snmp_set_var_typed_value(request->requestvb, var->type, var->val.string, var->val_len); DEBUGMSGTL(("proxy", "got response... ")); DEBUGMSGOID(("proxy", var->name, var->name_length)); DEBUGMSG(("proxy", "\n")); request->delegated = 0; /* * Check the response oid is legitimate, * and discard the value if not. * * XXX - what's the difference between these cases? */ if (sp->base_len && (var->name_length < sp->base_len || snmp_oid_compare(var->name, sp->base_len, sp->base, sp->base_len) != 0)) { DEBUGMSGTL(( "proxy", "out of registered range... ")); DEBUGMSGOID(("proxy", var->name, sp->base_len)); DEBUGMSG(( "proxy", " (%d) != ", (int)sp->base_len)); DEBUGMSGOID(("proxy", sp->base, sp->base_len)); DEBUGMSG(( "proxy", "\n")); snmp_set_var_typed_value(request->requestvb, ASN_NULL, NULL, 0); continue; } else if (!sp->base_len && (var->name_length < sp->name_len || snmp_oid_compare(var->name, sp->name_len, sp->name, sp->name_len) != 0)) { DEBUGMSGTL(( "proxy", "out of registered base range... ")); DEBUGMSGOID(("proxy", var->name, sp->name_len)); DEBUGMSG(( "proxy", " (%d) != ", (int)sp->name_len)); DEBUGMSGOID(("proxy", sp->name, sp->name_len)); DEBUGMSG(( "proxy", "\n")); snmp_set_var_typed_value(request->requestvb, ASN_NULL, NULL, 0); continue; } else { /* * If the returned OID is legitimate, then update * the original request varbind accordingly. */ if (sp->base_len) { /* * XXX: oid size maxed? */ memcpy(myname, sp->name, sizeof(oid) * sp->name_len); myname_len = sp->name_len + var->name_length - sp->base_len; if (myname_len > MAX_OID_LEN) { snmp_log(LOG_WARNING, "proxy OID return length too long.\n"); netsnmp_set_request_error(cache->reqinfo, requests, SNMP_ERR_GENERR); if (pdu) snmp_free_pdu(pdu); netsnmp_free_delegated_cache(cache); return 1; } if (var->name_length > sp->base_len) memcpy(&myname[sp->name_len], &var->name[sp->base_len], sizeof(oid) * (var->name_length - sp->base_len)); snmp_set_var_objid(request->requestvb, myname, myname_len); } else { snmp_set_var_objid(request->requestvb, var->name, var->name_length); } } } if (request || var) { /* * ack, this is bad. The # of varbinds don't match and * there is no way to fix the problem */ if (pdu) snmp_free_pdu(pdu); snmp_log(LOG_ERR, "response to proxy request illegal. We're screwed.\n"); netsnmp_set_request_error(cache->reqinfo, requests, SNMP_ERR_GENERR); } /* fix bulk_to_next operations */ if (cache->reqinfo->mode == MODE_GETBULK) netsnmp_bulk_to_next_fix_requests(requests); /* * free the response */ if (pdu && 0) snmp_free_pdu(pdu); break; default: DEBUGMSGTL(("proxy", "no response received: op = %d\n", operation)); break; } netsnmp_free_delegated_cache(cache); return 1; }
int tcp_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_variable_list *requestvb; long ret_value = -1; oid subid; int type = ASN_COUNTER; /* * The cached data should already have been loaded by the * cache handler, higher up the handler chain. * But just to be safe, check this and load it manually if necessary */ #if defined(_USE_FIRST_PROTOCOL) tcp_load(NULL, NULL); #endif /* * * */ DEBUGMSGTL(("mibII/tcpScalar", "Handler - mode %s\n", se_find_label_in_slist("agent_mode", reqinfo->mode))); switch (reqinfo->mode) { case MODE_GET: for (request=requests; request; request=request->next) { requestvb = request->requestvb; subid = requestvb->name[OID_LENGTH(tcp_oid)]; /* XXX */ DEBUGMSGTL(( "mibII/tcpScalar", "oid: ")); DEBUGMSGOID(("mibII/tcpScalar", requestvb->name, requestvb->name_length)); DEBUGMSG(( "mibII/tcpScalar", "\n")); switch (subid) { #ifdef USES_SNMP_DESIGNED_TCPSTAT case TCPRTOALGORITHM: ret_value = tcpstat.tcpRtoAlgorithm; type = ASN_INTEGER; break; case TCPRTOMIN: ret_value = tcpstat.tcpRtoMin; type = ASN_INTEGER; break; case TCPRTOMAX: ret_value = tcpstat.tcpRtoMax; type = ASN_INTEGER; break; case TCPMAXCONN: ret_value = tcpstat.tcpMaxConn; type = ASN_INTEGER; break; case TCPACTIVEOPENS: ret_value = tcpstat.tcpActiveOpens; break; case TCPPASSIVEOPENS: ret_value = tcpstat.tcpPassiveOpens; break; case TCPATTEMPTFAILS: ret_value = tcpstat.tcpAttemptFails; break; case TCPESTABRESETS: ret_value = tcpstat.tcpEstabResets; break; case TCPCURRESTAB: ret_value = tcpstat.tcpCurrEstab; type = ASN_GAUGE; break; case TCPINSEGS: ret_value = tcpstat.tcpInSegs & 0xffffffff; break; case TCPOUTSEGS: ret_value = tcpstat.tcpOutSegs & 0xffffffff; break; case TCPRETRANSSEGS: ret_value = tcpstat.tcpRetransSegs; break; case TCPINERRS: #ifdef solaris2 ret_value = tcp_load(NULL, (void *)TCPINERRS); if (ret_value == -1) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); continue; } break; #elif defined(linux) if (tcpstat.tcpInErrsValid) { ret_value = tcpstat.tcpInErrs; break; } else { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); continue; } #else /* linux */ netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); continue; #endif /* solaris2 */ case TCPOUTRSTS: #ifdef linux if (tcpstat.tcpOutRstsValid) { ret_value = tcpstat.tcpOutRsts; break; } #endif /* linux */ netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); continue; #elif defined(USES_TRADITIONAL_TCPSTAT) && !defined(_USE_FIRST_PROTOCOL) #ifdef HAVE_SYS_TCPIPSTATS_H /* * This actually reads statistics for *all* the groups together, * so we need to isolate the TCP-specific bits. */ #define tcpstat tcpstat.tcpstat #endif case TCPRTOALGORITHM: /* Assume Van Jacobsen's algorithm */ ret_value = 4; type = ASN_INTEGER; break; case TCPRTOMIN: #ifdef TCPTV_NEEDS_HZ ret_value = TCPTV_MIN; #else ret_value = TCPTV_MIN / PR_SLOWHZ * 1000; #endif type = ASN_INTEGER; break; case TCPRTOMAX: #ifdef TCPTV_NEEDS_HZ ret_value = TCPTV_REXMTMAX; #else ret_value = TCPTV_REXMTMAX / PR_SLOWHZ * 1000; #endif type = ASN_INTEGER; break; case TCPMAXCONN: ret_value = -1; /* Dynamic maximum */ type = ASN_INTEGER; break; case TCPACTIVEOPENS: ret_value = tcpstat.tcps_connattempt; break; case TCPPASSIVEOPENS: ret_value = tcpstat.tcps_accepts; break; /* * NB: tcps_drops is actually the sum of the two MIB * counters tcpAttemptFails and tcpEstabResets. */ case TCPATTEMPTFAILS: ret_value = tcpstat.tcps_conndrops; break; case TCPESTABRESETS: ret_value = tcpstat.tcps_drops; break; case TCPCURRESTAB: #ifdef NETSNMP_FEATURE_CHECKING netsnmp_feature_want(tcp_count_connections) #endif #ifndef NETSNMP_FEATURE_REMOVE_TCP_COUNT_CONNECTIONS ret_value = TCP_Count_Connections(); #else ret_value = 0; #endif /* NETSNMP_FEATURE_REMOVE_TCP_COUNT_CONNECTIONS */ type = ASN_GAUGE; break; case TCPINSEGS: ret_value = tcpstat.tcps_rcvtotal & 0xffffffff; break; case TCPOUTSEGS: /* * RFC 1213 defines this as the number of segments sent * "excluding those containing only retransmitted octets" */ ret_value = (tcpstat.tcps_sndtotal - tcpstat.tcps_sndrexmitpack) & 0xffffffff; break; case TCPRETRANSSEGS: ret_value = tcpstat.tcps_sndrexmitpack; break; case TCPINERRS: ret_value = tcpstat.tcps_rcvbadsum + tcpstat.tcps_rcvbadoff #ifdef HAVE_STRUCT_TCPSTAT_TCPS_RCVMEMDROP + tcpstat.tcps_rcvmemdrop #endif + tcpstat.tcps_rcvshort; break; case TCPOUTRSTS: ret_value = tcpstat.tcps_sndctrl - tcpstat.tcps_closed; break; #ifdef HAVE_SYS_TCPIPSTATS_H #undef tcpstat #endif #elif defined(hpux11) case TCPRTOALGORITHM: case TCPRTOMIN: case TCPRTOMAX: case TCPMAXCONN: case TCPCURRESTAB: if (subid == TCPCURRESTAB) type = ASN_GAUGE; else type = ASN_INTEGER; case TCPACTIVEOPENS: case TCPPASSIVEOPENS: case TCPATTEMPTFAILS: case TCPESTABRESETS: case TCPINSEGS: case TCPOUTSEGS: case TCPRETRANSSEGS: case TCPINERRS: case TCPOUTRSTS: /* * This is a bit of a hack, to shoehorn the HP-UX 11 * single-object retrieval approach into the caching * architecture. */ if (tcp_load(NULL, (void*)subid) == -1 ) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); continue; } ret_value = tcpstat; break; #elif defined (WIN32) || defined (cygwin) case TCPRTOALGORITHM: ret_value = tcpstat.dwRtoAlgorithm; type = ASN_INTEGER; break; case TCPRTOMIN: ret_value = tcpstat.dwRtoMin; type = ASN_INTEGER; break; case TCPRTOMAX: ret_value = tcpstat.dwRtoMax; type = ASN_INTEGER; break; case TCPMAXCONN: ret_value = tcpstat.dwMaxConn; type = ASN_INTEGER; break; case TCPACTIVEOPENS: ret_value = tcpstat.dwActiveOpens; break; case TCPPASSIVEOPENS: ret_value = tcpstat.dwPassiveOpens; break; case TCPATTEMPTFAILS: ret_value = tcpstat.dwAttemptFails; break; case TCPESTABRESETS: ret_value = tcpstat.dwEstabResets; break; case TCPCURRESTAB: ret_value = tcpstat.dwCurrEstab; type = ASN_GAUGE; break; case TCPINSEGS: ret_value = tcpstat.dwInSegs; break; case TCPOUTSEGS: ret_value = tcpstat.dwOutSegs; break; case TCPRETRANSSEGS: ret_value = tcpstat.dwRetransSegs; break; case TCPINERRS: ret_value = tcpstat.dwInErrs; break; case TCPOUTRSTS: ret_value = tcpstat.dwOutRsts; break; #elif defined(_USE_FIRST_PROTOCOL) case TCPRTOALGORITHM: ret_value = 4; type = ASN_INTEGER; break; case TCPRTOMIN: ret_value = 0; type = ASN_INTEGER; break; case TCPRTOMAX: ret_value = 0; type = ASN_INTEGER; break; case TCPMAXCONN: ret_value = -1; type = ASN_INTEGER; break; case TCPACTIVEOPENS: ret_value = ps_proto.u.tcp.initiated; break; case TCPPASSIVEOPENS: ret_value = ps_proto.u.tcp.accepted; break; case TCPATTEMPTFAILS: ret_value = ps_proto.u.tcp.dropped; break; case TCPESTABRESETS: ret_value = ps_proto.u.tcp.dropped; break; case TCPCURRESTAB: /* this value is currently missing */ ret_value = 0; /*ps_proto.u.tcp.established;*/ type = ASN_GAUGE; break; case TCPINSEGS: ret_value = ps_proto.u.tcp.ipackets; break; case TCPOUTSEGS: ret_value = ps_proto.u.tcp.opackets; break; case TCPRETRANSSEGS: ret_value = 0; break; case TCPINERRS: ret_value = ps_proto.u.tcp.ierrors; break; case TCPOUTRSTS: ret_value = 0; break; #endif /* USES_SNMP_DESIGNED_TCPSTAT */ case TCPCONNTABLE: /* * This is not actually a valid scalar object. * The table registration should take precedence, * so skip this subtree, regardless of architecture. */ netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); continue; } snmp_set_var_typed_value(request->requestvb, (u_char)type, (u_char *)&ret_value, sizeof(ret_value)); } break; case MODE_GETNEXT: case MODE_GETBULK: #ifndef NETSNMP_NO_WRITE_SUPPORT case MODE_SET_RESERVE1: case MODE_SET_RESERVE2: case MODE_SET_ACTION: case MODE_SET_COMMIT: case MODE_SET_FREE: case MODE_SET_UNDO: snmp_log(LOG_WARNING, "mibII/tcp: Unsupported mode (%d)\n", reqinfo->mode); break; #endif /* !NETSNMP_NO_WRITE_SUPPORT */ default: snmp_log(LOG_WARNING, "mibII/tcp: Unrecognised mode (%d)\n", reqinfo->mode); break; } return SNMP_ERR_NOERROR; }
int main(int argc, char *argv[]) { netsnmp_session session, *ss; netsnmp_pdu *pdu = NULL, *response = NULL; int arg; size_t name_length = USM_OID_LEN; size_t name_length2 = USM_OID_LEN; int status; int exitval = 0; int rval; int command = 0; long longvar; size_t oldKu_len = SNMP_MAXBUF_SMALL, newKu_len = SNMP_MAXBUF_SMALL, oldkul_len = SNMP_MAXBUF_SMALL, oldkulpriv_len = SNMP_MAXBUF_SMALL, newkulpriv_len = SNMP_MAXBUF_SMALL, newkul_len = SNMP_MAXBUF_SMALL, keychange_len = SNMP_MAXBUF_SMALL, keychangepriv_len = SNMP_MAXBUF_SMALL; char *newpass = NULL, *oldpass = NULL; u_char oldKu[SNMP_MAXBUF_SMALL], newKu[SNMP_MAXBUF_SMALL], oldkul[SNMP_MAXBUF_SMALL], oldkulpriv[SNMP_MAXBUF_SMALL], newkulpriv[SNMP_MAXBUF_SMALL], newkul[SNMP_MAXBUF_SMALL], keychange[SNMP_MAXBUF_SMALL], keychangepriv[SNMP_MAXBUF_SMALL]; authKeyChange = authKeyOid; privKeyChange = privKeyOid; /* * get the common command line arguments */ switch (arg = snmp_parse_args(argc, argv, &session, "C:", optProc)) { case -2: exit(0); case -1: usage(); exit(1); default: break; } if (arg >= argc) { fprintf(stderr, "Please specify an operation to perform.\n"); usage(); exit(1); } SOCK_STARTUP; /* * open an SNMP session */ /* * Note: this needs to obtain the engineID used below */ session.flags &= ~SNMP_FLAGS_DONT_PROBE; ss = snmp_open(&session); if (ss == NULL) { /* * diagnose snmp_open errors with the input netsnmp_session pointer */ snmp_sess_perror("snmpusm", &session); exit(1); } /* * set usmUserEngineID from ss->contextEngineID * if not already set (via -CE) */ if (usmUserEngineID == NULL) { usmUserEngineID = ss->contextEngineID; usmUserEngineIDLen = ss->contextEngineIDLen; } /* * create PDU for SET request and add object names and values to request */ pdu = snmp_pdu_create(SNMP_MSG_SET); if (!pdu) { fprintf(stderr, "Failed to create request\n"); exit(1); } if (strcmp(argv[arg], CMD_PASSWD_NAME) == 0) { /* * passwd: change a users password. * * XXX: Uses the auth type of the calling user, a MD5 user can't * change a SHA user's key. */ char *passwd_user; command = CMD_PASSWD; oldpass = argv[++arg]; newpass = argv[++arg]; passwd_user = argv[++arg]; if (doprivkey == 0 && doauthkey == 0) doprivkey = doauthkey = 1; if (newpass == NULL || strlen(newpass) < USM_LENGTH_P_MIN) { fprintf(stderr, "New passphrase must be greater than %d characters in length.\n", USM_LENGTH_P_MIN); exit(1); } if (oldpass == NULL || strlen(oldpass) < USM_LENGTH_P_MIN) { fprintf(stderr, "Old passphrase must be greater than %d characters in length.\n", USM_LENGTH_P_MIN); exit(1); } /* * Change the user supplied on command line. */ if ((passwd_user != NULL) && (strlen(passwd_user) > 0)) { session.securityName = passwd_user; } else { /* * Use own key object if no user was supplied. */ authKeyChange = ownAuthKeyOid; privKeyChange = ownPrivKeyOid; } /* * do we have a securityName? If not, copy the default */ if (session.securityName == NULL) { session.securityName = strdup(netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_SECNAME)); } /* * the old Ku is in the session, but we need the new one */ if (session.securityAuthProto == NULL) { /* * get .conf set default */ const oid *def = get_default_authtype(&session.securityAuthProtoLen); session.securityAuthProto = snmp_duplicate_objid(def, session.securityAuthProtoLen); } if (session.securityAuthProto == NULL) { /* * assume MD5 */ #ifndef NETSNMP_DISABLE_MD5 session.securityAuthProtoLen = sizeof(usmHMACMD5AuthProtocol) / sizeof(oid); session.securityAuthProto = snmp_duplicate_objid(usmHMACMD5AuthProtocol, session.securityAuthProtoLen); #else session.securityAuthProtoLen = sizeof(usmHMACSHA1AuthProtocol) / sizeof(oid); session.securityAuthProto = snmp_duplicate_objid(usmHMACSHA1AuthProtocol, session.securityAuthProtoLen); #endif } if (uselocalizedkey && (strncmp(oldpass, "0x", 2) == 0)) { /* * use the localized key from the command line */ u_char *buf; size_t buf_len = SNMP_MAXBUF_SMALL; buf = (u_char *) malloc (buf_len * sizeof(u_char)); oldkul_len = 0; /* initialize the offset */ if (!snmp_hex_to_binary((u_char **) (&buf), &buf_len, &oldkul_len, 0, oldpass)) { snmp_perror(argv[0]); fprintf(stderr, "generating the old Kul from localized key failed\n"); exit(1); } memcpy(oldkul, buf, oldkul_len); SNMP_FREE(buf); } else { /* * the old Ku is in the session, but we need the new one */ rval = generate_Ku(session.securityAuthProto, session.securityAuthProtoLen, (u_char *) oldpass, strlen(oldpass), oldKu, &oldKu_len); if (rval != SNMPERR_SUCCESS) { snmp_perror(argv[0]); fprintf(stderr, "generating the old Ku failed\n"); exit(1); } /* * generate the two Kul's */ rval = generate_kul(session.securityAuthProto, session.securityAuthProtoLen, usmUserEngineID, usmUserEngineIDLen, oldKu, oldKu_len, oldkul, &oldkul_len); if (rval != SNMPERR_SUCCESS) { snmp_perror(argv[0]); fprintf(stderr, "generating the old Kul failed\n"); exit(1); } } if (uselocalizedkey && (strncmp(newpass, "0x", 2) == 0)) { /* * use the localized key from the command line */ u_char *buf; size_t buf_len = SNMP_MAXBUF_SMALL; buf = (u_char *) malloc (buf_len * sizeof(u_char)); newkul_len = 0; /* initialize the offset */ if (!snmp_hex_to_binary((u_char **) (&buf), &buf_len, &newkul_len, 0, newpass)) { snmp_perror(argv[0]); fprintf(stderr, "generating the new Kul from localized key failed\n"); exit(1); } memcpy(newkul, buf, newkul_len); SNMP_FREE(buf); } else { rval = generate_Ku(session.securityAuthProto, session.securityAuthProtoLen, (u_char *) newpass, strlen(newpass), newKu, &newKu_len); if (rval != SNMPERR_SUCCESS) { snmp_perror(argv[0]); fprintf(stderr, "generating the new Ku failed\n"); exit(1); } rval = generate_kul(session.securityAuthProto, session.securityAuthProtoLen, usmUserEngineID, usmUserEngineIDLen, newKu, newKu_len, newkul, &newkul_len); if (rval != SNMPERR_SUCCESS) { snmp_perror(argv[0]); fprintf(stderr, "generating the new Kul failed\n"); exit(1); } } /* * for encryption, we may need to truncate the key to the proper length * so we need two copies. For simplicity, we always just copy even if * they're the same lengths. */ if (doprivkey) { if (!session.securityPrivProto) { snmp_log(LOG_ERR, "no encryption type specified, which I need in order to know to change the key\n"); exit(1); } #ifndef NETSNMP_DISABLE_DES if (ISTRANSFORM(session.securityPrivProto, DESPriv)) { /* DES uses a 128 bit key, 64 bits of which is a salt */ oldkulpriv_len = newkulpriv_len = 16; } #endif #ifdef HAVE_AES if (ISTRANSFORM(session.securityPrivProto, AESPriv)) { oldkulpriv_len = newkulpriv_len = 16; } #endif memcpy(oldkulpriv, oldkul, oldkulpriv_len); memcpy(newkulpriv, newkul, newkulpriv_len); } /* * create the keychange string */ if (doauthkey) { rval = encode_keychange(session.securityAuthProto, session.securityAuthProtoLen, oldkul, oldkul_len, newkul, newkul_len, keychange, &keychange_len); if (rval != SNMPERR_SUCCESS) { snmp_perror(argv[0]); fprintf(stderr, "encoding the keychange failed\n"); usage(); exit(1); } } /* which is slightly different for encryption if lengths are different */ if (doprivkey) { rval = encode_keychange(session.securityAuthProto, session.securityAuthProtoLen, oldkulpriv, oldkulpriv_len, newkulpriv, newkulpriv_len, keychangepriv, &keychangepriv_len); if (rval != SNMPERR_SUCCESS) { snmp_perror(argv[0]); fprintf(stderr, "encoding the keychange failed\n"); usage(); exit(1); } } /* * add the keychange string to the outgoing packet */ if (doauthkey) { setup_oid(authKeyChange, &name_length, usmUserEngineID, usmUserEngineIDLen, session.securityName); snmp_pdu_add_variable(pdu, authKeyChange, name_length, ASN_OCTET_STR, keychange, keychange_len); } if (doprivkey) { setup_oid(privKeyChange, &name_length2, usmUserEngineID, usmUserEngineIDLen, session.securityName); snmp_pdu_add_variable(pdu, privKeyChange, name_length2, ASN_OCTET_STR, keychangepriv, keychangepriv_len); } } else if (strcmp(argv[arg], CMD_CREATE_NAME) == 0) { /* * create: create a user * * create USER [CLONEFROM] */ if (++arg >= argc) { fprintf(stderr, "You must specify the user name to create\n"); usage(); exit(1); } command = CMD_CREATE; if (++arg < argc) { /* * clone the new user from an existing user * (and make them active immediately) */ setup_oid(usmUserStatus, &name_length, usmUserEngineID, usmUserEngineIDLen, argv[arg-1]); longvar = RS_CREATEANDGO; snmp_pdu_add_variable(pdu, usmUserStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof(longvar)); name_length = USM_OID_LEN; setup_oid(usmUserCloneFrom, &name_length, usmUserEngineID, usmUserEngineIDLen, argv[arg - 1]); setup_oid(usmUserSecurityName, &name_length2, usmUserEngineID, usmUserEngineIDLen, argv[arg]); snmp_pdu_add_variable(pdu, usmUserCloneFrom, name_length, ASN_OBJECT_ID, (u_char *) usmUserSecurityName, sizeof(oid) * name_length2); } else { /* * create a new (unauthenticated) user from scratch * The Net-SNMP agent won't allow such a user to be made active. */ setup_oid(usmUserStatus, &name_length, usmUserEngineID, usmUserEngineIDLen, argv[arg-1]); longvar = RS_CREATEANDWAIT; snmp_pdu_add_variable(pdu, usmUserStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof(longvar)); } } else if (strcmp(argv[arg], CMD_CLONEFROM_NAME) == 0) { /* * create: clone a user from another * * cloneFrom USER FROM */ if (++arg >= argc) { fprintf(stderr, "You must specify the user name to operate on\n"); usage(); exit(1); } command = CMD_CLONEFROM; setup_oid(usmUserStatus, &name_length, usmUserEngineID, usmUserEngineIDLen, argv[arg]); longvar = RS_ACTIVE; snmp_pdu_add_variable(pdu, usmUserStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof(longvar)); name_length = USM_OID_LEN; setup_oid(usmUserCloneFrom, &name_length, usmUserEngineID, usmUserEngineIDLen, argv[arg]); if (++arg >= argc) { fprintf(stderr, "You must specify the user name to clone from\n"); usage(); exit(1); } setup_oid(usmUserSecurityName, &name_length2, usmUserEngineID, usmUserEngineIDLen, argv[arg]); snmp_pdu_add_variable(pdu, usmUserCloneFrom, name_length, ASN_OBJECT_ID, (u_char *) usmUserSecurityName, sizeof(oid) * name_length2); } else if (strcmp(argv[arg], CMD_DELETE_NAME) == 0) { /* * delete: delete a user * * delete USER */ if (++arg >= argc) { fprintf(stderr, "You must specify the user name to delete\n"); exit(1); } command = CMD_DELETE; setup_oid(usmUserStatus, &name_length, usmUserEngineID, usmUserEngineIDLen, argv[arg]); longvar = RS_DESTROY; snmp_pdu_add_variable(pdu, usmUserStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof(longvar)); } else if (strcmp(argv[arg], CMD_ACTIVATE_NAME) == 0) { /* * activate: activate a user * * activate USER */ if (++arg >= argc) { fprintf(stderr, "You must specify the user name to activate\n"); exit(1); } command = CMD_ACTIVATE; setup_oid(usmUserStatus, &name_length, usmUserEngineID, usmUserEngineIDLen, argv[arg]); longvar = RS_ACTIVE; snmp_pdu_add_variable(pdu, usmUserStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof(longvar)); } else if (strcmp(argv[arg], CMD_DEACTIVATE_NAME) == 0) { /* * deactivate: deactivate a user * * deactivate USER */ if (++arg >= argc) { fprintf(stderr, "You must specify the user name to deactivate\n"); exit(1); } command = CMD_DEACTIVATE; setup_oid(usmUserStatus, &name_length, usmUserEngineID, usmUserEngineIDLen, argv[arg]); longvar = RS_NOTINSERVICE; snmp_pdu_add_variable(pdu, usmUserStatus, name_length, ASN_INTEGER, (u_char *) & longvar, sizeof(longvar)); #if defined(HAVE_OPENSSL_DH_H) && defined(HAVE_LIBCRYPTO) } else if (strcmp(argv[arg], CMD_CHANGEKEY_NAME) == 0) { /* * change the key of a user if DH is available */ char *passwd_user; netsnmp_pdu *dhpdu, *dhresponse = NULL; netsnmp_variable_list *vars, *dhvar; command = CMD_CHANGEKEY; name_length = DH_USM_OID_LEN; name_length2 = DH_USM_OID_LEN; passwd_user = argv[++arg]; if (doprivkey == 0 && doauthkey == 0) doprivkey = doauthkey = 1; /* * Change the user supplied on command line. */ if ((passwd_user != NULL) && (strlen(passwd_user) > 0)) { session.securityName = passwd_user; } else { /* * Use own key object if no user was supplied. */ dhauthKeyChange = usmDHUserOwnAuthKeyChange; dhprivKeyChange = usmDHUserOwnPrivKeyChange; } /* * do we have a securityName? If not, copy the default */ if (session.securityName == NULL) { session.securityName = strdup(netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_SECNAME)); } /* fetch the needed diffie helman parameters */ dhpdu = snmp_pdu_create(SNMP_MSG_GET); if (!dhpdu) { fprintf(stderr, "Failed to create DH request\n"); exit(1); } /* get the current DH parameters */ snmp_add_null_var(dhpdu, usmDHParameters, usmDHParameters_len); /* maybe the auth key public value */ if (doauthkey) { setup_oid(dhauthKeyChange, &name_length, usmUserEngineID, usmUserEngineIDLen, session.securityName); snmp_add_null_var(dhpdu, dhauthKeyChange, name_length); } /* maybe the priv key public value */ if (doprivkey) { setup_oid(dhprivKeyChange, &name_length2, usmUserEngineID, usmUserEngineIDLen, session.securityName); snmp_add_null_var(dhpdu, dhprivKeyChange, name_length2); } /* fetch the values */ status = snmp_synch_response(ss, dhpdu, &dhresponse); if (status != SNMPERR_SUCCESS || dhresponse == NULL || dhresponse->errstat != SNMP_ERR_NOERROR || dhresponse->variables->type != ASN_OCTET_STR) { snmp_sess_perror("snmpusm", ss); if (dhresponse && dhresponse->variables && dhresponse->variables->type != ASN_OCTET_STR) { fprintf(stderr, "Can't get diffie-helman exchange from the agent\n"); fprintf(stderr, " (maybe it doesn't support the SNMP-USM-DH-OBJECTS-MIB MIB)\n"); } exitval = 1; goto begone; } dhvar = dhresponse->variables; vars = dhvar->next_variable; /* complete the DH equation & print resulting keys */ if (doauthkey) { if (get_USM_DH_key(vars, dhvar, sc_get_properlength(ss->securityAuthProto, ss->securityAuthProtoLen), pdu, "auth", dhauthKeyChange, name_length) != SNMPERR_SUCCESS) goto begone; vars = vars->next_variable; } if (doprivkey) { size_t dhprivKeyLen = 0; #ifndef NETSNMP_DISABLE_DES if (ISTRANSFORM(ss->securityPrivProto, DESPriv)) { /* DES uses a 128 bit key, 64 bits of which is a salt */ dhprivKeyLen = 16; } #endif #ifdef HAVE_AES if (ISTRANSFORM(ss->securityPrivProto, AESPriv)) { dhprivKeyLen = 16; } #endif if (get_USM_DH_key(vars, dhvar, dhprivKeyLen, pdu, "priv", dhprivKeyChange, name_length2) != SNMPERR_SUCCESS) goto begone; vars = vars->next_variable; } /* snmp_free_pdu(dhresponse); */ /* parts still in use somewhere */ #endif /* HAVE_OPENSSL_DH_H */ } else { fprintf(stderr, "Unknown command\n"); usage(); exit(1); } /* * add usmUserPublic if specified (via -Cp) */ if (usmUserPublic_val) { name_length = USM_OID_LEN; setup_oid(usmUserPublic, &name_length, usmUserEngineID, usmUserEngineIDLen, session.securityName); snmp_pdu_add_variable(pdu, usmUserPublic, name_length, ASN_OCTET_STR, usmUserPublic_val, strlen(usmUserPublic_val)); } /* * do the request */ status = snmp_synch_response(ss, pdu, &response); if (status == STAT_SUCCESS) { if (response) { if (response->errstat == SNMP_ERR_NOERROR) { fprintf(stdout, "%s\n", successNotes[command - 1]); } else { fprintf(stderr, "Error in packet.\nReason: %s\n", snmp_errstring(response->errstat)); if (response->errindex != 0) { int count; netsnmp_variable_list *vars; fprintf(stderr, "Failed object: "); for (count = 1, vars = response->variables; vars && count != response->errindex; vars = vars->next_variable, count++) /*EMPTY*/; if (vars) fprint_objid(stderr, vars->name, vars->name_length); fprintf(stderr, "\n"); } exitval = 2; } } } else if (status == STAT_TIMEOUT) { fprintf(stderr, "Timeout: No Response from %s\n", session.peername); exitval = 1; } else { /* status == STAT_ERROR */ snmp_sess_perror("snmpset", ss); exitval = 1; } begone: if (response) snmp_free_pdu(response); snmp_close(ss); SOCK_CLEANUP; return exitval; }
int netsnmp_instance_helper_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_variable_list *var = requests->requestvb; int ret, cmp; DEBUGMSGTL(("helper:instance", "Got request:\n")); cmp = snmp_oid_compare(requests->requestvb->name, requests->requestvb->name_length, reginfo->rootoid, reginfo->rootoid_len); DEBUGMSGTL(("helper:instance", " oid:")); DEBUGMSGOID(("helper:instance", var->name, var->name_length)); DEBUGMSG(("helper:instance", "\n")); switch (reqinfo->mode) { case MODE_GET: if (cmp != 0) { netsnmp_set_request_error(reqinfo, requests, SNMP_NOSUCHINSTANCE); return SNMP_ERR_NOERROR; } else { return netsnmp_call_next_handler(handler, reginfo, reqinfo, requests); } break; #ifndef NETSNMP_NO_WRITE_SUPPORT case MODE_SET_RESERVE1: case MODE_SET_RESERVE2: case MODE_SET_ACTION: case MODE_SET_COMMIT: case MODE_SET_UNDO: case MODE_SET_FREE: if (cmp != 0) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_NOCREATION); return SNMP_ERR_NOERROR; } else { return netsnmp_call_next_handler(handler, reginfo, reqinfo, requests); } break; #endif /* NETSNMP_NO_WRITE_SUPPORT */ case MODE_GETNEXT: if (cmp < 0 || (cmp == 0 && requests->inclusive)) { reqinfo->mode = MODE_GET; snmp_set_var_objid(requests->requestvb, reginfo->rootoid, reginfo->rootoid_len); ret = netsnmp_call_next_handler(handler, reginfo, reqinfo, requests); reqinfo->mode = MODE_GETNEXT; /* * if the instance doesn't have data, set type to ASN_NULL * to move to the next sub-tree. Ignore delegated requests; they * might have data later on. */ if (!requests->delegated && (requests->requestvb->type == SNMP_NOSUCHINSTANCE || requests->requestvb->type == SNMP_NOSUCHOBJECT)) { requests->requestvb->type = ASN_NULL; } return ret; } else { return SNMP_ERR_NOERROR; } break; default: snmp_log(LOG_ERR, "netsnmp_instance_helper_handler: illegal mode\n"); netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR); return SNMP_ERR_NOERROR; } /* * got here only if illegal mode found */ return SNMP_ERR_GENERR; }
/** * @internal * Initialize the table ipv4InterfaceTable * (Define its contents and how it's structured) */ void _ipv4InterfaceTable_initialize_interface(ipv4InterfaceTable_registration * reg_ptr, u_long flags) { netsnmp_baby_steps_access_methods *access_multiplexer = &ipv4InterfaceTable_if_ctx.access_multiplexer; netsnmp_table_registration_info *tbl_info = &ipv4InterfaceTable_if_ctx.tbl_info; netsnmp_handler_registration *reginfo; netsnmp_mib_handler *handler; int mfd_modes = 0; DEBUGMSGTL(("internal:ipv4InterfaceTable:_ipv4InterfaceTable_initialize_interface", "called\n")); /************************************************* * * save interface context for ipv4InterfaceTable */ /* * Setting up the table's definition */ netsnmp_table_helper_add_indexes(tbl_info, ASN_INTEGER, /** index: ipv4InterfaceIfIndex */ 0); /* * Define the minimum and maximum accessible columns. This * optimizes retrieval. */ tbl_info->min_column = IPV4INTERFACETABLE_MIN_COL; tbl_info->max_column = IPV4INTERFACETABLE_MAX_COL; /* * save users context */ ipv4InterfaceTable_if_ctx.user_ctx = reg_ptr; /* * call data access initialization code */ ipv4InterfaceTable_init_data(reg_ptr); /* * set up the container */ _ipv4InterfaceTable_container_init(&ipv4InterfaceTable_if_ctx); if (NULL == ipv4InterfaceTable_if_ctx.container) { snmp_log(LOG_ERR, "could not initialize container for ipv4InterfaceTable\n"); return; } /* * access_multiplexer: REQUIRED wrapper for get request handling */ access_multiplexer->object_lookup = _mfd_ipv4InterfaceTable_object_lookup; access_multiplexer->get_values = _mfd_ipv4InterfaceTable_get_values; /* * no wrappers yet */ access_multiplexer->pre_request = _mfd_ipv4InterfaceTable_pre_request; access_multiplexer->post_request = _mfd_ipv4InterfaceTable_post_request; #ifndef NETSNMP_DISABLE_SET_SUPPORT /* * REQUIRED wrappers for set request handling */ access_multiplexer->object_syntax_checks = _mfd_ipv4InterfaceTable_check_objects; access_multiplexer->undo_setup = _mfd_ipv4InterfaceTable_undo_setup; access_multiplexer->undo_cleanup = _mfd_ipv4InterfaceTable_undo_cleanup; access_multiplexer->set_values = _mfd_ipv4InterfaceTable_set_values; access_multiplexer->undo_sets = _mfd_ipv4InterfaceTable_undo_values; /* * no wrappers yet */ access_multiplexer->commit = _mfd_ipv4InterfaceTable_commit; access_multiplexer->undo_commit = _mfd_ipv4InterfaceTable_undo_commit; access_multiplexer->irreversible_commit = _mfd_ipv4InterfaceTable_irreversible_commit; #endif /************************************************* * * Create a registration, save our reg data, register table. */ DEBUGMSGTL(("ipv4InterfaceTable:init_ipv4InterfaceTable", "Registering ipv4InterfaceTable as a mibs-for-dummies table.\n")); handler = netsnmp_baby_steps_access_multiplexer_get(access_multiplexer); reginfo = netsnmp_handler_registration_create("ipv4InterfaceTable", handler, ipv4InterfaceTable_oid, ipv4InterfaceTable_oid_size, HANDLER_CAN_BABY_STEP #ifndef NETSNMP_DISABLE_SET_SUPPORT | HANDLER_CAN_RWRITE #endif ); if (NULL == reginfo) { snmp_log(LOG_ERR, "error registering table ipv4InterfaceTable\n"); return; } reginfo->my_reg_void = &ipv4InterfaceTable_if_ctx; /************************************************* * * set up baby steps handler, create it and inject it */ if (access_multiplexer->object_lookup) mfd_modes |= BABY_STEP_OBJECT_LOOKUP; if (access_multiplexer->pre_request) mfd_modes |= BABY_STEP_PRE_REQUEST; if (access_multiplexer->post_request) mfd_modes |= BABY_STEP_POST_REQUEST; #ifndef NETSNMP_DISABLE_SET_SUPPORT if (access_multiplexer->set_values) mfd_modes |= BABY_STEP_SET_VALUES; if (access_multiplexer->irreversible_commit) mfd_modes |= BABY_STEP_IRREVERSIBLE_COMMIT; if (access_multiplexer->object_syntax_checks) mfd_modes |= BABY_STEP_CHECK_OBJECT; if (access_multiplexer->undo_setup) mfd_modes |= BABY_STEP_UNDO_SETUP; if (access_multiplexer->undo_cleanup) mfd_modes |= BABY_STEP_UNDO_CLEANUP; if (access_multiplexer->undo_sets) mfd_modes |= BABY_STEP_UNDO_SETS; if (access_multiplexer->row_creation) mfd_modes |= BABY_STEP_ROW_CREATE; if (access_multiplexer->consistency_checks) mfd_modes |= BABY_STEP_CHECK_CONSISTENCY; if (access_multiplexer->commit) mfd_modes |= BABY_STEP_COMMIT; if (access_multiplexer->undo_commit) mfd_modes |= BABY_STEP_UNDO_COMMIT; #endif handler = netsnmp_baby_steps_handler_get(mfd_modes); netsnmp_inject_handler(reginfo, handler); /************************************************* * * inject row_merge helper with prefix rootoid_len + 2 (entry.col) */ handler = netsnmp_get_row_merge_handler(reginfo->rootoid_len + 2); netsnmp_inject_handler(reginfo, handler); /************************************************* * * inject container_table helper */ handler = netsnmp_container_table_handler_get(tbl_info, ipv4InterfaceTable_if_ctx. container, TABLE_CONTAINER_KEY_NETSNMP_INDEX); netsnmp_inject_handler(reginfo, handler); /* * register table */ netsnmp_register_table(reginfo, tbl_info); /* * register LastChanged */ { oid lc_oid[] = { IPV4INTERFACETABLELASTCHANGE_OID }; netsnmp_register_watched_scalar2(netsnmp_create_handler_registration ("ipv4TableLastChanged", NULL, lc_oid, OID_LENGTH(lc_oid), HANDLER_CAN_RONLY), netsnmp_create_watcher_info((void *) &ipv4InterfaceTable_if_ctx. last_changed, sizeof (u_long), ASN_TIMETICKS, WATCHER_FIXED_SIZE)); } } /* _ipv4InterfaceTable_initialize_interface */