📄 table_data.c
字号:
#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_data.h>#include <net-snmp/agent/read_only.h>#if HAVE_DMALLOC_H#include <dmalloc.h>#endif/** @defgroup table_data table_data: Helps you implement a table with datamatted storage. * @ingroup table * * This helper helps you implement a table where all the indexes are * expected to be stored within the agent itself and not in some * external storage location. It can be used to store a list of * rows, where a row consists of the indexes to the table and a * generic data pointer. You can then implement a subhandler which * is passed the exact row definition and data it must return data * for or accept data for. Complex GETNEXT handling is greatly * simplified in this case. * * @{ *//** * generates the index portion of an table oid from a varlist. */voidnetsnmp_table_data_generate_index_oid(netsnmp_table_row *row){ build_oid(&row->index_oid, &row->index_oid_len, NULL, 0, row->indexes);}/** * Adds a row of data to a given table (stored in proper lexographical order). * * returns SNMPERR_SUCCESS on successful addition. * or SNMPERR_GENERR on failure (E.G., indexes already existed) */intnetsnmp_table_data_add_row(netsnmp_table_data *table, netsnmp_table_row *row){ int rc, dup = 0; netsnmp_table_row *nextrow = NULL, *prevrow; if (!row || !table) return SNMPERR_GENERR; if (row->indexes) netsnmp_table_data_generate_index_oid(row); /* * we don't store the index info as it * takes up memory. */ if (!table->store_indexes) { snmp_free_varbind(row->indexes); row->indexes = NULL; } if (!row->index_oid) { snmp_log(LOG_ERR, "illegal data attempted to be added to table %s (no index)\n", table->name); return SNMPERR_GENERR; } /* * check for simple append */ if ((prevrow = table->last_row) != NULL) { rc = snmp_oid_compare(prevrow->index_oid, prevrow->index_oid_len, row->index_oid, row->index_oid_len); if (0 == rc) dup = 1; } else rc = 1; /* * if no last row, or newrow < last row, search the table and * insert it into the table in the proper oid-lexographical order */ if (rc > 0) { for (nextrow = table->first_row, prevrow = NULL; nextrow != NULL; prevrow = nextrow, nextrow = nextrow->next) { if (NULL == nextrow->index_oid) { DEBUGMSGT(("table_data_add_data", "row doesn't have index!\n")); /** xxx-rks: remove invalid row? */ continue; } rc = snmp_oid_compare(nextrow->index_oid, nextrow->index_oid_len, row->index_oid, row->index_oid_len); if(rc > 0) break; if (0 == rc) { dup = 1; break; } } } if (dup) { /* * exact match. Duplicate entries illegal */ snmp_log(LOG_WARNING, "duplicate table data attempted to be entered. row exists\n"); return SNMPERR_GENERR; } /* * ok, we have the location of where it should go */ /* * (after prevrow, and before nextrow) */ row->next = nextrow; row->prev = prevrow; if (row->next) row->next->prev = row; if (row->prev) row->prev->next = row; if (NULL == row->prev) /* it's the (new) first row */ table->first_row = row; if (NULL == row->next) /* it's the last row */ table->last_row = row; DEBUGMSGTL(("table_data_add_data", "added something...\n")); return SNMPERR_SUCCESS;}/** * removes a row of data to a given table and returns it (no free's called) * * returns the row pointer itself on successful removing. * or NULL on failure (bad arguments) */netsnmp_table_row *netsnmp_table_data_remove_row(netsnmp_table_data *table, netsnmp_table_row *row){ if (!row || !table) return NULL; if (row->prev) row->prev->next = row->next; else table->first_row = row->next; if (row->next) row->next->prev = row->prev; else table->last_row = row->prev; return row;}/** deletes a row's memory. * returns the void data that it doesn't know how to delete. */void *netsnmp_table_data_delete_row(netsnmp_table_row *row){ void *data; if (!row) return NULL; /* * free the memory we can */ if (row->indexes) snmp_free_varbind(row->indexes); SNMP_FREE(row->index_oid); data = row->data; free(row); /* * return the void * pointer */ return data;}/** * removes and frees a row of data to a given table and returns the void * * * returns the void * data on successful deletion. * or NULL on failure (bad arguments) */void *netsnmp_table_data_remove_and_delete_row(netsnmp_table_data *table, netsnmp_table_row *row){ if (!row || !table) return NULL; /* * remove it from the list */ netsnmp_table_data_remove_row(table, row); return netsnmp_table_data_delete_row(row);}/** swaps out origrow with newrow. This does *not* delete/free anything! */NETSNMP_INLINE voidnetsnmp_table_data_replace_row(netsnmp_table_data *table, netsnmp_table_row *origrow, netsnmp_table_row *newrow){ netsnmp_table_data_remove_row(table, origrow); netsnmp_table_data_add_row(table, newrow);}/** finds the data in "datalist" stored at "indexes" */netsnmp_table_row *netsnmp_table_data_get(netsnmp_table_data *table, netsnmp_variable_list * indexes){ oid searchfor[MAX_OID_LEN]; size_t searchfor_len = MAX_OID_LEN; build_oid_noalloc(searchfor, MAX_OID_LEN, &searchfor_len, NULL, 0, indexes); return netsnmp_table_data_get_from_oid(table, searchfor, searchfor_len);}/** finds the data in "datalist" stored at the searchfor oid */netsnmp_table_row *netsnmp_table_data_get_from_oid(netsnmp_table_data *table, oid * searchfor, size_t searchfor_len){ netsnmp_table_row *row; if (!table) return NULL; for (row = table->first_row; row != NULL; row = row->next) { if (row->index_oid && snmp_oid_compare(searchfor, searchfor_len, row->index_oid, row->index_oid_len) == 0) return row; } return NULL;}/** Creates a table_data handler and returns it */netsnmp_mib_handler *netsnmp_get_table_data_handler(netsnmp_table_data *table){ netsnmp_mib_handler *ret = NULL; if (!table) { snmp_log(LOG_INFO, "netsnmp_get_table_data_handler(NULL) called\n"); return NULL; } ret = netsnmp_create_handler(TABLE_DATA_NAME, netsnmp_table_data_helper_handler); if (ret) { ret->flags |= MIB_HANDLER_AUTO_NEXT; ret->myvoid = (void *) table; } return ret;}/** registers a handler as a data table. * If table_info != NULL, it registers it as a normal table too. */intnetsnmp_register_table_data(netsnmp_handler_registration *reginfo, netsnmp_table_data *table, netsnmp_table_registration_info *table_info){ netsnmp_inject_handler(reginfo, netsnmp_get_table_data_handler(table)); return netsnmp_register_table(reginfo, table_info);}/** registers a handler as a read-only data table * If table_info != NULL, it registers it as a normal table too. */intnetsnmp_register_read_only_table_data(netsnmp_handler_registration *reginfo, netsnmp_table_data *table, netsnmp_table_registration_info *table_info){ netsnmp_inject_handler(reginfo, netsnmp_get_read_only_handler()); return netsnmp_register_table_data(reginfo, table, table_info);}/** * The helper handler that takes care of passing a specific row of * data down to the lower handler(s). It sets request->processed if * the request should not be handled. */intnetsnmp_table_data_helper_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests){ netsnmp_table_data *table = (netsnmp_table_data *) handler->myvoid; netsnmp_request_info *request; int valid_request = 0; netsnmp_table_row *row; netsnmp_table_request_info *table_info; netsnmp_table_registration_info *table_reg_info = netsnmp_find_table_registration_info(reginfo); int result, regresult; int oldmode; for (request = requests; request; request = request->next) { if (request->processed) continue; table_info = netsnmp_extract_table_info(request); if (!table_info) continue; /* ack */ switch (reqinfo->mode) { case MODE_GET: case MODE_GETNEXT: case MODE_SET_RESERVE1: netsnmp_request_add_list_data(request, netsnmp_create_data_list( TABLE_DATA_TABLE, table, NULL)); } /* * find the row in question */ switch (reqinfo->mode) { case MODE_GETNEXT: case MODE_GETBULK: /* XXXWWW */ if (request->requestvb->type != ASN_NULL) continue; /* * loop through data till we find the next row */ result = snmp_oid_compare(request->requestvb->name, request->requestvb->name_length, reginfo->rootoid, reginfo->rootoid_len); regresult = snmp_oid_compare(request->requestvb->name, SNMP_MIN(request->requestvb-> name_length, reginfo->rootoid_len), reginfo->rootoid, reginfo->rootoid_len); if (regresult == 0 && request->requestvb->name_length < reginfo->rootoid_len)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -