📄 table_data.c
字号:
if (old_row->indexes) new_row->indexes = snmp_clone_varbind(old_row->indexes); if (old_row->index_oid) memdup((u_char **) & new_row->index_oid, (u_char *) old_row->index_oid, old_row->index_oid_len * sizeof(oid)); /* XXX - Doesn't copy table-specific row structure */ return 0;} /* * netsnmp_table_data_delete_row() * netsnmp_table_data_add_row() * netsnmp_table_data_replace_row() * netsnmp_table_data_remove_row() * all defined above */void *netsnmp_table_data_remove_delete_row(netsnmp_table_data *table, netsnmp_table_row *row){ return netsnmp_table_data_remove_and_delete_row(table, row);}/* ================================== * * Table Data API: MIB maintenance * * ================================== *//** 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) regresult = -1; if (result < 0 || 0 == result) { /* * before us entirely, return the first */ row = table->first_row; table_info->colnum = table_reg_info->min_column; } else if (regresult == 0 && request->requestvb->name_length == reginfo->rootoid_len + 1 && /* entry node must be 1, but any column is ok */ request->requestvb->name[reginfo->rootoid_len] == 1) { /* * exactly to the entry */ row = table->first_row; table_info->colnum = table_reg_info->min_column; } else if (regresult == 0 && request->requestvb->name_length == reginfo->rootoid_len + 2 && /* entry node must be 1, but any column is ok */ request->requestvb->name[reginfo->rootoid_len] == 1) { /* * exactly to the column */ row = table->first_row; } else { /* * loop through all rows looking for the first one * that is equal to the request or greater than it */ for (row = table->first_row; row; row = row->next) { /* * compare the index of the request to the row */ result = snmp_oid_compare(row->index_oid, row->index_oid_len, request->requestvb->name + 2 + reginfo->rootoid_len, request->requestvb->name_length - 2 - reginfo->rootoid_len); if (result == 0) { /* * equal match, return the next row */ if (row) { row = row->next; } break; } else if (result > 0) { /* * the current row is greater than the * request, use it */ break; } } } if (!row) { table_info->colnum++; if (table_info->colnum <= table_reg_info->max_column) { row = table->first_row; } } if (row) { valid_request = 1; netsnmp_request_add_list_data(request, netsnmp_create_data_list (TABLE_DATA_ROW, row, NULL)); /* * Set the name appropriately, so we can pass this * request on as a simple GET request */ netsnmp_table_data_build_result(reginfo, reqinfo, request, row, table_info->colnum, ASN_NULL, NULL, 0); } else { /* no decent result found. Give up. It's beyond us. */ request->processed = 1; } break; case MODE_GET: if (request->requestvb->type != ASN_NULL) continue; /* * find the row in question */ if (request->requestvb->name_length < (reginfo->rootoid_len + 3)) { /* table.entry.column... */ /* * request too short */ netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); break; } else if (NULL == (row = netsnmp_table_data_get_from_oid(table, request-> requestvb->name + reginfo-> rootoid_len + 2, request-> requestvb-> name_length - reginfo-> rootoid_len - 2))) { /* * no such row */ netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); break; } else { valid_request = 1; netsnmp_request_add_list_data(request, netsnmp_create_data_list (TABLE_DATA_ROW, row, NULL)); } break; case MODE_SET_RESERVE1: valid_request = 1; if (NULL != (row = netsnmp_table_data_get_from_oid(table, request->requestvb->name + reginfo->rootoid_len + 2, request->requestvb-> name_length - reginfo->rootoid_len - 2))) { netsnmp_request_add_list_data(request, netsnmp_create_data_list (TABLE_DATA_ROW, row, NULL)); } break; case MODE_SET_RESERVE2: case MODE_SET_ACTION: case MODE_SET_COMMIT: case MODE_SET_FREE: case MODE_SET_UNDO: valid_request = 1; } } if (valid_request && (reqinfo->mode == MODE_GETNEXT || reqinfo->mode == MODE_GETBULK)) { /* * If this is a GetNext or GetBulk request, then we've identified * the row that ought to include the appropriate next instance. * Convert the request into a Get request, so that the lower-level * handlers don't need to worry about skipping on, and call these * handlers ourselves (so we can undo this again afterwards). */ oldmode = reqinfo->mode; reqinfo->mode = MODE_GET; result = netsnmp_call_next_handler(handler, reginfo, reqinfo, requests); reqinfo->mode = oldmode; handler->flags |= MIB_HANDLER_AUTO_NEXT_OVERRIDE_ONCE; return result; } else /* next handler called automatically - 'AUTO_NEXT' */ return SNMP_ERR_NOERROR;}/** extracts the table being accessed passed from the table_data helper */netsnmp_table_data *netsnmp_extract_table(netsnmp_request_info *request){ return (netsnmp_table_data *) netsnmp_request_get_list_data(request, TABLE_DATA_TABLE);}/** extracts the row being accessed passed from the table_data helper */netsnmp_table_row *netsnmp_extract_table_row(netsnmp_request_info *request){ return (netsnmp_table_row *) netsnmp_request_get_list_data(request, TABLE_DATA_ROW);}/** extracts the data from the row being accessed passed from the * table_data helper */void *netsnmp_extract_table_row_data(netsnmp_request_info *request){ netsnmp_table_row *row; row = (netsnmp_table_row *) netsnmp_extract_table_row(request); if (row) return row->data; else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -