📄 table_data.c
字号:
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;}/** creates and returns a pointer to table data set */netsnmp_table_data *netsnmp_create_table_data(const char *name){ netsnmp_table_data *table = SNMP_MALLOC_TYPEDEF(netsnmp_table_data); if (name && table) table->name = strdup(name); return table;}/** creates and returns a pointer to table data set */netsnmp_table_row *netsnmp_create_table_data_row(void){ netsnmp_table_row *row = SNMP_MALLOC_TYPEDEF(netsnmp_table_row); return row;}/** inserts a newly created table_data row into a request */NETSNMP_INLINE voidnetsnmp_insert_table_row(netsnmp_request_info *request, netsnmp_table_row *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_DATA_ROW, row, NULL)); } }}/** 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 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 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 return NULL;}/** builds a result given a row, a varbind to set and the data */intnetsnmp_table_data_build_result(netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *request, netsnmp_table_row *row, int column, u_char type, u_char * result_data, size_t result_data_len){ oid build_space[MAX_OID_LEN]; if (!reginfo || !reqinfo || !request) return SNMPERR_GENERR; if (reqinfo->mode == MODE_GETNEXT || reqinfo->mode == MODE_GETBULK) { /* * only need to do this for getnext type cases where oid is changing */ memcpy(build_space, reginfo->rootoid, /* registered oid */ reginfo->rootoid_len * sizeof(oid)); build_space[reginfo->rootoid_len] = 1; /* entry */ build_space[reginfo->rootoid_len + 1] = column; /* column */ memcpy(build_space + reginfo->rootoid_len + 2, /* index data */ row->index_oid, row->index_oid_len * sizeof(oid)); snmp_set_var_objid(request->requestvb, build_space, reginfo->rootoid_len + 2 + row->index_oid_len); } snmp_set_var_typed_value(request->requestvb, type, result_data, result_data_len); return SNMPERR_SUCCESS; /* WWWXXX: check for bounds */}/** clones a data row. DOES NOT CLONE THE CONTAINED DATA. */netsnmp_table_row *netsnmp_table_data_clone_row(netsnmp_table_row *row){ netsnmp_table_row *newrow = NULL; if (!row) return NULL; memdup((u_char **) & newrow, (u_char *) row, sizeof(netsnmp_table_row)); if (!newrow) return NULL; if (row->indexes) { newrow->indexes = snmp_clone_varbind(newrow->indexes); if (!newrow->indexes) return NULL; } if (row->index_oid) { memdup((u_char **) & newrow->index_oid, (u_char *) row->index_oid, row->index_oid_len * sizeof(oid)); if (!newrow->index_oid) return NULL; } return newrow;}intnetsnmp_table_data_num_rows(netsnmp_table_data *table){ int i=0; netsnmp_table_row *row; if (!table) return 0; for (row = table->first_row; row; row = row->next) { i++; } return i;}/* * @} */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -