/** Frees the contents of a netsnmp_oid_stash tree. @param root the top of the tree (or branch to be freed) @param freefn The function to be called on each data (void *) pointer. If left NULL the system free() function will be called */ void netsnmp_oid_stash_free(netsnmp_oid_stash_node **root, NetSNMPStashFreeNode *freefn) { netsnmp_oid_stash_node *curnode, *tmpp; unsigned int i; if (!root || !*root) return; /* loop through all our children and free each node */ for (i = 0; i < (*root)->children_size; i++) { if ((*root)->children[i]) { for(tmpp = (*root)->children[i]; tmpp; tmpp = curnode) { if (tmpp->thedata) { if (freefn) (*freefn)(tmpp->thedata); else free(tmpp->thedata); } curnode = tmpp->next_sibling; netsnmp_oid_stash_free(&tmpp, freefn); } } } free((*root)->children); free (*root); *root = NULL; }
void _netsnmp_stash_cache_free( netsnmp_cache *cache, void *magic ) { netsnmp_stash_cache_info *cinfo = (netsnmp_stash_cache_info*) magic; netsnmp_oid_stash_free(&cinfo->cache, (NetSNMPStashFreeNode *) snmp_free_var); return; }
/** 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; memdup((u_char **) & ui->ptr, (u_char *) 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; memdup((u_char **) & ui->ptr, (u_char *) 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; memdup((u_char **) & ui->ptr, (u_char *) 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; memdup((u_char **) & ui->ptr, (u_char *) 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; }
/** handles requests for the ipCidrRouteTable table, if anything else needs to be done */ int ipCidrRouteTable_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; netsnmp_variable_list *var; void *data_context; oid *suffix; size_t suffix_len; /** column and row index encoded portion */ suffix = requests->requestvb->name + reginfo->rootoid_len + 1; suffix_len = requests->requestvb->name_length - (reginfo->rootoid_len + 1); for (request = requests; request; request = request->next) { var = request->requestvb; if (request->processed != 0) continue; 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; } /** XXX: no row existed, if you support creation and this is a set, start dealing with it here, else continue */ } /** 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_IPCIDRROUTEDEST: { u_long *retval; size_t retval_len = 0; retval = get_ipCidrRouteDest(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_IPADDRESS, (const u_char *) retval, retval_len); } break; case COLUMN_IPCIDRROUTEMASK: { u_long *retval; size_t retval_len = 0; retval = get_ipCidrRouteMask(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_IPADDRESS, (const u_char *) retval, retval_len); } break; case COLUMN_IPCIDRROUTETOS: { long *retval; size_t retval_len = 0; retval = get_ipCidrRouteTos(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_INTEGER, (const u_char *) retval, retval_len); } break; case COLUMN_IPCIDRROUTENEXTHOP: { u_long *retval; size_t retval_len = 0; retval = get_ipCidrRouteNextHop(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_IPADDRESS, (const u_char *) retval, retval_len); } break; case COLUMN_IPCIDRROUTEIFINDEX: { long *retval; size_t retval_len = 0; retval = get_ipCidrRouteIfIndex(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_INTEGER, (const u_char *) retval, retval_len); } break; case COLUMN_IPCIDRROUTETYPE: { long *retval; size_t retval_len = 0; retval = get_ipCidrRouteType(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_INTEGER, (const u_char *) retval, retval_len); } break; case COLUMN_IPCIDRROUTEPROTO: { long *retval; size_t retval_len = 0; retval = get_ipCidrRouteProto(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_INTEGER, (const u_char *) retval, retval_len); } break; case COLUMN_IPCIDRROUTEAGE: { long *retval; size_t retval_len = 0; retval = get_ipCidrRouteAge(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_INTEGER, (const u_char *) retval, retval_len); } break; case COLUMN_IPCIDRROUTEINFO: { oid *retval; size_t retval_len = 0; retval = get_ipCidrRouteInfo(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_OBJECT_ID, (const u_char *) retval, retval_len); } break; case COLUMN_IPCIDRROUTENEXTHOPAS: { long *retval; size_t retval_len = 0; retval = get_ipCidrRouteNextHopAS(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_INTEGER, (const u_char *) retval, retval_len); } break; case COLUMN_IPCIDRROUTEMETRIC1: { long *retval; size_t retval_len = 0; retval = get_ipCidrRouteMetric1(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_INTEGER, (const u_char *) retval, retval_len); } break; case COLUMN_IPCIDRROUTEMETRIC2: { long *retval; size_t retval_len = 0; retval = get_ipCidrRouteMetric2(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_INTEGER, (const u_char *) retval, retval_len); } break; case COLUMN_IPCIDRROUTEMETRIC3: { long *retval; size_t retval_len = 0; retval = get_ipCidrRouteMetric3(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_INTEGER, (const u_char *) retval, retval_len); } break; case COLUMN_IPCIDRROUTEMETRIC4: { long *retval; size_t retval_len = 0; retval = get_ipCidrRouteMetric4(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_INTEGER, (const u_char *) retval, retval_len); } break; case COLUMN_IPCIDRROUTEMETRIC5: { long *retval; size_t retval_len = 0; retval = get_ipCidrRouteMetric5(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_INTEGER, (const u_char *) retval, retval_len); } break; case COLUMN_IPCIDRROUTESTATUS: { long *retval; size_t retval_len = 0; retval = get_ipCidrRouteStatus(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 ipCidrRouteTable_handler: unknown column\n"); } break; case MODE_SET_RESERVE1: /** mib2cXXX: clear out old undo info if we have any. Remove if table_iterator becomes un-serialized */ netsnmp_oid_stash_free(&undoStorage, free_undoInfo); switch (table_info->colnum) { case COLUMN_IPCIDRROUTEIFINDEX: { int ret = check_ipCidrRouteIfIndex(request->requestvb->type, (long *) request-> requestvb->val.string, request->requestvb-> val_len); if (ret != 0) { netsnmp_set_request_error(reqinfo, requests, ret); } } break; case COLUMN_IPCIDRROUTETYPE: { int ret = check_ipCidrRouteType(request->requestvb->type, (long *) request->requestvb-> val.string, request->requestvb->val_len); if (ret != 0) { netsnmp_set_request_error(reqinfo, requests, ret); } } break; case COLUMN_IPCIDRROUTEINFO: { int ret = check_ipCidrRouteInfo(request->requestvb->type, (oid *) request->requestvb-> val.string, request->requestvb->val_len); if (ret != 0) { netsnmp_set_request_error(reqinfo, requests, ret); } } break; case COLUMN_IPCIDRROUTENEXTHOPAS: { int ret = check_ipCidrRouteNextHopAS(request->requestvb-> type, (long *) request-> requestvb->val.string, request->requestvb-> val_len); if (ret != 0) { netsnmp_set_request_error(reqinfo, requests, ret); } } break; case COLUMN_IPCIDRROUTEMETRIC1: { int ret = check_ipCidrRouteMetric1(request->requestvb->type, (long *) request-> requestvb->val.string, request->requestvb-> val_len); if (ret != 0) { netsnmp_set_request_error(reqinfo, requests, ret); } } break; case COLUMN_IPCIDRROUTEMETRIC2: { int ret = check_ipCidrRouteMetric2(request->requestvb->type, (long *) request-> requestvb->val.string, request->requestvb-> val_len); if (ret != 0) { netsnmp_set_request_error(reqinfo, requests, ret); } } break; case COLUMN_IPCIDRROUTEMETRIC3: { int ret = check_ipCidrRouteMetric3(request->requestvb->type, (long *) request-> requestvb->val.string, request->requestvb-> val_len); if (ret != 0) { netsnmp_set_request_error(reqinfo, requests, ret); } } break; case COLUMN_IPCIDRROUTEMETRIC4: { int ret = check_ipCidrRouteMetric4(request->requestvb->type, (long *) request-> requestvb->val.string, request->requestvb-> val_len); if (ret != 0) { netsnmp_set_request_error(reqinfo, requests, ret); } } break; case COLUMN_IPCIDRROUTEMETRIC5: { int ret = check_ipCidrRouteMetric5(request->requestvb->type, (long *) request-> requestvb->val.string, request->requestvb-> val_len); if (ret != 0) { netsnmp_set_request_error(reqinfo, requests, ret); } } break; case COLUMN_IPCIDRROUTESTATUS: { int ret = check_ipCidrRouteStatus(request->requestvb->type, (long *) request-> requestvb->val.string, request->requestvb-> val_len); if (ret != 0) { netsnmp_set_request_error(reqinfo, requests, ret); } } break; default: netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_NOTWRITABLE); break; } break; case MODE_SET_RESERVE2: /** save a variable copy */ switch (table_info->colnum) { case COLUMN_IPCIDRROUTEIFINDEX: { long *retval; size_t retval_len = 0; struct undoInfo *ui; retval = get_ipCidrRouteIfIndex(data_context, &retval_len); if (retval) { ui = SNMP_MALLOC_STRUCT(undoInfo); ui->len = retval_len; memdup((u_char **) & ui->ptr, (u_char *) retval, ui->len); netsnmp_oid_stash_add_data(&undoStorage, suffix, suffix_len, ui); } } break; case COLUMN_IPCIDRROUTETYPE: { long *retval; size_t retval_len = 0; struct undoInfo *ui; retval = get_ipCidrRouteType(data_context, &retval_len); if (retval) { ui = SNMP_MALLOC_STRUCT(undoInfo); ui->len = retval_len; memdup((u_char **) & ui->ptr, (u_char *) retval, ui->len); netsnmp_oid_stash_add_data(&undoStorage, suffix, suffix_len, ui); } } break; case COLUMN_IPCIDRROUTEINFO: { oid *retval; size_t retval_len = 0; struct undoInfo *ui; retval = get_ipCidrRouteInfo(data_context, &retval_len); if (retval) { ui = SNMP_MALLOC_STRUCT(undoInfo); ui->len = retval_len; memdup((u_char **) & ui->ptr, (u_char *) retval, ui->len); netsnmp_oid_stash_add_data(&undoStorage, suffix, suffix_len, ui); } } break; case COLUMN_IPCIDRROUTENEXTHOPAS: { long *retval; size_t retval_len = 0; struct undoInfo *ui; retval = get_ipCidrRouteNextHopAS(data_context, &retval_len); if (retval) { ui = SNMP_MALLOC_STRUCT(undoInfo); ui->len = retval_len; memdup((u_char **) & ui->ptr, (u_char *) retval, ui->len); netsnmp_oid_stash_add_data(&undoStorage, suffix, suffix_len, ui); } } break; case COLUMN_IPCIDRROUTEMETRIC1: { long *retval; size_t retval_len = 0; struct undoInfo *ui; retval = get_ipCidrRouteMetric1(data_context, &retval_len); if (retval) { ui = SNMP_MALLOC_STRUCT(undoInfo); ui->len = retval_len; memdup((u_char **) & ui->ptr, (u_char *) retval, ui->len); netsnmp_oid_stash_add_data(&undoStorage, suffix, suffix_len, ui); } } break; case COLUMN_IPCIDRROUTEMETRIC2: { long *retval; size_t retval_len = 0; struct undoInfo *ui; retval = get_ipCidrRouteMetric2(data_context, &retval_len); if (retval) { ui = SNMP_MALLOC_STRUCT(undoInfo); ui->len = retval_len; memdup((u_char **) & ui->ptr, (u_char *) retval, ui->len); netsnmp_oid_stash_add_data(&undoStorage, suffix, suffix_len, ui); } } break; case COLUMN_IPCIDRROUTEMETRIC3: { long *retval; size_t retval_len = 0; struct undoInfo *ui; retval = get_ipCidrRouteMetric3(data_context, &retval_len); if (retval) { ui = SNMP_MALLOC_STRUCT(undoInfo); ui->len = retval_len; memdup((u_char **) & ui->ptr, (u_char *) retval, ui->len); netsnmp_oid_stash_add_data(&undoStorage, suffix, suffix_len, ui); } } break; case COLUMN_IPCIDRROUTEMETRIC4: { long *retval; size_t retval_len = 0; struct undoInfo *ui; retval = get_ipCidrRouteMetric4(data_context, &retval_len); if (retval) { ui = SNMP_MALLOC_STRUCT(undoInfo); ui->len = retval_len; memdup((u_char **) & ui->ptr, (u_char *) retval, ui->len); netsnmp_oid_stash_add_data(&undoStorage, suffix, suffix_len, ui); } } break; case COLUMN_IPCIDRROUTEMETRIC5: { long *retval; size_t retval_len = 0; struct undoInfo *ui; retval = get_ipCidrRouteMetric5(data_context, &retval_len); if (retval) { ui = SNMP_MALLOC_STRUCT(undoInfo); ui->len = retval_len; memdup((u_char **) & ui->ptr, (u_char *) retval, ui->len); netsnmp_oid_stash_add_data(&undoStorage, suffix, suffix_len, ui); } } break; case COLUMN_IPCIDRROUTESTATUS: { long *retval; size_t retval_len = 0; struct undoInfo *ui; retval = get_ipCidrRouteStatus(data_context, &retval_len); if (retval) { ui = SNMP_MALLOC_STRUCT(undoInfo); ui->len = retval_len; memdup((u_char **) & ui->ptr, (u_char *) retval, ui->len); netsnmp_oid_stash_add_data(&undoStorage, suffix, suffix_len, ui); } } break; } break; case MODE_SET_FREE: /** Forget undo data, if exists */ netsnmp_oid_stash_free(&undoStorage, free_undoInfo); break; case MODE_SET_ACTION: /** save a variable copy */ switch (table_info->colnum) { case COLUMN_IPCIDRROUTEIFINDEX: { int ret = set_ipCidrRouteIfIndex(data_context, (long *) request-> requestvb->val.string, request->requestvb-> val_len); if (ret) { netsnmp_set_request_error(reqinfo, requests, ret); } } break; case COLUMN_IPCIDRROUTETYPE: { int ret = set_ipCidrRouteType(data_context, (long *) request-> requestvb-> val.string, request-> requestvb-> val_len); if (ret) { netsnmp_set_request_error(reqinfo, requests, ret); } } break; case COLUMN_IPCIDRROUTEINFO: { int ret = set_ipCidrRouteInfo(data_context, (oid *) request-> requestvb-> val.string, request-> requestvb-> val_len); if (ret) { netsnmp_set_request_error(reqinfo, requests, ret); } } break; case COLUMN_IPCIDRROUTENEXTHOPAS: { int ret = set_ipCidrRouteNextHopAS(data_context, (long *) request-> requestvb->val.string, request->requestvb-> val_len); if (ret) { netsnmp_set_request_error(reqinfo, requests, ret); } } break; case COLUMN_IPCIDRROUTEMETRIC1: { int ret = set_ipCidrRouteMetric1(data_context, (long *) request-> requestvb->val.string, request->requestvb-> val_len); if (ret) { netsnmp_set_request_error(reqinfo, requests, ret); } } break; case COLUMN_IPCIDRROUTEMETRIC2: { int ret = set_ipCidrRouteMetric2(data_context, (long *) request-> requestvb->val.string, request->requestvb-> val_len); if (ret) { netsnmp_set_request_error(reqinfo, requests, ret); } } break; case COLUMN_IPCIDRROUTEMETRIC3: { int ret = set_ipCidrRouteMetric3(data_context, (long *) request-> requestvb->val.string, request->requestvb-> val_len); if (ret) { netsnmp_set_request_error(reqinfo, requests, ret); } } break; case COLUMN_IPCIDRROUTEMETRIC4: { int ret = set_ipCidrRouteMetric4(data_context, (long *) request-> requestvb->val.string, request->requestvb-> val_len); if (ret) { netsnmp_set_request_error(reqinfo, requests, ret); } } break; case COLUMN_IPCIDRROUTEMETRIC5: { int ret = set_ipCidrRouteMetric5(data_context, (long *) request-> requestvb->val.string, request->requestvb-> val_len); if (ret) { netsnmp_set_request_error(reqinfo, requests, ret); } } break; case COLUMN_IPCIDRROUTESTATUS: { int ret = set_ipCidrRouteStatus(data_context, (long *) request->requestvb-> val.string, request->requestvb->val_len); if (ret) { netsnmp_set_request_error(reqinfo, requests, ret); } } break; } break; case MODE_SET_COMMIT: /** answers were all good. Forget undo data */ netsnmp_oid_stash_free(&undoStorage, free_undoInfo); /** mib2cXXX: call commit hook */ break; case MODE_SET_UNDO: /** save a variable copy */ switch (table_info->colnum) { case COLUMN_IPCIDRROUTEIFINDEX: { int retval; struct undoInfo *ui; ui = netsnmp_oid_stash_get_data(undoStorage, suffix, suffix_len); retval = set_ipCidrRouteIfIndex(data_context, ui->ptr, ui->len); if (retval) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_UNDOFAILED); } } break; case COLUMN_IPCIDRROUTETYPE: { int retval; struct undoInfo *ui; ui = netsnmp_oid_stash_get_data(undoStorage, suffix, suffix_len); retval = set_ipCidrRouteType(data_context, ui->ptr, ui->len); if (retval) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_UNDOFAILED); } } break; case COLUMN_IPCIDRROUTEINFO: { int retval; struct undoInfo *ui; ui = netsnmp_oid_stash_get_data(undoStorage, suffix, suffix_len); retval = set_ipCidrRouteInfo(data_context, ui->ptr, ui->len); if (retval) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_UNDOFAILED); } } break; case COLUMN_IPCIDRROUTENEXTHOPAS: { int retval; struct undoInfo *ui; ui = netsnmp_oid_stash_get_data(undoStorage, suffix, suffix_len); retval = set_ipCidrRouteNextHopAS(data_context, ui->ptr, ui->len); if (retval) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_UNDOFAILED); } } break; case COLUMN_IPCIDRROUTEMETRIC1: { int retval; struct undoInfo *ui; ui = netsnmp_oid_stash_get_data(undoStorage, suffix, suffix_len); retval = set_ipCidrRouteMetric1(data_context, ui->ptr, ui->len); if (retval) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_UNDOFAILED); } } break; case COLUMN_IPCIDRROUTEMETRIC2: { int retval; struct undoInfo *ui; ui = netsnmp_oid_stash_get_data(undoStorage, suffix, suffix_len); retval = set_ipCidrRouteMetric2(data_context, ui->ptr, ui->len); if (retval) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_UNDOFAILED); } } break; case COLUMN_IPCIDRROUTEMETRIC3: { int retval; struct undoInfo *ui; ui = netsnmp_oid_stash_get_data(undoStorage, suffix, suffix_len); retval = set_ipCidrRouteMetric3(data_context, ui->ptr, ui->len); if (retval) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_UNDOFAILED); } } break; case COLUMN_IPCIDRROUTEMETRIC4: { int retval; struct undoInfo *ui; ui = netsnmp_oid_stash_get_data(undoStorage, suffix, suffix_len); retval = set_ipCidrRouteMetric4(data_context, ui->ptr, ui->len); if (retval) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_UNDOFAILED); } } break; case COLUMN_IPCIDRROUTEMETRIC5: { int retval; struct undoInfo *ui; ui = netsnmp_oid_stash_get_data(undoStorage, suffix, suffix_len); retval = set_ipCidrRouteMetric5(data_context, ui->ptr, ui->len); if (retval) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_UNDOFAILED); } } break; case COLUMN_IPCIDRROUTESTATUS: { int retval; struct undoInfo *ui; ui = netsnmp_oid_stash_get_data(undoStorage, suffix, suffix_len); retval = set_ipCidrRouteStatus(data_context, ui->ptr, ui->len); if (retval) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_UNDOFAILED); } } break; } /** mib2cXXX: remove cache! hard to do when serialized, however */ break; default: snmp_log(LOG_ERR, "problem encountered in ipCidrRouteTable_handler: unsupported mode\n"); } } return SNMP_ERR_NOERROR; }
/** handles requests for the qosObjectTable table, if anything else needs to be done */ int qosObjectTable_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; netsnmp_variable_list *var; struct commitInfo *ci = NULL; void *data_context = NULL; oid *suffix; size_t suffix_len; /** column and row index encoded portion */ suffix = requests->requestvb->name + reginfo->rootoid_len + 1; suffix_len = requests->requestvb->name_length - (reginfo->rootoid_len + 1); for (request = requests; request; request = request->next) { var = request->requestvb; 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_QOSDEVICETYPE: { long *retval; size_t retval_len = 0; retval = get_qosDeviceIndex(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_INTEGER, (const u_char *) retval, retval_len); } break; case COLUMN_QOSDEVICEINDEX: { long *retval; size_t retval_len = 0; retval = get_qosDeviceIndex(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_INTEGER, (const u_char *) retval, retval_len); } break; case COLUMN_QOSMAJORHANDLE: { long *retval; size_t retval_len = 0; retval = get_qosMajorHandle(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_UNSIGNED, (const u_char *) retval, retval_len); } break; case COLUMN_QOSMINORHANDLE: { long *retval; size_t retval_len = 0; retval = get_qosMinorHandle(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_UNSIGNED, (const u_char *) retval, retval_len); } break; case COLUMN_QOSTEXTHANDLE: { char *retval; size_t retval_len = 0; retval = get_qosTextHandle(data_context, &retval_len); snmp_set_var_typed_value(var,ASN_OCTET_STR, (const u_char *) retval, retval_len); } break; case COLUMN_QOSTEXTLEAF: { char *retval; size_t retval_len = 0; retval = get_qosTextLeaf(data_context, &retval_len); snmp_set_var_typed_value(var,ASN_OCTET_STR, (const u_char *) retval, retval_len); } break; case COLUMN_QOSPARENT: { long *retval; size_t retval_len = 0; retval = get_qosParent(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_UNSIGNED, (const u_char *) retval, retval_len); } break; case COLUMN_QOSTEXTPARENT: { char *retval; size_t retval_len = 0; retval = get_qosTextParent(data_context, &retval_len); snmp_set_var_typed_value(var,ASN_OCTET_STR, (const u_char *) retval, retval_len); } break; case COLUMN_QOSDEVICENAME: { char *retval; size_t retval_len = 0; retval = get_qosDeviceName(data_context, &retval_len); snmp_set_var_typed_value(var,ASN_OCTET_STR, (const u_char *) retval, retval_len); } break; case COLUMN_QOSTYPE: { char *retval; size_t retval_len = 0; retval = get_qosType(data_context, &retval_len); snmp_set_var_typed_value(var,ASN_OCTET_STR, (const u_char *) retval, retval_len); } break; case COLUMN_QOSBYTES: { unsigned long long *retval; // u_long *retval; size_t retval_len = 0; retval = get_qosBytes(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_COUNTER64, (const u_char *) retval, retval_len); } break; case COLUMN_QOSPACKETS: { u_long *retval; size_t retval_len = 0; retval = get_qosPackets(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_COUNTER, (const u_char *) retval, retval_len); } break; case COLUMN_QOSDROPPED: { u_long *retval; size_t retval_len = 0; retval = get_qosDropped(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_COUNTER, (const u_char *) retval, retval_len); } break; case COLUMN_QOSOVERLIMIT: { u_long *retval; size_t retval_len = 0; retval = get_qosOverlimit(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_COUNTER, (const u_char *) retval, retval_len); } break; case COLUMN_QOSBPS: { u_long *retval; size_t retval_len = 0; retval = get_qosBps(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_UNSIGNED, (const u_char *) retval, retval_len); } break; case COLUMN_QOSPPS: { u_long *retval; size_t retval_len = 0; retval = get_qosPps(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_UNSIGNED, (const u_char *) retval, retval_len); } break; case COLUMN_QOSQLEN: { u_long *retval; size_t retval_len = 0; retval = get_qosQlen(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_UNSIGNED, (const u_char *) retval, retval_len); } break; case COLUMN_QOSBACKLOG: { u_long *retval; size_t retval_len = 0; retval = get_qosBacklog(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_UNSIGNED, (const u_char *) retval, retval_len); } break; case COLUMN_QOSREDEARLY: { u_long *retval; size_t retval_len = 0; retval = get_redEarly(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_COUNTER, (const u_char *) retval, retval_len); } break; case COLUMN_QOSREDPDROP: { u_long *retval; size_t retval_len = 0; retval = get_redPdrop(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_COUNTER, (const u_char *) retval, retval_len); } break; case COLUMN_QOSREDOTHER: { u_long *retval; size_t retval_len = 0; retval = get_redOther(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_COUNTER, (const u_char *) retval, retval_len); } break; case COLUMN_QOSREDMARKED: { u_long *retval; size_t retval_len = 0; retval = get_redMarked(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_COUNTER, (const u_char *) retval, retval_len); } break; case COLUMN_QOSHTBLENDS: { u_long *retval; size_t retval_len = 0; retval = get_htbLends(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_COUNTER, (const u_char *) retval, retval_len); } break; case COLUMN_QOSHTBBORROWS: { u_long *retval; size_t retval_len = 0; retval = get_htbBorrows(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_COUNTER, (const u_char *) retval, retval_len); } break; case COLUMN_QOSHTBGIANTS: { u_long *retval; size_t retval_len = 0; retval = get_htbGiants(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_COUNTER, (const u_char *) retval, retval_len); } break; case COLUMN_QOSHTBTOKENS: { u_long *retval; size_t retval_len = 0; retval = get_htbTokens(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_INTEGER, (const u_char *) retval, retval_len); } break; case COLUMN_QOSHTBCTOKENS: { u_long *retval; size_t retval_len = 0; retval = get_htbCTokens(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_INTEGER, (const u_char *) retval, retval_len); } break; case COLUMN_QOSHTBRATE: { u_long *retval; size_t retval_len = 0; retval = get_htbRate(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_UNSIGNED, (const u_char *) retval, retval_len); } break; case COLUMN_QOSHTBCEIL: { u_long *retval; size_t retval_len = 0; retval = get_htbCeil(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_UNSIGNED, (const u_char *) retval, retval_len); } break; case COLUMN_QOSHTBPRIO: { u_long *retval; size_t retval_len = 0; retval = get_htbPrio(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_UNSIGNED, (const u_char *) retval, retval_len); } break; case COLUMN_QOSCBQBORROWS: { u_long *retval; size_t retval_len = 0; retval = get_cbqBorrows(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_COUNTER, (const u_char *) retval, retval_len); } break; case COLUMN_QOSCBQOVERACTIONS: { u_long *retval; size_t retval_len = 0; retval = get_cbqOveractions(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_COUNTER, (const u_char *) retval, retval_len); } break; case COLUMN_QOSCBQAVGIDLE: { long *retval; size_t retval_len = 0; retval = get_cbqUndertime(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_INTEGER, (const u_char *) retval, retval_len); } break; case COLUMN_QOSCBQUNDERTIME: { long *retval; size_t retval_len = 0; retval = get_cbqUndertime(data_context, &retval_len); snmp_set_var_typed_value(var, ASN_INTEGER, (const u_char *) retval, retval_len); } break; case COLUMN_QOSINFO: { char *retval; size_t retval_len = 0; retval = get_qosInfo(data_context, &retval_len); snmp_set_var_typed_value(var,ASN_OCTET_STR, (const u_char *) retval, retval_len); } break; default: /** We shouldn't get here */ snmp_log(LOG_ERR, "problem encountered in qosObjectTable_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 = qosObjectTable_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) { default: netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOTWRITABLE); break; } break; case MODE_SET_ACTION: /** save a variable copy */ switch (table_info->colnum) { } break; case MODE_SET_COMMIT: if (!ci->have_committed) { /** do this once per row only */ qosObjectTable_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) { } break; case MODE_SET_FREE: break; default: snmp_log(LOG_ERR, "problem encountered in qosObjectTable_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, qos_free_undoInfo); netsnmp_oid_stash_free(&commitStorage, netsnmp_oid_stash_no_free); } return SNMP_ERR_NOERROR; }