📄 table_container.c
字号:
/* * table_container.c * $Id: table_container.c,v 1.13 2004/10/09 02:12:55 rstory Exp $ */#include <net-snmp/net-snmp-config.h>#if HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#include <net-snmp/net-snmp-includes.h>#include <net-snmp/agent/net-snmp-agent-includes.h>#include <net-snmp/agent/table.h>#include <net-snmp/agent/table_container.h>#include <net-snmp/library/container.h>#include <net-snmp/library/snmp_assert.h>#if HAVE_DMALLOC_H#include <dmalloc.h>#endif/* * snmp.h:#define SNMP_MSG_INTERNAL_SET_BEGIN -1 * snmp.h:#define SNMP_MSG_INTERNAL_SET_RESERVE1 0 * snmp.h:#define SNMP_MSG_INTERNAL_SET_RESERVE2 1 * snmp.h:#define SNMP_MSG_INTERNAL_SET_ACTION 2 * snmp.h:#define SNMP_MSG_INTERNAL_SET_COMMIT 3 * snmp.h:#define SNMP_MSG_INTERNAL_SET_FREE 4 * snmp.h:#define SNMP_MSG_INTERNAL_SET_UNDO 5 *//* * PRIVATE structure for holding important info for each table. */typedef struct container_table_data_s { /** registration info for the table */ netsnmp_table_registration_info *tblreg_info; /** container for the table rows */ netsnmp_container *table; /* * mutex_type lock; */ /* what type of key do we want? */ char key_type;} container_table_data;/** @defgroup table_container table_container: Helps you implement a table when data can be found via a netsnmp_container. * @ingroup table * * The table_container handler is used (automatically) in conjuntion * with the @link table table@endlink handler. * * This handler will use the index information provided by * the @link table @endlink handler to find the row needed to process * the request. * * The container must use one of 3 key types. It is the sub-handler's * responsibility to ensure that the container and key type match (unless * neither is specified, in which case a default will be used.) * * The current key types are: * * TABLE_CONTAINER_KEY_NETSNMP_INDEX * The container should do comparisons based on a key that may be cast * to a netsnmp index (netsnmp_index *). This index contains only the * index portion of the OID, not the entire OID. * * TABLE_CONTAINER_KEY_VARBIND_INDEX * The container should do comparisons based on a key that may be cast * to a netsnmp variable list (netsnmp_variable_list *). This variable * list will contain one varbind for each index component. * * TABLE_CONTAINER_KEY_VARBIND_RAW (NOTE: unimplemented) * While not yet implemented, future plans include passing the request * varbind with the full OID to a container. * * If a key type is not specified at registration time, the default ket type * of TABLE_CONTAINER_KEY_NETSNMP_INDEX will be used. If a container is * provided, or the handler name is aliased to a container type, the container * must use a netsnmp index. * * If no container is provided, a lookup will be made based on the * sub-handler's name, or if that isn't found, "table_container". The * table_container key type will be netsnmp_index. * * The container must, at a minimum, implement find and find_next. If a NULL * key is passed to the container, it must return the first item, if any. * All containers provided by net-snmp fulfil this requirement. * * This handler will only register to process 'data lookup' modes. In * traditional net-snmp modes, that is any GET-like mode (GET, GET-NEXT, * GET-BULK) or the first phase of a SET (RESERVE1). In the new baby-steps * mode, DATA_LOOKUP is it's own mode, and is a pre-cursor to other modes. * * When called, the handler will call the appropriate container method * with the appropriate key type. If a row was not found, the result depends * on the mode. * * GET Processing * An exact match must be found. If one is not, the error NOSUCHINSTANCE * is set. * * GET-NEXT / GET-BULK * If no row is found, the column number will be increased (using any * valid_columns structure that may have been provided), and the first row * will be retrieved. If no first row is found, the processed flag will be * set, so that the sub-handler can skip any processing related to the * request. The agent will notice this unsatisfied request, and attempt to * pass it to the next appropriate handler. * * SET * If the hander did not register with the HANDLER_CAN_NOT_CREATE flag * set in the registration modes, it is assumed that this is a row * creation request and a NULL row is added to the request's data list. * The sub-handler is responsbile for dealing with any row creation * contraints and inserting any newly created rows into the container * and the request's data list. * * If a row is found, it will be inserted into * the request's data list. The sub-handler may retrieve it by calling * netsnmp_container_table_extract_context(request); * * NOTE NOTE NOTE: * * This helper and it's API are still being tested and are subject to change. * * @{ */static int_container_table_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *agtreq_info, netsnmp_request_info *requests);/********************************************************************** ********************************************************************** * * * * * PUBLIC Registration functions * * * * * ********************************************************************** **********************************************************************//** register specified callbacks for the specified table/oid.*/netsnmp_mib_handler *netsnmp_container_table_handler_get(netsnmp_table_registration_info *tabreg, netsnmp_container *container, char key_type){ container_table_data *tad; netsnmp_mib_handler *handler; if (NULL == tabreg) { snmp_log(LOG_ERR, "bad param in netsnmp_container_table_register\n"); return NULL; } tad = SNMP_MALLOC_TYPEDEF(container_table_data); handler = netsnmp_create_handler("table_container", _container_table_handler); if((NULL == tad) || (NULL == handler)) { if(tad) free(tad); /* SNMP_FREE wasted on locals */ if(handler) free(handler); /* SNMP_FREE wasted on locals */ snmp_log(LOG_ERR, "malloc failure in netsnmp_container_table_register\n"); return NULL; } tad->tblreg_info = tabreg; /* we need it too, but it really is not ours */ if(key_type) tad->key_type = key_type; else tad->key_type = TABLE_CONTAINER_KEY_NETSNMP_INDEX; if(NULL == container) container = netsnmp_container_find("table_container"); tad->table = container; if (NULL==container->compare) container->compare = netsnmp_compare_netsnmp_index; if (NULL==container->ncompare) container->ncompare = netsnmp_ncompare_netsnmp_index; handler->myvoid = (void*)tad; handler->flags |= MIB_HANDLER_AUTO_NEXT; return handler;}intnetsnmp_container_table_register(netsnmp_handler_registration *reginfo, netsnmp_table_registration_info *tabreg, netsnmp_container *container, char key_type ){ netsnmp_mib_handler *handler; if ((NULL == reginfo) || (NULL == reginfo->handler) || (NULL == tabreg)) { snmp_log(LOG_ERR, "bad param in netsnmp_container_table_register\n"); return SNMPERR_GENERR; } if (NULL==container) container = netsnmp_container_find(reginfo->handlerName); handler = netsnmp_container_table_handler_get(tabreg, container, key_type); netsnmp_inject_handler(reginfo, handler ); return netsnmp_register_table(reginfo, tabreg);}/** @} */#ifndef DOXYGEN_SHOULD_SKIP_THIS/********************************************************************** ********************************************************************** * * * * * DATA LOOKUP functions * * * * * ********************************************************************** **********************************************************************/NETSNMP_STATIC_INLINE void_set_key( container_table_data * tad, netsnmp_request_info *request, netsnmp_table_request_info *tblreq_info, void **key, netsnmp_index *index ){ if (TABLE_CONTAINER_KEY_NETSNMP_INDEX == tad->key_type) { index->oids = tblreq_info->index_oid; index->len = tblreq_info->index_oid_len; *key = index; } else if (TABLE_CONTAINER_KEY_VARBIND_INDEX == tad->key_type) { *key = tblreq_info->indexes; }#if 0 else if (TABLE_CONTAINER_KEY_VARBIND_RAW == tad->key_type) { *key = request->requestvb; }#endif else *key = NULL;}static void *_find_next_row(netsnmp_container *c, netsnmp_table_request_info *tblreq, void * key){ void *row = NULL; if (!c || !tblreq || !tblreq->reg_info ) { snmp_log(LOG_ERR,"_find_next_row param error\n"); return NULL; } /* * table helper should have made sure we aren't below our minimum column */ netsnmp_assert(tblreq->colnum >= tblreq->reg_info->min_column); /* * if no indexes then use first row. */ if(tblreq->number_indexes == 0) { row = CONTAINER_FIRST(c); } else { if(NULL == key) { netsnmp_index index; index.oids = tblreq->index_oid; index.len = tblreq->index_oid_len; row = CONTAINER_NEXT(c, &index); } else row = CONTAINER_NEXT(c, key); /* * we don't have a row, but we might be at the end of a * column, so try the next column. */ if (NULL == row) { /* * don't set tblreq next_col unless we know there is one, * so we don't mess up table handler sparse table processing. */ oid next_col = netsnmp_table_next_column(tblreq); if (0 != next_col) { tblreq->colnum = next_col; row = CONTAINER_FIRST(c); } } } return row;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -