diff options
author | Kozlov Dmitry <dima@server> | 2011-08-19 14:04:55 +0400 |
---|---|---|
committer | Kozlov Dmitry <dima@server> | 2011-08-19 14:04:55 +0400 |
commit | 5ef49162ea9763ca9878c22e3736766d8f1db014 (patch) | |
tree | f58da9adfc87ece6c608265fc694e66bd5db162c /accel-pppd/extra/net-snmp/sessionTable_interface.c | |
parent | fd52e4578dcc7de2301480fece9395563d643045 (diff) | |
download | accel-ppp-5ef49162ea9763ca9878c22e3736766d8f1db014.tar.gz accel-ppp-5ef49162ea9763ca9878c22e3736766d8f1db014.zip |
snmp support
Diffstat (limited to 'accel-pppd/extra/net-snmp/sessionTable_interface.c')
-rw-r--r-- | accel-pppd/extra/net-snmp/sessionTable_interface.c | 946 |
1 files changed, 946 insertions, 0 deletions
diff --git a/accel-pppd/extra/net-snmp/sessionTable_interface.c b/accel-pppd/extra/net-snmp/sessionTable_interface.c new file mode 100644 index 00000000..cf60f910 --- /dev/null +++ b/accel-pppd/extra/net-snmp/sessionTable_interface.c @@ -0,0 +1,946 @@ +/* + * Note: this file originally auto-generated by mib2c using + * version : 15899 $ of $ + * + * $Id:$ + */ +/* + * ********************************************************************* + * ********************************************************************* + * ********************************************************************* + * *** *** + * *** NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE *** + * *** *** + * *** *** + * *** THIS FILE DOES NOT CONTAIN ANY USER EDITABLE CODE. *** + * *** *** + * *** *** + * *** THE GENERATED CODE IS INTERNAL IMPLEMENTATION, AND *** + * *** *** + * *** *** + * *** IS SUBJECT TO CHANGE WITHOUT WARNING IN FUTURE RELEASES. *** + * *** *** + * *** *** + * ********************************************************************* + * ********************************************************************* + * ********************************************************************* + */ + +/* standard Net-SNMP includes */ +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/net-snmp-includes.h> +#include <net-snmp/agent/net-snmp-agent-includes.h> + +/* include our parent header */ +#include "sessionTable.h" + + +#include <net-snmp/agent/table_container.h> +#include <net-snmp/library/container.h> + +#include "sessionTable_interface.h" + +#include <ctype.h> + +/********************************************************************** + ********************************************************************** + *** + *** Table sessionTable + *** + ********************************************************************** + **********************************************************************/ +/* + * ACCEL-PPP-MIB::sessionTable is subid 1 of accelPPPSessions. + * Its status is Current. + * OID: .1.3.6.1.4.1.8072.100.2.1, length: 10 +*/ +typedef struct sessionTable_interface_ctx_s { + + netsnmp_container *container; + netsnmp_cache *cache; + + sessionTable_registration * user_ctx; + + netsnmp_table_registration_info tbl_info; + + netsnmp_baby_steps_access_methods access_multiplexer; + +} sessionTable_interface_ctx; + +static sessionTable_interface_ctx sessionTable_if_ctx; + +static void _sessionTable_container_init( + sessionTable_interface_ctx *if_ctx); +static void _sessionTable_container_shutdown( + sessionTable_interface_ctx *if_ctx); + + +netsnmp_container * +sessionTable_container_get( void ) +{ + return sessionTable_if_ctx.container; +} + +sessionTable_registration * +sessionTable_registration_get( void ) +{ + return sessionTable_if_ctx.user_ctx; +} + +sessionTable_registration * +sessionTable_registration_set( sessionTable_registration * newreg ) +{ + sessionTable_registration * old = sessionTable_if_ctx.user_ctx; + sessionTable_if_ctx.user_ctx = newreg; + return old; +} + +int +sessionTable_container_size( void ) +{ + return CONTAINER_SIZE(sessionTable_if_ctx.container); +} + +/* + * mfd multiplexer modes + */ +static Netsnmp_Node_Handler _mfd_sessionTable_pre_request; +static Netsnmp_Node_Handler _mfd_sessionTable_post_request; +static Netsnmp_Node_Handler _mfd_sessionTable_object_lookup; +static Netsnmp_Node_Handler _mfd_sessionTable_get_values; +/** + * @internal + * Initialize the table sessionTable + * (Define its contents and how it's structured) + */ +void +_sessionTable_initialize_interface(sessionTable_registration * reg_ptr, u_long flags) +{ + netsnmp_baby_steps_access_methods *access_multiplexer = + &sessionTable_if_ctx.access_multiplexer; + netsnmp_table_registration_info *tbl_info = &sessionTable_if_ctx.tbl_info; + netsnmp_handler_registration *reginfo; + netsnmp_mib_handler *handler; + int mfd_modes = 0; + + DEBUGMSGTL(("internal:sessionTable:_sessionTable_initialize_interface","called\n")); + + + /************************************************* + * + * save interface context for sessionTable + */ + /* + * Setting up the table's definition + */ + netsnmp_table_helper_add_indexes(tbl_info, + ASN_OCTET_STR, /** index: sesSID */ + 0); + + /* Define the minimum and maximum accessible columns. This + optimizes retrival. */ + tbl_info->min_column = SESSIONTABLE_MIN_COL; + tbl_info->max_column = SESSIONTABLE_MAX_COL; + + /* + * save users context + */ + sessionTable_if_ctx.user_ctx = reg_ptr; + + /* + * call data access initialization code + */ + sessionTable_init_data(reg_ptr); + + /* + * set up the container + */ + _sessionTable_container_init(&sessionTable_if_ctx); + if (NULL == sessionTable_if_ctx.container) { + snmp_log(LOG_ERR,"could not initialize container for sessionTable\n"); + return; + } + + /* + * access_multiplexer: REQUIRED wrapper for get request handling + */ + access_multiplexer->object_lookup = _mfd_sessionTable_object_lookup; + access_multiplexer->get_values = _mfd_sessionTable_get_values; + + /* + * no wrappers yet + */ + access_multiplexer->pre_request = _mfd_sessionTable_pre_request; + access_multiplexer->post_request = _mfd_sessionTable_post_request; + + + /************************************************* + * + * Create a registration, save our reg data, register table. + */ + DEBUGMSGTL(("sessionTable:init_sessionTable", + "Registering sessionTable as a mibs-for-dummies table.\n")); + handler = netsnmp_baby_steps_access_multiplexer_get(access_multiplexer); + reginfo = netsnmp_handler_registration_create("sessionTable", handler, + sessionTable_oid, + sessionTable_oid_size, + HANDLER_CAN_BABY_STEP | + HANDLER_CAN_RONLY + ); + if(NULL == reginfo) { + snmp_log(LOG_ERR,"error registering table sessionTable\n"); + return; + } + reginfo->my_reg_void = &sessionTable_if_ctx; + + /************************************************* + * + * set up baby steps handler, create it and inject it + */ + if( access_multiplexer->object_lookup ) + mfd_modes |= BABY_STEP_OBJECT_LOOKUP; + if( access_multiplexer->set_values ) + mfd_modes |= BABY_STEP_SET_VALUES; + if( access_multiplexer->irreversible_commit ) + mfd_modes |= BABY_STEP_IRREVERSIBLE_COMMIT; + if( access_multiplexer->object_syntax_checks ) + mfd_modes |= BABY_STEP_CHECK_OBJECT; + + if( access_multiplexer->pre_request ) + mfd_modes |= BABY_STEP_PRE_REQUEST; + if( access_multiplexer->post_request ) + mfd_modes |= BABY_STEP_POST_REQUEST; + + if( access_multiplexer->undo_setup ) + mfd_modes |= BABY_STEP_UNDO_SETUP; + if( access_multiplexer->undo_cleanup ) + mfd_modes |= BABY_STEP_UNDO_CLEANUP; + if( access_multiplexer->undo_sets ) + mfd_modes |= BABY_STEP_UNDO_SETS; + + if( access_multiplexer->row_creation ) + mfd_modes |= BABY_STEP_ROW_CREATE; + if( access_multiplexer->consistency_checks ) + mfd_modes |= BABY_STEP_CHECK_CONSISTENCY; + if( access_multiplexer->commit ) + mfd_modes |= BABY_STEP_COMMIT; + if( access_multiplexer->undo_commit ) + mfd_modes |= BABY_STEP_UNDO_COMMIT; + + handler = netsnmp_baby_steps_handler_get(mfd_modes); + netsnmp_inject_handler(reginfo, handler); + + /************************************************* + * + * inject row_merge helper with prefix rootoid_len + 2 (entry.col) + */ + handler = netsnmp_get_row_merge_handler(reginfo->rootoid_len + 2); + netsnmp_inject_handler(reginfo, handler); + + /************************************************* + * + * inject container_table helper + */ + handler = + netsnmp_container_table_handler_get(tbl_info, + sessionTable_if_ctx.container, + TABLE_CONTAINER_KEY_NETSNMP_INDEX); + netsnmp_inject_handler( reginfo, handler ); + + /************************************************* + * + * inject cache helper + */ + if(NULL != sessionTable_if_ctx.cache) { + handler = netsnmp_cache_handler_get(sessionTable_if_ctx.cache); + netsnmp_inject_handler( reginfo, handler ); + } + + /* + * register table + */ + netsnmp_register_table(reginfo, tbl_info); + +} /* _sessionTable_initialize_interface */ + +/** + * @internal + * Shutdown the table sessionTable + */ +void +_sessionTable_shutdown_interface(sessionTable_registration * reg_ptr) +{ + /* + * shutdown the container + */ + _sessionTable_container_shutdown(&sessionTable_if_ctx); +} + +void +sessionTable_valid_columns_set(netsnmp_column_info *vc) +{ + sessionTable_if_ctx.tbl_info.valid_columns = vc; +} /* sessionTable_valid_columns_set */ + +/** + * @internal + * convert the index component stored in the context to an oid + */ +int +sessionTable_index_to_oid(netsnmp_index *oid_idx, + sessionTable_mib_index *mib_idx) +{ + int err = SNMP_ERR_NOERROR; + + /* + * temp storage for parsing indexes + */ + /* + * sesSID(1)/OCTETSTR/ASN_OCTET_STR/char(char)//L/A/w/e/R/d/h + */ + netsnmp_variable_list var_sesSID; + + /* + * set up varbinds + */ + memset( &var_sesSID, 0x00, sizeof(var_sesSID) ); + var_sesSID.type = ASN_OCTET_STR; + + /* + * chain temp index varbinds together + */ + var_sesSID.next_variable = NULL; + + + DEBUGMSGTL(("verbose:sessionTable:sessionTable_index_to_oid","called\n")); + + /* sesSID(1)/OCTETSTR/ASN_OCTET_STR/char(char)//L/A/w/e/R/d/h */ + snmp_set_var_value(&var_sesSID, (u_char*)&mib_idx->sesSID, + mib_idx->sesSID_len * sizeof(mib_idx->sesSID[0])); + + + err = build_oid_noalloc(oid_idx->oids, oid_idx->len, &oid_idx->len, + NULL, 0, &var_sesSID); + if(err) + snmp_log(LOG_ERR,"error %d converting index to oid\n", err); + + /* + * parsing may have allocated memory. free it. + */ + snmp_reset_var_buffers( &var_sesSID ); + + return err; +} /* sessionTable_index_to_oid */ + +/** + * extract sessionTable indexes from a netsnmp_index + * + * @retval SNMP_ERR_NOERROR : no error + * @retval SNMP_ERR_GENERR : error + */ +int +sessionTable_index_from_oid(netsnmp_index *oid_idx, + sessionTable_mib_index *mib_idx) +{ + int err = SNMP_ERR_NOERROR; + + /* + * temp storage for parsing indexes + */ + /* + * sesSID(1)/OCTETSTR/ASN_OCTET_STR/char(char)//L/A/w/e/R/d/h + */ + netsnmp_variable_list var_sesSID; + + /* + * set up varbinds + */ + memset( &var_sesSID, 0x00, sizeof(var_sesSID) ); + var_sesSID.type = ASN_OCTET_STR; + + /* + * chain temp index varbinds together + */ + var_sesSID.next_variable = NULL; + + + DEBUGMSGTL(("verbose:sessionTable:sessionTable_index_from_oid","called\n")); + + /* + * parse the oid into the individual index components + */ + err = parse_oid_indexes( oid_idx->oids, oid_idx->len, + &var_sesSID ); + if (err == SNMP_ERR_NOERROR) { + /* + * copy out values + */ + /* + * NOTE: val_len is in bytes, sesSID_len might not be + */ + if(var_sesSID.val_len > sizeof(mib_idx->sesSID)) + err = SNMP_ERR_GENERR; + else { + memcpy(mib_idx->sesSID, var_sesSID.val.string, var_sesSID.val_len); + mib_idx->sesSID_len = var_sesSID.val_len / sizeof(mib_idx->sesSID[0]); + } + + + } + + /* + * parsing may have allocated memory. free it. + */ + snmp_reset_var_buffers( &var_sesSID ); + + return err; +} /* sessionTable_index_from_oid */ + + +/* ********************************************************************* + * @internal + * allocate resources for a sessionTable_rowreq_ctx + */ +sessionTable_rowreq_ctx * +sessionTable_allocate_rowreq_ctx(sessionTable_data *data, void *user_init_ctx) +{ + sessionTable_rowreq_ctx *rowreq_ctx = + SNMP_MALLOC_TYPEDEF(sessionTable_rowreq_ctx); + + DEBUGMSGTL(("internal:sessionTable:sessionTable_allocate_rowreq_ctx","called\n")); + + if(NULL == rowreq_ctx) { + snmp_log(LOG_ERR,"Couldn't allocate memory for a " + "sessionTable_rowreq_ctx.\n"); + return NULL; + } + else { + if(NULL != data) { + /* + * track if we got data from user + */ + rowreq_ctx->rowreq_flags |= MFD_ROW_DATA_FROM_USER; + rowreq_ctx->data = data; + } + else if (NULL == (rowreq_ctx->data = sessionTable_allocate_data())) { + SNMP_FREE(rowreq_ctx); + return NULL; + } + } + + /* + * undo context will be allocated when needed (in *_undo_setup) + */ + + rowreq_ctx->oid_idx.oids = rowreq_ctx->oid_tmp; + + rowreq_ctx->sessionTable_data_list = NULL; + + /* + * if we allocated data, call init routine + */ + if (!(rowreq_ctx->rowreq_flags & MFD_ROW_DATA_FROM_USER)) { + if(SNMPERR_SUCCESS != + sessionTable_rowreq_ctx_init(rowreq_ctx, user_init_ctx)) { + sessionTable_release_rowreq_ctx(rowreq_ctx); + rowreq_ctx = NULL; + } + } + + return rowreq_ctx; +} /* sessionTable_allocate_rowreq_ctx */ + +/* + * @internal + * release resources for a sessionTable_rowreq_ctx + */ +void +sessionTable_release_rowreq_ctx(sessionTable_rowreq_ctx *rowreq_ctx) +{ + DEBUGMSGTL(("internal:sessionTable:sessionTable_release_rowreq_ctx","called\n")); + + netsnmp_assert(NULL != rowreq_ctx); + + sessionTable_rowreq_ctx_cleanup(rowreq_ctx); + + /* + * for non-transient data, don't free data we got from the user + */ + if ((rowreq_ctx->data) && + !(rowreq_ctx->rowreq_flags & MFD_ROW_DATA_FROM_USER)) + sessionTable_release_data(rowreq_ctx->data); + + /* + * free index oid pointer + */ + if(rowreq_ctx->oid_idx.oids != rowreq_ctx->oid_tmp) + free(rowreq_ctx->oid_idx.oids); + + SNMP_FREE(rowreq_ctx); +} /* sessionTable_release_rowreq_ctx */ + +/** + * @internal + * wrapper + */ +static int +_mfd_sessionTable_pre_request(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *agtreq_info, + netsnmp_request_info *requests) +{ + int rc; + + DEBUGMSGTL(("internal:sessionTable:_mfd_sessionTable_pre_request", + "called\n")); + + if (1 != netsnmp_row_merge_status_first(reginfo, agtreq_info)) { + DEBUGMSGTL(("internal:sessionTable", + "skipping additional pre_request\n")); + return SNMP_ERR_NOERROR; + } + + rc = sessionTable_pre_request(sessionTable_if_ctx.user_ctx); + if (MFD_SUCCESS != rc) { + /* + * nothing we can do about it but log it + */ + DEBUGMSGTL(("sessionTable","error %d from " + "sessionTable_pre_request\n", rc)); + netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc)); + } + + return SNMP_ERR_NOERROR; +} /* _mfd_sessionTable_pre_request */ + +/** + * @internal + * wrapper + */ +static int +_mfd_sessionTable_post_request(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *agtreq_info, + netsnmp_request_info *requests) +{ + sessionTable_rowreq_ctx *rowreq_ctx = + netsnmp_container_table_row_extract(requests); + int rc, packet_rc; + + DEBUGMSGTL(("internal:sessionTable:_mfd_sessionTable_post_request", + "called\n")); + + /* + * release row context, if deleted + */ + if (rowreq_ctx && (rowreq_ctx->rowreq_flags & MFD_ROW_DELETED)) + sessionTable_release_rowreq_ctx(rowreq_ctx); + + /* + * wait for last call before calling user + */ + if (1 != netsnmp_row_merge_status_last(reginfo, agtreq_info)) { + DEBUGMSGTL(("internal:sessionTable", + "waiting for last post_request\n")); + return SNMP_ERR_NOERROR; + } + + packet_rc = netsnmp_check_all_requests_error(agtreq_info->asp, 0); + rc = sessionTable_post_request(sessionTable_if_ctx.user_ctx,packet_rc); + if (MFD_SUCCESS != rc) { + /* + * nothing we can do about it but log it + */ + DEBUGMSGTL(("sessionTable","error %d from " + "sessionTable_post_request\n", rc)); + } + + return SNMP_ERR_NOERROR; +} /* _mfd_sessionTable_post_request */ + +/** + * @internal + * wrapper + */ +static int +_mfd_sessionTable_object_lookup(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *agtreq_info, + netsnmp_request_info *requests) +{ + int rc = SNMP_ERR_NOERROR; + sessionTable_rowreq_ctx *rowreq_ctx = + netsnmp_container_table_row_extract(requests); + + DEBUGMSGTL(("internal:sessionTable:_mfd_sessionTable_object_lookup","called\n")); + + /* + * get our context from mfd + * sessionTable_interface_ctx *if_ctx = + * (sessionTable_interface_ctx *)reginfo->my_reg_void; + */ + + if(NULL == rowreq_ctx) { + rc = SNMP_ERR_NOCREATION; + } + + if (MFD_SUCCESS != rc) + netsnmp_request_set_error_all(requests, rc); + else + sessionTable_row_prep(rowreq_ctx); + + return SNMP_VALIDATE_ERR(rc); +} /* _mfd_sessionTable_object_lookup */ + +/*********************************************************************** + * + * GET processing + * + ***********************************************************************/ +/* + * @internal + * Retrieve the value for a particular column + */ +NETSNMP_STATIC_INLINE int +_sessionTable_get_column( sessionTable_rowreq_ctx *rowreq_ctx, + netsnmp_variable_list *var, int column ) +{ + int rc = SNMPERR_SUCCESS; + + DEBUGMSGTL(("internal:sessionTable:_mfd_sessionTable_get_column", + "called for %d\n", column)); + + + netsnmp_assert(NULL != rowreq_ctx); + + switch(column) { + + /* (INDEX) sesSID(1)/OCTETSTR/ASN_OCTET_STR/char(char)//L/A/w/e/R/d/h */ + case COLUMN_SESSID: + var->type = ASN_OCTET_STR; + /* + * NOTE: val_len is in bytes, sesSID_len might not be (e.g. oids) + */ + if (var->val_len < (rowreq_ctx->tbl_idx.sesSID_len * + sizeof(rowreq_ctx->tbl_idx.sesSID[0]))) { + var->val.string = malloc(rowreq_ctx->tbl_idx.sesSID_len * + sizeof(rowreq_ctx->tbl_idx.sesSID[0])); + } + var->val_len = rowreq_ctx->tbl_idx.sesSID_len * sizeof(rowreq_ctx->tbl_idx.sesSID[0]); + memcpy( var->val.string, rowreq_ctx->tbl_idx.sesSID, var->val_len ); + break; + + /* sesIfName(2)/OCTETSTR/ASN_OCTET_STR/char(char)//L/A/w/e/r/d/h */ + case COLUMN_SESIFNAME: + var->type = ASN_OCTET_STR; +rc = sesIfName_get(rowreq_ctx, (char **)&var->val.string, &var->val_len ); + break; + + /* sesUsername(3)/OCTETSTR/ASN_OCTET_STR/char(char)//L/A/w/e/r/d/h */ + case COLUMN_SESUSERNAME: + var->type = ASN_OCTET_STR; +rc = sesUsername_get(rowreq_ctx, (char **)&var->val.string, &var->val_len ); + break; + + /* sesIP(4)/InetAddressIPv4/ASN_OCTET_STR/char(char)//L/A/w/e/R/d/H */ + case COLUMN_SESIP: + var->type = ASN_OCTET_STR; +rc = sesIP_get(rowreq_ctx, (char **)&var->val.string, &var->val_len ); + break; + + /* sesType(5)/INTEGER/ASN_INTEGER/long(u_long)//l/A/w/E/r/d/h */ + case COLUMN_SESTYPE: + var->val_len = sizeof(u_long); + var->type = ASN_INTEGER; +rc = sesType_get(rowreq_ctx, (u_long *)var->val.string ); + break; + + /* sesState(6)/INTEGER/ASN_INTEGER/long(u_long)//l/A/w/E/r/d/h */ + case COLUMN_SESSTATE: + var->val_len = sizeof(u_long); + var->type = ASN_INTEGER; +rc = sesState_get(rowreq_ctx, (u_long *)var->val.string ); + break; + + /* sesUptime(7)/GAUGE/ASN_GAUGE/u_long(u_long)//l/A/w/e/r/d/h */ + case COLUMN_SESUPTIME: + var->val_len = sizeof(u_long); + var->type = ASN_GAUGE; +rc = sesUptime_get(rowreq_ctx, (u_long *)var->val.string ); + break; + + /* sesCallingSID(8)/OCTETSTR/ASN_OCTET_STR/char(char)//L/A/w/e/r/d/h */ + case COLUMN_SESCALLINGSID: + var->type = ASN_OCTET_STR; +rc = sesCallingSID_get(rowreq_ctx, (char **)&var->val.string, &var->val_len ); + break; + + /* sesCalledSID(9)/OCTETSTR/ASN_OCTET_STR/char(char)//L/A/w/e/r/d/h */ + case COLUMN_SESCALLEDSID: + var->type = ASN_OCTET_STR; +rc = sesCalledSID_get(rowreq_ctx, (char **)&var->val.string, &var->val_len ); + break; + + default: + if (SESSIONTABLE_MIN_COL <= column && column <= SESSIONTABLE_MAX_COL) { + DEBUGMSGTL(("internal:sessionTable:_mfd_sessionTable_get_column", + "assume column %d is reserved\n", column)); + rc = MFD_SKIP; + } else { + snmp_log(LOG_ERR, + "unknown column %d in _sessionTable_get_column\n", column); + } + break; + } + + return rc; +} /* _sessionTable_get_column */ + +int +_mfd_sessionTable_get_values(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *agtreq_info, + netsnmp_request_info *requests) +{ + sessionTable_rowreq_ctx *rowreq_ctx = + netsnmp_container_table_row_extract(requests); + netsnmp_table_request_info * tri; + u_char * old_string; + void (*dataFreeHook)(void *); + int rc; + + DEBUGMSGTL(("internal:sessionTable:_mfd_sessionTable_get_values","called\n")); + + netsnmp_assert(NULL != rowreq_ctx); + + for(;requests; requests = requests->next) { + /* + * save old pointer, so we can free it if replaced + */ + old_string = requests->requestvb->val.string; + dataFreeHook = requests->requestvb->dataFreeHook; + if(NULL == requests->requestvb->val.string) { + requests->requestvb->val.string = requests->requestvb->buf; + requests->requestvb->val_len = sizeof(requests->requestvb->buf); + } + else if(requests->requestvb->buf == requests->requestvb->val.string) { + if(requests->requestvb->val_len != sizeof(requests->requestvb->buf)) + requests->requestvb->val_len = sizeof(requests->requestvb->buf); + } + + /* + * get column data + */ + tri = netsnmp_extract_table_info(requests); + if(NULL == tri) + continue; + + rc = _sessionTable_get_column(rowreq_ctx, requests->requestvb, tri->colnum); + if(rc) { + if(MFD_SKIP == rc) { + requests->requestvb->type = SNMP_NOSUCHINSTANCE; + rc = SNMP_ERR_NOERROR; + } + } + else if (NULL == requests->requestvb->val.string) { + snmp_log(LOG_ERR,"NULL varbind data pointer!\n"); + rc = SNMP_ERR_GENERR; + } + if(rc) + netsnmp_request_set_error(requests, SNMP_VALIDATE_ERR(rc)); + + /* + * if the buffer wasn't used previously for the old data (i.e. it + * was allcoated memory) and the get routine replaced the pointer, + * we need to free the previous pointer. + */ + if(old_string && (old_string != requests->requestvb->buf) && + (requests->requestvb->val.string != old_string)) { + if(dataFreeHook) + (*dataFreeHook)(old_string); + else + free(old_string); + } + } /* for results */ + + return SNMP_ERR_NOERROR; +} /* _mfd_sessionTable_get_values */ + + +/*********************************************************************** + * + * SET processing + * + ***********************************************************************/ + +/* + * SET PROCESSING NOT APPLICABLE (per MIB or user setting) + */ +/*********************************************************************** + * + * DATA ACCESS + * + ***********************************************************************/ +static void _container_free(netsnmp_container *container); + +/** + * @internal + */ +static int +_cache_load(netsnmp_cache *cache, void *vmagic) +{ + DEBUGMSGTL(("internal:sessionTable:_cache_load","called\n")); + + if((NULL == cache) || (NULL == cache->magic)) { + snmp_log(LOG_ERR, "invalid cache for sessionTable_cache_load\n"); + return -1; + } + + /** should only be called for an invalid or expired cache */ + netsnmp_assert((0 == cache->valid) || (1 == cache->expired)); + + /* + * call user code + */ + return sessionTable_container_load((netsnmp_container*)cache->magic); +} /* _cache_load */ + +/** + * @internal + */ +static void +_cache_free(netsnmp_cache *cache, void *magic) +{ + netsnmp_container *container; + + DEBUGMSGTL(("internal:sessionTable:_cache_free","called\n")); + + if((NULL == cache) || (NULL == cache->magic)) { + snmp_log(LOG_ERR, "invalid cache in sessionTable_cache_free\n"); + return; + } + + container = (netsnmp_container*)cache->magic; + + _container_free(container); +} /* _cache_free */ + +/** + * @internal + */ +static void +_container_item_free(sessionTable_rowreq_ctx *rowreq_ctx, void *context) +{ + DEBUGMSGTL(("internal:sessionTable:_container_item_free","called\n")); + + if(NULL == rowreq_ctx) + return; + + sessionTable_release_rowreq_ctx(rowreq_ctx); +} /* _container_item_free */ + +/** + * @internal + */ +static void +_container_free(netsnmp_container *container) +{ + DEBUGMSGTL(("internal:sessionTable:_container_free","called\n")); + + if (NULL == container) { + snmp_log(LOG_ERR, "invalid container in sessionTable_container_free\n"); + return; + } + + /* + * call user code + */ + sessionTable_container_free(container); + + /* + * free all items. inefficient, but easy. + */ + CONTAINER_CLEAR(container, + (netsnmp_container_obj_func *)_container_item_free, + NULL); +} /* _container_free */ + +/** + * @internal + * initialize the container with functions or wrappers + */ +void +_sessionTable_container_init(sessionTable_interface_ctx *if_ctx) +{ + DEBUGMSGTL(("internal:sessionTable:_sessionTable_container_init","called\n")); + + /* + * cache init + */ + if_ctx->cache = netsnmp_cache_create(30, /* timeout in seconds */ + _cache_load, _cache_free, + sessionTable_oid, + sessionTable_oid_size); + + if(NULL == if_ctx->cache) { + snmp_log(LOG_ERR, "error creating cache for sessionTable\n"); + return; + } + + if_ctx->cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET; + + sessionTable_container_init(&if_ctx->container, if_ctx->cache); + if(NULL == if_ctx->container) + if_ctx->container = netsnmp_container_find("sessionTable:table_container"); + if(NULL == if_ctx->container) { + snmp_log(LOG_ERR,"error creating container in " + "sessionTable_container_init\n"); + return; + } + + if (NULL != if_ctx->cache) + if_ctx->cache->magic = (void*)if_ctx->container; +} /* _sessionTable_container_init */ + +/** + * @internal + * shutdown the container with functions or wrappers + */ +void +_sessionTable_container_shutdown(sessionTable_interface_ctx *if_ctx) +{ + DEBUGMSGTL(("internal:sessionTable:_sessionTable_container_shutdown","called\n")); + + sessionTable_container_shutdown(if_ctx->container); + + _container_free(if_ctx->container); + +} /* _sessionTable_container_shutdown */ + + +sessionTable_rowreq_ctx * +sessionTable_row_find_by_mib_index(sessionTable_mib_index *mib_idx) +{ + sessionTable_rowreq_ctx *rowreq_ctx; + oid oid_tmp[MAX_OID_LEN]; + netsnmp_index oid_idx; + int rc; + + /* + * set up storage for OID + */ + oid_idx.oids = oid_tmp; + oid_idx.len = sizeof(oid_tmp)/sizeof(oid); + + /* + * convert + */ + rc = sessionTable_index_to_oid(&oid_idx, mib_idx); + if (MFD_SUCCESS != rc) + return NULL; + + rowreq_ctx = CONTAINER_FIND(sessionTable_if_ctx.container, &oid_idx); + + return rowreq_ctx; +} + |