📄 table_container.c
字号:
/** * deprecated, backwards compatability only * * expected impact to remove: none * - used between helpers, shouldn't have been used by end users * * replacement: none * - never should have been a public method in the first place */netsnmp_index *netsnmp_table_index_find_next_row(netsnmp_container *c, netsnmp_table_request_info *tblreq){ return _find_next_row(c, tblreq, NULL );}NETSNMP_STATIC_INLINE void_data_lookup(netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *agtreq_info, netsnmp_request_info *request, container_table_data * tad){ netsnmp_index *row = NULL; netsnmp_table_request_info *tblreq_info; netsnmp_variable_list *var; netsnmp_index index; void *key; var = request->requestvb; DEBUGIF("table_container") { DEBUGMSGTL(("table_container", " data_lookup oid:")); DEBUGMSGOID(("table_container", var->name, var->name_length)); DEBUGMSG(("table_container", "\n")); } /* * Get pointer to the table information for this request. This * information was saved by table_helper_handler. */ tblreq_info = netsnmp_extract_table_info(request); /** the table_helper_handler should enforce column boundaries. */ netsnmp_assert((NULL != tblreq_info) && (tblreq_info->colnum <= tad->tblreg_info->max_column)); if ((agtreq_info->mode == MODE_GETNEXT) || (agtreq_info->mode == MODE_GETBULK)) { /* * find the row. This will automatically move to the next * column, if necessary. */ _set_key( tad, request, tblreq_info, &key, &index ); row = _find_next_row(tad->table, tblreq_info, key); if (row) { /* * update indexes in tblreq_info (index & varbind), * then update request varbind oid */ if(TABLE_CONTAINER_KEY_NETSNMP_INDEX == tad->key_type) { tblreq_info->index_oid_len = row->len; memcpy(tblreq_info->index_oid, row->oids, row->len * sizeof(oid)); netsnmp_update_variable_list_from_index(tblreq_info); } else if (TABLE_CONTAINER_KEY_VARBIND_INDEX == tad->key_type) { netsnmp_update_indexes_from_variable_list(tblreq_info); } if (TABLE_CONTAINER_KEY_VARBIND_RAW != tad->key_type) { netsnmp_table_build_oid_from_index(reginfo, request, tblreq_info); } } else { /* * no results found. Flag the request so lower handlers will * ignore it, but it is not an error - getnext will move * on to another handler to process this request. */ netsnmp_set_request_error(agtreq_info, request, SNMP_ENDOFMIBVIEW); DEBUGMSGTL(("table_container", "no row found\n")); } } /** GETNEXT/GETBULK */ else { _set_key( tad, request, tblreq_info, &key, &index ); row = CONTAINER_FIND(tad->table, key); if (NULL == row) { /* * not results found. For a get, that is an error */ DEBUGMSGTL(("table_container", "no row found\n")); if((agtreq_info->mode != MODE_SET_RESERVE1) || /* get */ (reginfo->modes & HANDLER_CAN_NOT_CREATE)) { /* no create */ netsnmp_set_request_error(agtreq_info, request, SNMP_NOSUCHINSTANCE); } } } /** GET/SET */ /* * save the data and table in the request. */ if (SNMP_ENDOFMIBVIEW != request->status) { if (NULL != row) netsnmp_request_add_list_data(request, netsnmp_create_data_list (TABLE_CONTAINER_ROW, row, NULL)); netsnmp_request_add_list_data(request, netsnmp_create_data_list (TABLE_CONTAINER_CONTAINER, tad->table, NULL)); }}/********************************************************************** ********************************************************************** * * * * * netsnmp_table_container_helper_handler() * * * * * ********************************************************************** **********************************************************************/static int_container_table_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *agtreq_info, netsnmp_request_info *requests){ int rc = SNMP_ERR_NOERROR; int oldmode, need_processing = 0; container_table_data *tad; /** sanity checks */ netsnmp_assert((NULL != handler) && (NULL != handler->myvoid)); netsnmp_assert((NULL != reginfo) && (NULL != agtreq_info)); DEBUGMSGTL(("table_container", "Mode %s, Got request:\n", se_find_label_in_slist("agent_mode",agtreq_info->mode))); /* * First off, get our pointer from the handler. This * lets us get to the table registration information we * saved in get_table_container_handler(), as well as the * container where the actual table data is stored. */ tad = (container_table_data *)handler->myvoid; /* * only do data lookup for first pass * * xxx-rks: this should really be handled up one level. we should * be able to say what modes we want to be called for during table * registration. */ oldmode = agtreq_info->mode; if(MODE_IS_GET(oldmode) || (MODE_SET_RESERVE1 == oldmode)) { netsnmp_request_info *curr_request; /* * Loop through each of the requests, and * try to find the appropriate row from the container. */ for (curr_request = requests; curr_request; curr_request = curr_request->next) { /* * skip anything that doesn't need processing. */ if (curr_request->processed != 0) { DEBUGMSGTL(("table_container", "already processed\n")); continue; } /* * find data for this request */ _data_lookup(reginfo, agtreq_info, curr_request, tad); if(curr_request->processed) continue; ++need_processing; } /** for ( ... requests ... ) */ } /* * send GET instead of GETNEXT to sub-handlers * xxx-rks: again, this should be handled further up. */ if ((oldmode == MODE_GETNEXT) && (handler->next)) { /* * tell agent handlder not to auto call next handler */ handler->flags |= MIB_HANDLER_AUTO_NEXT_OVERRIDE_ONCE; /* * if we found rows to process, pretend to be a get request * and call handler below us. */ if(need_processing > 0) { agtreq_info->mode = MODE_GET; rc = netsnmp_call_next_handler(handler, reginfo, agtreq_info, requests); if (rc != SNMP_ERR_NOERROR) { DEBUGMSGTL(("table_container", "next handler returned %d\n", rc)); } agtreq_info->mode = oldmode; /* restore saved mode */ } } return rc;}/** retrieve the container used by the table_container helper */netsnmp_container*netsnmp_container_table_container_extract(netsnmp_request_info *request){ return (netsnmp_container *) netsnmp_request_get_list_data(request, TABLE_CONTAINER_CONTAINER);}/** inserts a newly created table_container entry into a request list */voidnetsnmp_container_table_row_insert(netsnmp_request_info *request, netsnmp_index *row){ netsnmp_request_info *req; netsnmp_table_request_info *table_info = NULL; netsnmp_variable_list *this_index = NULL; netsnmp_variable_list *that_index = NULL; oid base_oid[] = {0, 0}; /* Make sure index OIDs are legal! */ oid this_oid[MAX_OID_LEN]; oid that_oid[MAX_OID_LEN]; size_t this_oid_len, that_oid_len; if (!request) return; /* * We'll add the new row information to any request * structure with the same index values as the request * passed in (which includes that one!). * * So construct an OID based on these index values. */ table_info = netsnmp_extract_table_info(request); this_index = table_info->indexes; build_oid_noalloc(this_oid, MAX_OID_LEN, &this_oid_len, base_oid, 2, this_index); /* * We need to look through the whole of the request list * (as received by the current handler), as there's no * guarantee that this routine will be called by the first * varbind that refers to this row. * In particular, a RowStatus controlled row creation * may easily occur later in the variable list. * * So first, we rewind to the head of the list.... */ for (req=request; req->prev; req=req->prev) ; /* * ... and then start looking for matching indexes * (by constructing OIDs from these index values) */ for (; req; req=req->next) { table_info = netsnmp_extract_table_info(req); that_index = table_info->indexes; build_oid_noalloc(that_oid, MAX_OID_LEN, &that_oid_len, base_oid, 2, that_index); /* * This request has the same index values, * so add the newly-created row information. */ if (snmp_oid_compare(this_oid, this_oid_len, that_oid, that_oid_len) == 0) { netsnmp_request_add_list_data(req, netsnmp_create_data_list(TABLE_CONTAINER_ROW, row, NULL)); } }}#ifndef NETSNMP_USE_INLINE/** find the context data used by the table_container helper */void *netsnmp_container_table_row_extract(netsnmp_request_info *request){ /* * NOTE: this function must match in table_container.c and table_container.h. * if you change one, change them both! */ return netsnmp_request_get_list_data(request, TABLE_CONTAINER_ROW);}#endif /* inline */#endif /** DOXYGEN_SHOULD_SKIP_THIS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -