| /* |
| * Note: this file originally auto-generated by mib2c using |
| * : mib2c.iterate_access.conf,v 1.4 2003/07/01 00:15:11 hardaker Exp $ |
| */ |
| |
| #include <net-snmp/net-snmp-config.h> |
| #include <net-snmp/net-snmp-features.h> |
| #include <net-snmp/net-snmp-includes.h> |
| #include <net-snmp/agent/net-snmp-agent-includes.h> |
| #include "netSnmpHostsTable.h" |
| #include "netSnmpHostsTable_checkfns.h" |
| #include "netSnmpHostsTable_access.h" |
| |
| netsnmp_feature_require(oid_stash) |
| netsnmp_feature_require(oid_stash_get_data) |
| netsnmp_feature_require(oid_stash_add_data) |
| |
| static netsnmp_oid_stash_node *undoStorage = NULL; |
| static netsnmp_oid_stash_node *commitStorage = NULL; |
| |
| struct undoInfo { |
| void *ptr; |
| size_t len; |
| }; |
| |
| struct commitInfo { |
| void *data_context; |
| int have_committed; |
| int new_row; |
| }; |
| |
| void |
| netSnmpHostsTable_free_undoInfo(void *vptr) |
| { |
| struct undoInfo *ui = vptr; |
| if (!ui) |
| return; |
| SNMP_FREE(ui->ptr); |
| SNMP_FREE(ui); |
| } |
| |
| /** Initialize the netSnmpHostsTable table by defining its contents and how it's structured */ |
| void |
| initialize_table_netSnmpHostsTable(void) |
| { |
| static oid netSnmpHostsTable_oid[] = |
| { 1, 3, 6, 1, 4, 1, 8072, 2, 2, 2 }; |
| netsnmp_table_registration_info *table_info; |
| netsnmp_handler_registration *my_handler; |
| netsnmp_iterator_info *iinfo; |
| |
| /** create the table registration information structures */ |
| table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); |
| iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); |
| |
| /** if your table is read only, it's easiest to change the |
| HANDLER_CAN_RWRITE definition below to HANDLER_CAN_RONLY */ |
| my_handler = netsnmp_create_handler_registration("netSnmpHostsTable", |
| netSnmpHostsTable_handler, |
| netSnmpHostsTable_oid, |
| OID_LENGTH |
| (netSnmpHostsTable_oid), |
| HANDLER_CAN_RWRITE); |
| |
| if (!my_handler || !table_info || !iinfo) { |
| snmp_log(LOG_ERR, |
| "malloc failed in initialize_table_netSnmpHostsTable"); |
| return; /** Serious error. */ |
| } |
| |
| /*************************************************** |
| * Setting up the table's definition |
| */ |
| netsnmp_table_helper_add_indexes(table_info, ASN_OCTET_STR, |
| /** index: netSnmpHostName */ |
| 0); |
| |
| /** Define the minimum and maximum accessible columns. This |
| optimizes retrieval. */ |
| table_info->min_column = 2; |
| table_info->max_column = 5; |
| |
| /** iterator access routines */ |
| iinfo->get_first_data_point = netSnmpHostsTable_get_first_data_point; |
| iinfo->get_next_data_point = netSnmpHostsTable_get_next_data_point; |
| |
| /** you may wish to set these as well */ |
| iinfo->make_data_context = netSnmpHostsTable_context_convert_function; |
| iinfo->free_data_context = netSnmpHostsTable_data_free; |
| iinfo->free_loop_context_at_end = netSnmpHostsTable_loop_free; |
| |
| /** tie the two structures together */ |
| iinfo->table_reginfo = table_info; |
| |
| /*************************************************** |
| * registering the table with the master agent |
| */ |
| DEBUGMSGTL(("initialize_table_netSnmpHostsTable", |
| "Registering table netSnmpHostsTable as a table iterator\n")); |
| netsnmp_register_table_iterator2(my_handler, iinfo); |
| } |
| |
| /** Initializes the netSnmpHostsTable module */ |
| void |
| init_netSnmpHostsTable(void) |
| { |
| |
| /** here we initialize all the tables we're planning on supporting */ |
| initialize_table_netSnmpHostsTable(); |
| } |
| |
| /** handles requests for the netSnmpHostsTable table, if anything else needs to be done */ |
| int |
| netSnmpHostsTable_handler(netsnmp_mib_handler *handler, |
| netsnmp_handler_registration *reginfo, |
| netsnmp_agent_request_info *reqinfo, |
| netsnmp_request_info *requests) |
| { |
| |
| netsnmp_request_info *request; |
| netsnmp_table_request_info *table_info; |
| struct commitInfo *ci = NULL; |
| |
| void *data_context = NULL; |
| |
| for (request = requests; request; request = request->next) { |
| /* column and row index encoded portion */ |
| netsnmp_variable_list *var = request->requestvb; |
| const oid * const suffix = var->name + reginfo->rootoid_len + 1; |
| const size_t suffix_len = var->name_length - (reginfo->rootoid_len + 1); |
| |
| if (request->processed != 0) |
| continue; |
| |
| switch (reqinfo->mode) { |
| case MODE_GET: |
| case MODE_SET_RESERVE1: |
| data_context = netsnmp_extract_iterator_context(request); |
| if (data_context == NULL) { |
| if (reqinfo->mode == MODE_GET) { |
| netsnmp_set_request_error(reqinfo, request, |
| SNMP_NOSUCHINSTANCE); |
| continue; |
| } |
| } |
| break; |
| |
| default: /* == the other SET modes */ |
| ci = netsnmp_oid_stash_get_data(commitStorage, |
| suffix + 1, suffix_len - 1); |
| break; |
| |
| } |
| |
| /** extracts the information about the table from the request */ |
| table_info = netsnmp_extract_table_info(request); |
| /** table_info->colnum contains the column number requested */ |
| /** table_info->indexes contains a linked list of snmp variable |
| bindings for the indexes of the table. Values in the list |
| have been set corresponding to the indexes of the |
| request */ |
| if (table_info == NULL) { |
| continue; |
| } |
| |
| switch (reqinfo->mode) { |
| case MODE_GET: |
| switch (table_info->colnum) { |
| case COLUMN_NETSNMPHOSTADDRESSTYPE: |
| { |
| long *retval; |
| size_t retval_len = 0; |
| retval = |
| get_netSnmpHostAddressType(data_context, |
| &retval_len); |
| snmp_set_var_typed_value(var, ASN_INTEGER, |
| (const u_char *) retval, |
| retval_len); |
| } |
| break; |
| |
| case COLUMN_NETSNMPHOSTADDRESS: |
| { |
| char *retval; |
| size_t retval_len = 0; |
| retval = |
| get_netSnmpHostAddress(data_context, &retval_len); |
| snmp_set_var_typed_value(var, ASN_OCTET_STR, |
| (const u_char *) retval, |
| retval_len); |
| } |
| break; |
| |
| case COLUMN_NETSNMPHOSTSTORAGE: |
| { |
| long *retval; |
| size_t retval_len = 0; |
| retval = |
| get_netSnmpHostStorage(data_context, &retval_len); |
| snmp_set_var_typed_value(var, ASN_INTEGER, |
| (const u_char *) retval, |
| retval_len); |
| } |
| break; |
| |
| case COLUMN_NETSNMPHOSTROWSTATUS: |
| { |
| long *retval; |
| size_t retval_len = 0; |
| retval = |
| get_netSnmpHostRowStatus(data_context, |
| &retval_len); |
| snmp_set_var_typed_value(var, ASN_INTEGER, |
| (const u_char *) retval, |
| retval_len); |
| } |
| break; |
| |
| default: |
| /** We shouldn't get here */ |
| snmp_log(LOG_ERR, |
| "problem encountered in netSnmpHostsTable_handler: unknown column\n"); |
| } |
| break; |
| |
| case MODE_SET_RESERVE1: |
| ci = netsnmp_oid_stash_get_data(commitStorage, |
| suffix + 1, suffix_len - 1); |
| |
| if (!ci) { |
| /** create the commit storage info */ |
| ci = SNMP_MALLOC_STRUCT(commitInfo); |
| if (!data_context) { |
| ci->data_context = |
| netSnmpHostsTable_create_data_context(table_info-> |
| indexes); |
| ci->new_row = 1; |
| } else { |
| ci->data_context = data_context; |
| } |
| netsnmp_oid_stash_add_data(&commitStorage, |
| suffix + 1, suffix_len - 1, ci); |
| } |
| break; |
| |
| case MODE_SET_RESERVE2: |
| switch (table_info->colnum) { |
| case COLUMN_NETSNMPHOSTADDRESSTYPE: |
| { |
| long *retval; |
| size_t retval_len = 0; |
| struct undoInfo *ui = NULL; |
| int ret; |
| |
| /** first, get the old value */ |
| retval = |
| get_netSnmpHostAddressType(ci->data_context, |
| &retval_len); |
| if (retval) { |
| ui = SNMP_MALLOC_STRUCT(undoInfo); |
| ui->len = retval_len; |
| ui->ptr = netsnmp_memdup(retval, ui->len); |
| } |
| |
| /** check the new value, possibly against the |
| older value for a valid state transition */ |
| ret = |
| check_netSnmpHostAddressType(request->requestvb-> |
| type, |
| (long *) request-> |
| requestvb->val.string, |
| request->requestvb-> |
| val_len, retval, |
| retval_len); |
| if (ret != 0) { |
| netsnmp_set_request_error(reqinfo, request, ret); |
| netSnmpHostsTable_free_undoInfo(ui); |
| } else if (ui) { |
| /** remember information for undo purposes later */ |
| netsnmp_oid_stash_add_data(&undoStorage, |
| suffix, suffix_len, ui); |
| } |
| |
| } |
| break; |
| case COLUMN_NETSNMPHOSTADDRESS: |
| { |
| char *retval; |
| size_t retval_len = 0; |
| struct undoInfo *ui = NULL; |
| int ret; |
| |
| /** first, get the old value */ |
| retval = |
| get_netSnmpHostAddress(ci->data_context, |
| &retval_len); |
| if (retval) { |
| ui = SNMP_MALLOC_STRUCT(undoInfo); |
| ui->len = retval_len; |
| ui->ptr = netsnmp_memdup(retval, ui->len); |
| } |
| |
| /** check the new value, possibly against the |
| older value for a valid state transition */ |
| ret = |
| check_netSnmpHostAddress(request->requestvb->type, |
| (char *) request-> |
| requestvb->val.string, |
| request->requestvb-> |
| val_len, retval, |
| retval_len); |
| if (ret != 0) { |
| netsnmp_set_request_error(reqinfo, request, ret); |
| netSnmpHostsTable_free_undoInfo(ui); |
| } else if (ui) { |
| /** remember information for undo purposes later */ |
| netsnmp_oid_stash_add_data(&undoStorage, |
| suffix, suffix_len, ui); |
| } |
| |
| } |
| break; |
| case COLUMN_NETSNMPHOSTSTORAGE: |
| { |
| long *retval; |
| size_t retval_len = 0; |
| struct undoInfo *ui = NULL; |
| int ret; |
| |
| /** first, get the old value */ |
| retval = |
| get_netSnmpHostStorage(ci->data_context, |
| &retval_len); |
| if (retval) { |
| ui = SNMP_MALLOC_STRUCT(undoInfo); |
| ui->len = retval_len; |
| ui->ptr = netsnmp_memdup(retval, ui->len); |
| } |
| |
| /** check the new value, possibly against the |
| older value for a valid state transition */ |
| ret = |
| check_netSnmpHostStorage(request->requestvb->type, |
| (long *) request-> |
| requestvb->val.string, |
| request->requestvb-> |
| val_len, retval, |
| retval_len); |
| if (ret != 0) { |
| netsnmp_set_request_error(reqinfo, request, ret); |
| netSnmpHostsTable_free_undoInfo(ui); |
| } else if (ui) { |
| /** remember information for undo purposes later */ |
| netsnmp_oid_stash_add_data(&undoStorage, |
| suffix, suffix_len, ui); |
| } |
| |
| } |
| break; |
| case COLUMN_NETSNMPHOSTROWSTATUS: |
| { |
| long *retval; |
| size_t retval_len = 0; |
| struct undoInfo *ui = NULL; |
| int ret; |
| |
| /** first, get the old value */ |
| retval = |
| get_netSnmpHostRowStatus(ci->data_context, |
| &retval_len); |
| if (retval) { |
| ui = SNMP_MALLOC_STRUCT(undoInfo); |
| ui->len = retval_len; |
| ui->ptr = netsnmp_memdup(retval, ui->len); |
| } |
| |
| /** check the new value, possibly against the |
| older value for a valid state transition */ |
| ret = |
| check_netSnmpHostRowStatus(request->requestvb-> |
| type, |
| (long *) request-> |
| requestvb->val.string, |
| request->requestvb-> |
| val_len, retval, |
| retval_len); |
| if (ret != 0) { |
| netsnmp_set_request_error(reqinfo, request, ret); |
| netSnmpHostsTable_free_undoInfo(ui); |
| } else if (ui) { |
| /** remember information for undo purposes later */ |
| netsnmp_oid_stash_add_data(&undoStorage, |
| suffix, suffix_len, ui); |
| } |
| |
| } |
| break; |
| default: |
| netsnmp_set_request_error(reqinfo, request, |
| SNMP_ERR_NOTWRITABLE); |
| break; |
| } |
| break; |
| |
| case MODE_SET_ACTION: |
| /** save a variable copy */ |
| switch (table_info->colnum) { |
| case COLUMN_NETSNMPHOSTADDRESSTYPE: |
| { |
| int ret; |
| ret = set_netSnmpHostAddressType(ci->data_context, |
| (long *) request-> |
| requestvb->val.string, |
| request->requestvb-> |
| val_len); |
| if (ret) { |
| netsnmp_set_request_error(reqinfo, request, ret); |
| } |
| } |
| break; |
| case COLUMN_NETSNMPHOSTADDRESS: |
| { |
| int ret; |
| ret = set_netSnmpHostAddress(ci->data_context, |
| (char *) request-> |
| requestvb->val.string, |
| request->requestvb-> |
| val_len); |
| if (ret) { |
| netsnmp_set_request_error(reqinfo, request, ret); |
| } |
| } |
| break; |
| case COLUMN_NETSNMPHOSTSTORAGE: |
| { |
| int ret; |
| ret = set_netSnmpHostStorage(ci->data_context, |
| (long *) request-> |
| requestvb->val.string, |
| request->requestvb-> |
| val_len); |
| if (ret) { |
| netsnmp_set_request_error(reqinfo, request, ret); |
| } |
| } |
| break; |
| case COLUMN_NETSNMPHOSTROWSTATUS: |
| { |
| int ret; |
| ret = set_netSnmpHostRowStatus(ci->data_context, |
| (long *) request-> |
| requestvb->val.string, |
| request->requestvb-> |
| val_len); |
| if (ret) { |
| netsnmp_set_request_error(reqinfo, request, ret); |
| } |
| if (*request->requestvb->val.integer == RS_DESTROY) { |
| ci->new_row = -1; |
| } |
| } |
| break; |
| } |
| break; |
| |
| case MODE_SET_COMMIT: |
| if (!ci->have_committed) { |
| /** do this once per row only */ |
| netSnmpHostsTable_commit_row(&ci->data_context, |
| ci->new_row); |
| ci->have_committed = 1; |
| } |
| break; |
| |
| case MODE_SET_UNDO: |
| /** save a variable copy */ |
| switch (table_info->colnum) { |
| case COLUMN_NETSNMPHOSTADDRESSTYPE: |
| { |
| int retval; |
| struct undoInfo *ui; |
| ui = netsnmp_oid_stash_get_data(undoStorage, |
| suffix, suffix_len); |
| retval = |
| set_netSnmpHostAddressType(ci->data_context, |
| ui->ptr, ui->len); |
| if (retval) { |
| netsnmp_set_request_error(reqinfo, request, |
| SNMP_ERR_UNDOFAILED); |
| } |
| } |
| break; |
| case COLUMN_NETSNMPHOSTADDRESS: |
| { |
| int retval; |
| struct undoInfo *ui; |
| ui = netsnmp_oid_stash_get_data(undoStorage, |
| suffix, suffix_len); |
| retval = |
| set_netSnmpHostAddress(ci->data_context, ui->ptr, |
| ui->len); |
| if (retval) { |
| netsnmp_set_request_error(reqinfo, request, |
| SNMP_ERR_UNDOFAILED); |
| } |
| } |
| break; |
| case COLUMN_NETSNMPHOSTSTORAGE: |
| { |
| int retval; |
| struct undoInfo *ui; |
| ui = netsnmp_oid_stash_get_data(undoStorage, |
| suffix, suffix_len); |
| retval = |
| set_netSnmpHostStorage(ci->data_context, ui->ptr, |
| ui->len); |
| if (retval) { |
| netsnmp_set_request_error(reqinfo, request, |
| SNMP_ERR_UNDOFAILED); |
| } |
| } |
| break; |
| case COLUMN_NETSNMPHOSTROWSTATUS: |
| { |
| int retval; |
| struct undoInfo *ui; |
| ui = netsnmp_oid_stash_get_data(undoStorage, |
| suffix, suffix_len); |
| retval = |
| set_netSnmpHostRowStatus(ci->data_context, ui->ptr, |
| ui->len); |
| if (retval) { |
| netsnmp_set_request_error(reqinfo, request, |
| SNMP_ERR_UNDOFAILED); |
| } |
| } |
| break; |
| } |
| break; |
| |
| case MODE_SET_FREE: |
| break; |
| |
| default: |
| snmp_log(LOG_ERR, |
| "problem encountered in netSnmpHostsTable_handler: unsupported mode\n"); |
| } |
| } |
| |
| /** clean up after all requset processing has ended */ |
| switch (reqinfo->mode) { |
| case MODE_SET_UNDO: |
| case MODE_SET_FREE: |
| case MODE_SET_COMMIT: |
| /** clear out the undo cache */ |
| netsnmp_oid_stash_free(&undoStorage, |
| netSnmpHostsTable_free_undoInfo); |
| netsnmp_oid_stash_free(&commitStorage, netsnmp_oid_stash_no_free); |
| } |
| |
| |
| return SNMP_ERR_NOERROR; |
| } |