📄 table_container.c
字号:
/* * table_container.c * $Id: table_container.c 14169 2006-01-25 16:28:12Z dts12 $ */#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>/* * 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 key 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);static void *_find_next_row(netsnmp_container *c, netsnmp_table_request_info *tblreq, void * key);/********************************************************************** ********************************************************************** * * * * * PUBLIC Registration functions * * * * * ********************************************************************** **********************************************************************//* ================================== * * Container Table API: Table maintenance * * ================================== */container_table_data *netsnmp_tcontainer_create_table( const char *name, netsnmp_container *container, long flags ){ container_table_data *table; table = SNMP_MALLOC_TYPEDEF(container_table_data); if (!table) return NULL; if (container) table->table = container; else { table->table = netsnmp_container_find("table_container"); if (!table->table) { SNMP_FREE(table); return NULL; } } if (flags) table->key_type = flags & 0x03; /* Use lowest two bits */ else table->key_type = TABLE_CONTAINER_KEY_NETSNMP_INDEX; if (!table->table->compare) table->table->compare = netsnmp_compare_netsnmp_index; if (!table->table->ncompare) table->table->ncompare = netsnmp_ncompare_netsnmp_index; return table;}voidnetsnmp_tcontainer_delete_table( container_table_data *table ){ if (!table) return; if (table->table) CONTAINER_FREE(table->table); SNMP_FREE(table); return;} /* * The various standalone row operation routines * (create/clone/copy/delete) * will be specific to a particular table, * so can't be implemented here. */intnetsnmp_tcontainer_add_row( container_table_data *table, netsnmp_index *row ){ if (!table || !table->table || !row) return -1; CONTAINER_INSERT( table->table, row ); return 0;}netsnmp_index *netsnmp_tcontainer_remove_row( container_table_data *table, netsnmp_index *row ){ if (!table || !table->table || !row) return NULL; CONTAINER_REMOVE( table->table, row ); return NULL;}intnetsnmp_tcontainer_replace_row( container_table_data *table, netsnmp_index *old_row, netsnmp_index *new_row ){ if (!table || !table->table || !old_row || !new_row) return -1; netsnmp_tcontainer_remove_row( table, old_row ); netsnmp_tcontainer_add_row( table, new_row ); return 0;} /* netsnmp_tcontainer_remove_delete_row() will be table-specific too *//* ================================== * * Container Table API: MIB maintenance * * ================================== *//** returns a netsnmp_mib_handler object for the table_container helper */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);}/** 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);}#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);}/** find the context data used by the table_container helper */void *netsnmp_container_table_extract_context(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 *//** 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -