/*
 * Note: this file originally auto-generated by mib2c using
 *       version : 1.67 $ of : mfd-interface.m2c,v $ 
 *
 * $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-features.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

/*
 * include our parent header 
 */
#include "ifTable.h"
#include "ifTable_defs.h"


#include <net-snmp/agent/table_container.h>
#include <net-snmp/library/container.h>

#include "ifTable_interface.h"

#include <ctype.h>

netsnmp_feature_child_of(ifTable_external_access, libnetsnmpmibs)

netsnmp_feature_require(row_merge)
netsnmp_feature_require(baby_steps)
netsnmp_feature_require(check_all_requests_error)
netsnmp_feature_child_of(iftable_container_get, ifTable_external_access)
netsnmp_feature_child_of(ifxtable_shutdown_interface, netsnmp_unused)
netsnmp_feature_child_of(ifXTable_container_size, ifXTable_external_access)
netsnmp_feature_child_of(ifXTable_registration_set, ifXTable_external_access)
netsnmp_feature_child_of(ifXTable_registration_get, ifXTable_external_access)
netsnmp_feature_child_of(ifXTable_container_get, ifXTable_external_access)
netsnmp_feature_child_of(iftable_container_size, ifTable_external_access)
netsnmp_feature_child_of(iftable_registration_set, ifTable_external_access)
netsnmp_feature_child_of(iftable_registration_get, ifTable_external_access)

/**********************************************************************
 **********************************************************************
 ***
 *** Table ifTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * IF-MIB::ifTable is subid 2 of interfaces.
 * Its status is Current.
 * OID: .1.3.6.1.2.1.2.2, length: 8
 */
typedef struct ifTable_interface_ctx_s {

    netsnmp_container *container;
    netsnmp_cache  *cache;

    ifTable_registration *user_ctx;

    netsnmp_table_registration_info tbl_info;

    netsnmp_baby_steps_access_methods access_multiplexer;

    u_int           table_dirty;

    u_long          last_changed;

} ifTable_interface_ctx;

static ifTable_interface_ctx ifTable_if_ctx;

static void     _ifTable_container_init(ifTable_interface_ctx * if_ctx);
static void     _ifTable_container_shutdown(ifTable_interface_ctx *
                                            if_ctx);

#ifndef NETSNMP_FEATURE_REMOVE_IFTABLE_CONTAINER_GET
netsnmp_container *
ifTable_container_get(void)
{
    return ifTable_if_ctx.container;
}
#endif /* NETSNMP_FEATURE_REMOVE_IFTABLE_CONTAINER_GET */

#ifndef NETSNMP_FEATURE_REMOVE_IFTABLE_REGISTRATION_GET
ifTable_registration *
ifTable_registration_get(void)
{
    return ifTable_if_ctx.user_ctx;
}
#endif /* NETSNMP_FEATURE_REMOVE_IFTABLE_REGISTRATION_GET */

#ifndef NETSNMP_FEATURE_REMOVE_IFTABLE_REGISTRATION_SET
ifTable_registration *
ifTable_registration_set(ifTable_registration * newreg)
{
    ifTable_registration *old = ifTable_if_ctx.user_ctx;
    ifTable_if_ctx.user_ctx = newreg;
    return old;
}
#endif /* NETSNMP_FEATURE_REMOVE_IFTABLE_REGISTRATION_SET */

#ifndef NETSNMP_FEATURE_REMOVE_IFTABLE_CONTAINER_SIZE
int
ifTable_container_size(void)
{
    return CONTAINER_SIZE(ifTable_if_ctx.container);
}
#endif /* NETSNMP_FEATURE_REMOVE_IFTABLE_CONTAINER_SIZE */

u_int
ifTable_dirty_get(void)
{
    return ifTable_if_ctx.table_dirty;
}

void
ifTable_dirty_set(u_int status)
{
    DEBUGMSGTL(("ifTable:ifTable_dirty_set",
                "called. was %d, now %d\n",
                ifTable_if_ctx.table_dirty, status));
    ifTable_if_ctx.table_dirty = status;
}

/*
 * ifTableLastChanged, which is not the last time that a row in
 * the table was changed, but rather is the last time a row was
 * added/deleted from the table.
 */
void
ifTable_lastChange_set(u_long table_changed)
{
    DEBUGMSGTL(("ifTable:ifTable_lastChanged_set",
                "called. was %ld, now %ld\n",
                ifTable_if_ctx.last_changed, table_changed));
    ifTable_if_ctx.last_changed = table_changed;
}

/*
 * mfd multiplexer modes
 */
static Netsnmp_Node_Handler _mfd_ifTable_pre_request;
static Netsnmp_Node_Handler _mfd_ifTable_post_request;
static Netsnmp_Node_Handler _mfd_ifTable_object_lookup;
static Netsnmp_Node_Handler _mfd_ifTable_get_values;
#if !(defined(NETSNMP_NO_WRITE_SUPPORT) || defined(NETSNMP_DISABLE_SET_SUPPORT))
static Netsnmp_Node_Handler _mfd_ifTable_check_objects;
static Netsnmp_Node_Handler _mfd_ifTable_undo_setup;
static Netsnmp_Node_Handler _mfd_ifTable_set_values;
static Netsnmp_Node_Handler _mfd_ifTable_undo_cleanup;
static Netsnmp_Node_Handler _mfd_ifTable_undo_values;
static Netsnmp_Node_Handler _mfd_ifTable_commit;
static Netsnmp_Node_Handler _mfd_ifTable_undo_commit;
static Netsnmp_Node_Handler _mfd_ifTable_irreversible_commit;
static Netsnmp_Node_Handler _mfd_ifTable_check_dependencies;

NETSNMP_STATIC_INLINE int _ifTable_undo_column(ifTable_rowreq_ctx *
                                               rowreq_ctx,
                                               netsnmp_variable_list * var,
                                               int column);
#endif /* NETSNMP_NO_WRITE_SUPPORT || NETSNMP_DISABLE_SET_SUPPORT */

ifTable_data   *ifTable_allocate_data(void);

/**
 * common init of container for ifTable and ifXTable
 */
void
if_mib_container_init(void)
{
    static int      done = 0;

    if (done)
        return;

    DEBUGMSGTL(("internal:ifTable:ifTable_container_init", "called\n"));

    done = 1;

    /*
     * set up the container. This is outside the rewrite ifdef, because
     * the container is used by the ifXTable too..
     */
    _ifTable_container_init(&ifTable_if_ctx);
}

/**
 * @internal
 * Initialize the table ifTable 
 *    (Define its contents and how it's structured)
 */
void
_ifTable_initialize_interface(ifTable_registration * reg_ptr, u_long flags)
{
    netsnmp_baby_steps_access_methods *access_multiplexer =
        &ifTable_if_ctx.access_multiplexer;
    netsnmp_table_registration_info *tbl_info = &ifTable_if_ctx.tbl_info;
    netsnmp_handler_registration *reginfo;
    netsnmp_mib_handler *handler;
    int             mfd_modes = 0;

    DEBUGMSGTL(("internal:ifTable:_ifTable_initialize_interface",
                "called\n"));

    (void) if_mib_container_init();
    if (NULL == ifTable_if_ctx.container)
        return;                 /* msg already logged */

#ifndef USING_MIBII_INTERFACES_MODULE
    /*************************************************
     *
     * save interface context for ifTable
     */
    /*
     * Setting up the table's definition
     */
    netsnmp_table_helper_add_indexes(tbl_info, ASN_INTEGER,
                                               /** index: ifIndex */
                                     0);

    /*
     * Define the minimum and maximum accessible columns.  This
     * optimizes retrieval. 
     */
    tbl_info->min_column = IFTABLE_MIN_COL;
    tbl_info->max_column = IFTABLE_MAX_COL;

    /*
     * save users context
     */
    ifTable_if_ctx.user_ctx = reg_ptr;

    /*
     * call data access initialization code
     */
    ifTable_init_data(reg_ptr);

    /*
     * access_multiplexer: REQUIRED wrapper for get request handling
     */
    access_multiplexer->object_lookup = _mfd_ifTable_object_lookup;
    access_multiplexer->get_values = _mfd_ifTable_get_values;

    /*
     * no wrappers yet
     */
    access_multiplexer->pre_request = _mfd_ifTable_pre_request;
    access_multiplexer->post_request = _mfd_ifTable_post_request;


#if !(defined(NETSNMP_NO_WRITE_SUPPORT) || defined(NETSNMP_DISABLE_SET_SUPPORT))
    /*
     * REQUIRED wrappers for set request handling
     */
    access_multiplexer->object_syntax_checks = _mfd_ifTable_check_objects;
    access_multiplexer->undo_setup = _mfd_ifTable_undo_setup;
    access_multiplexer->undo_cleanup = _mfd_ifTable_undo_cleanup;
    access_multiplexer->set_values = _mfd_ifTable_set_values;
    access_multiplexer->undo_sets = _mfd_ifTable_undo_values;

    /*
     * no wrappers yet
     */
    access_multiplexer->commit = _mfd_ifTable_commit;
    access_multiplexer->undo_commit = _mfd_ifTable_undo_commit;
    access_multiplexer->irreversible_commit =
        _mfd_ifTable_irreversible_commit;

    /*
     * REQUIRED for tables with dependencies
     */
    access_multiplexer->consistency_checks =
        _mfd_ifTable_check_dependencies;
#endif /* NETSNMP_NO_WRITE_SUPPORT || NETSNMP_DISABLE_SET_SUPPORT */

    /*************************************************
     *
     * Create a registration, save our reg data, register table.
     */
    DEBUGMSGTL(("ifTable:init_ifTable",
                "Registering ifTable as a mibs-for-dummies table.\n"));
    handler =
        netsnmp_baby_steps_access_multiplexer_get(access_multiplexer);
    reginfo =
        netsnmp_handler_registration_create("ifTable", handler,
                                            ifTable_oid, ifTable_oid_size,
                                            HANDLER_CAN_BABY_STEP |
#if !(defined(NETSNMP_NO_WRITE_SUPPORT) || defined(NETSNMP_DISABLE_SET_SUPPORT))
                                            HANDLER_CAN_RWRITE
#else
                                            HANDLER_CAN_RONLY
#endif /* NETSNMP_NO_WRITE_SUPPORT || NETSNMP_DISABLE_SET_SUPPORT */
            );

    if (NULL == reginfo) {
        snmp_log(LOG_ERR, "error registering table ifTable\n");
        return;
    }
    reginfo->my_reg_void = &ifTable_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->pre_request)
        mfd_modes |= BABY_STEP_PRE_REQUEST;
    if (access_multiplexer->post_request)
        mfd_modes |= BABY_STEP_POST_REQUEST;

#if !(defined(NETSNMP_NO_WRITE_SUPPORT) || defined(NETSNMP_DISABLE_SET_SUPPORT))
    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->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;
#endif /* NETSNMP_NO_WRITE_SUPPORT || NETSNMP_DISABLE_SET_SUPPORT */

    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,
                                            ifTable_if_ctx.container,
                                            TABLE_CONTAINER_KEY_NETSNMP_INDEX);
    netsnmp_inject_handler(reginfo, handler);

    /*************************************************
     *
     * inject cache helper
     */
    if (NULL != ifTable_if_ctx.cache) {
        handler = netsnmp_cache_handler_get(ifTable_if_ctx.cache);
        netsnmp_inject_handler(reginfo, handler);
    }

    /*
     * register table
     */
    netsnmp_register_table(reginfo, tbl_info);


    /*
     * register ifTableLastChanged
     */
    {
        const oid       iftlc_oid[] = { IFTABLE_LAST_CHANGE };
        netsnmp_register_watched_scalar2(netsnmp_create_handler_registration
                                        ("ifTableLastChanged", NULL,
                                         iftlc_oid, OID_LENGTH(iftlc_oid),
                                         HANDLER_CAN_RONLY),
                                        netsnmp_create_watcher_info((void
                                                                     *)
                                                                    &ifTable_if_ctx.
                                                                    last_changed,
                                                                    sizeof
                                                                    (u_long),
                                                                    ASN_TIMETICKS,
                                                                    WATCHER_FIXED_SIZE));
    }
#endif                          /* USING_MIBII_INTERFACES_MODULE */

}                               /* _ifTable_initialize_interface */

/**
 * @internal
 * Shutdown the table ifTable
 */
void
_ifTable_shutdown_interface(ifTable_registration * reg_ptr)
{
    /*
     * shutdown the container
     */
    _ifTable_container_shutdown(&ifTable_if_ctx);
}

void
ifTable_valid_columns_set(netsnmp_column_info *vc)
{
    ifTable_if_ctx.tbl_info.valid_columns = vc;
}                               /* ifTable_valid_columns_set */

/**
 * @internal
 * convert the index component stored in the context to an oid
 */
int
ifTable_index_to_oid(netsnmp_index * oid_idx, ifTable_mib_index * mib_idx)
{
    int             err = SNMP_ERR_NOERROR;

    /*
     * temp storage for parsing indexes
     */
    /*
     * ifIndex(1)/InterfaceIndex/ASN_INTEGER/long(long)//l/A/w/e/R/d/H
     */
    netsnmp_variable_list var_ifIndex;

    /*
     * set up varbinds
     */
    memset(&var_ifIndex, 0x00, sizeof(var_ifIndex));
    var_ifIndex.type = ASN_INTEGER;

    /*
     * chain temp index varbinds together
     */
    var_ifIndex.next_variable = NULL;


    DEBUGMSGTL(("verbose:ifTable:ifTable_index_to_oid", "called\n"));

    /*
     * ifIndex(1)/InterfaceIndex/ASN_INTEGER/long(long)//l/A/w/e/R/d/H 
     */
    snmp_set_var_value(&var_ifIndex, (u_char *) & mib_idx->ifIndex,
                       sizeof(mib_idx->ifIndex));


    err = build_oid_noalloc(oid_idx->oids, oid_idx->len, &oid_idx->len,
                            NULL, 0, &var_ifIndex);
    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_ifIndex);

    return err;
}                               /* ifTable_index_to_oid */

/**
 * extract ifTable indexes from a netsnmp_index
 *
 * @retval SNMP_ERR_NOERROR  : no error
 * @retval SNMP_ERR_GENERR   : error
 */
int
ifTable_index_from_oid(netsnmp_index * oid_idx,
                       ifTable_mib_index * mib_idx)
{
    int             err = SNMP_ERR_NOERROR;

    /*
     * temp storage for parsing indexes
     */
    /*
     * ifIndex(1)/InterfaceIndex/ASN_INTEGER/long(long)//l/A/w/e/R/d/H
     */
    netsnmp_variable_list var_ifIndex;

    /*
     * set up varbinds
     */
    memset(&var_ifIndex, 0x00, sizeof(var_ifIndex));
    var_ifIndex.type = ASN_INTEGER;

    /*
     * chain temp index varbinds together
     */
    var_ifIndex.next_variable = NULL;


    DEBUGMSGTL(("verbose:ifTable:ifTable_index_from_oid", "called\n"));

    /*
     * parse the oid into the individual index components
     */
    err = parse_oid_indexes(oid_idx->oids, oid_idx->len, &var_ifIndex);
    if (err == SNMP_ERR_NOERROR) {
        /*
         * copy out values
         */
        mib_idx->ifIndex = *((long *) var_ifIndex.val.string);
    }

    /*
     * parsing may have allocated memory. free it.
     */
    snmp_reset_var_buffers(&var_ifIndex);

    return err;
}                               /* ifTable_index_from_oid */


/*
 * ifTable_allocate_data
 *
 * Purpose: create new ifTable_data.
 */
ifTable_data   *
ifTable_allocate_data(void)
{
    ifTable_data   *rtn = SNMP_MALLOC_TYPEDEF(ifTable_data);

    DEBUGMSGTL(("verbose:ifTable:ifTable_allocate_data", "called\n"));

    if (NULL == rtn) {
        snmp_log(LOG_ERR, "unable to malloc memory for new "
                 "ifTable_data.\n");
    }

    return rtn;
}                               /* ifTable_allocate_data */

/*
 * ifTable_release_data
 *
 * Purpose: release ifTable data.
 */
void
ifTable_release_data(ifTable_data * data)
{
    DEBUGMSGTL(("verbose:ifTable:ifTable_release_data", "called\n"));

    free(data);
}                               /* ifTable_release_data */

/*
 *********************************************************************
 * @internal
 * allocate resources for a ifTable_rowreq_ctx
 */
ifTable_rowreq_ctx *
ifTable_allocate_rowreq_ctx(void *user_init_ctx)
{
    ifTable_rowreq_ctx *rowreq_ctx =
        SNMP_MALLOC_TYPEDEF(ifTable_rowreq_ctx);

    DEBUGMSGTL(("internal:ifTable:ifTable_allocate_rowreq_ctx",
                "called\n"));

    if (NULL == rowreq_ctx) {
        snmp_log(LOG_ERR, "Couldn't allocate memory for a "
                 "ifTable_rowreq_ctx.\n");
        return NULL;
    }

    rowreq_ctx->oid_idx.oids = rowreq_ctx->oid_tmp;

    rowreq_ctx->ifTable_data_list = NULL;

    /*
     * if we allocated data, call init routine
     */
    if (!(rowreq_ctx->rowreq_flags & MFD_ROW_DATA_FROM_USER)) {
        if (SNMPERR_SUCCESS !=
            ifTable_rowreq_ctx_init(rowreq_ctx, user_init_ctx)) {
            ifTable_release_rowreq_ctx(rowreq_ctx);
            rowreq_ctx = NULL;
        }
    }

    return rowreq_ctx;
}                               /* ifTable_allocate_rowreq_ctx */

/*
 * @internal
 * release resources for a ifTable_rowreq_ctx
 */
void
ifTable_release_rowreq_ctx(ifTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("internal:ifTable:ifTable_release_rowreq_ctx",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    ifTable_rowreq_ctx_cleanup(rowreq_ctx);

    if (rowreq_ctx->undo) {
        ifTable_release_data(rowreq_ctx->undo);
        rowreq_ctx->undo = NULL;
    }

    /*
     * free index oid pointer
     */
    if (rowreq_ctx->oid_idx.oids != rowreq_ctx->oid_tmp)
        free(rowreq_ctx->oid_idx.oids);

    SNMP_FREE(rowreq_ctx);
}                               /* ifTable_release_rowreq_ctx */

/**
 * @internal
 * wrapper
 */
static int
_mfd_ifTable_pre_request(netsnmp_mib_handler *handler,
                         netsnmp_handler_registration *reginfo,
                         netsnmp_agent_request_info *agtreq_info,
                         netsnmp_request_info *requests)
{
    int             rc;

    DEBUGMSGTL(("internal:ifTable:_mfd_ifTable_pre_request", "called\n"));

    if (1 != netsnmp_row_merge_status_first(reginfo, agtreq_info)) {
        DEBUGMSGTL(("internal:ifTable",
                    "skipping additional pre_request\n"));
        return SNMP_ERR_NOERROR;
    }

    rc = ifTable_pre_request(ifTable_if_ctx.user_ctx);
    if (MFD_SUCCESS != rc) {
        /*
         * nothing we can do about it but log it
         */
        DEBUGMSGTL(("ifTable", "error %d from "
                    "ifTable_pre_request\n", rc));
        netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc));
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ifTable_pre_request */

/**
 * @internal
 * wrapper
 */
static int
_mfd_ifTable_post_request(netsnmp_mib_handler *handler,
                          netsnmp_handler_registration *reginfo,
                          netsnmp_agent_request_info *agtreq_info,
                          netsnmp_request_info *requests)
{
    ifTable_rowreq_ctx *rowreq_ctx = (ifTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);
    int             rc, packet_rc;

    DEBUGMSGTL(("internal:ifTable:_mfd_ifTable_post_request", "called\n"));

    /*
     * release row context, if deleted
     */
    if (rowreq_ctx && (rowreq_ctx->rowreq_flags & MFD_ROW_DELETED))
        ifTable_release_rowreq_ctx(rowreq_ctx);

    /*
     * wait for last call before calling user
     */
    if (1 != netsnmp_row_merge_status_last(reginfo, agtreq_info)) {
        DEBUGMSGTL(("internal:ifTable",
                    "waiting for last post_request\n"));
        return SNMP_ERR_NOERROR;
    }

    packet_rc = netsnmp_check_all_requests_error(agtreq_info->asp, 0);
    if ((MFD_SUCCESS != packet_rc) && ifTable_dirty_get()) {
        /*
         * we shouldn't get here. the undo steps should also clear
         * the dirty flags.
         */
        snmp_log(LOG_WARNING, "ifTable dirty flag set in post_request "
                 "but status != SUCCESS.\n");
    }

    rc = ifTable_post_request(ifTable_if_ctx.user_ctx, packet_rc);
    if (MFD_SUCCESS != rc) {
        /*
         * nothing we can do about it but log it
         */
        DEBUGMSGTL(("ifTable", "error %d from "
                    "ifTable_post_request\n", rc));
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ifTable_post_request */

/**
 * @internal
 * wrapper
 */
static int
_mfd_ifTable_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;
    ifTable_rowreq_ctx *rowreq_ctx = (ifTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);

    DEBUGMSGTL(("internal:ifTable:_mfd_ifTable_object_lookup",
                "called\n"));

    /*
     * get our context from mfd
     * ifTable_interface_ctx *if_ctx =
     *             (ifTable_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
        ifTable_row_prep(rowreq_ctx);

    return SNMP_VALIDATE_ERR(rc);
}                               /* _mfd_ifTable_object_lookup */

/***********************************************************************
 *
 * GET processing
 *
 ***********************************************************************/
/*
 * @internal
 * Retrieve the value for a particular column
 */
NETSNMP_STATIC_INLINE int
_ifTable_get_column(ifTable_rowreq_ctx * rowreq_ctx,
                    netsnmp_variable_list * var, int column)
{
    int             rc = SNMPERR_SUCCESS;

    DEBUGMSGTL(("internal:ifTable:_mfd_ifTable_get_column",
                "called for %d\n", column));


    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * (INDEX) ifIndex(1)/InterfaceIndex/ASN_INTEGER/long(long)//l/A/w/e/R/d/H 
         */
    case COLUMN_IFINDEX:
        var->type = ASN_INTEGER;
        var->val_len = sizeof(long);
        (*var->val.integer) = rowreq_ctx->tbl_idx.ifIndex;
        break;

        /*
         * ifDescr(2)/DisplayString/ASN_OCTET_STR/char(char)//L/A/w/e/R/d/H 
         */
    case COLUMN_IFDESCR:
        var->type = ASN_OCTET_STR;
        rc = ifDescr_get(rowreq_ctx, (char **) &var->val.string,
                         &var->val_len);
        break;

        /*
         * ifType(3)/IANAifType/ASN_INTEGER/long(u_long)//l/A/w/E/r/d/h 
         */
    case COLUMN_IFTYPE:
        var->val_len = sizeof(u_long);
        var->type = ASN_INTEGER;
        rc = ifType_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * ifMtu(4)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFMTU:
        var->val_len = sizeof(long);
        var->type = ASN_INTEGER;
        rc = ifMtu_get(rowreq_ctx, (long *) var->val.string);
        break;

        /*
         * ifSpeed(5)/GAUGE/ASN_GAUGE/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFSPEED:
        var->val_len = sizeof(u_long);
        var->type = ASN_GAUGE;
        rc = ifSpeed_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * ifPhysAddress(6)/PhysAddress/ASN_OCTET_STR/char(char)//L/A/w/e/r/d/H 
         */
    case COLUMN_IFPHYSADDRESS:
        var->type = ASN_OCTET_STR;
        rc = ifPhysAddress_get(rowreq_ctx, (char **) &var->val.string,
                               &var->val_len);
        break;

        /*
         * ifAdminStatus(7)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_IFADMINSTATUS:
        var->val_len = sizeof(u_long);
        var->type = ASN_INTEGER;
        rc = ifAdminStatus_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * ifOperStatus(8)/INTEGER/ASN_INTEGER/long(u_long)//l/A/w/E/r/d/h 
         */
    case COLUMN_IFOPERSTATUS:
        var->val_len = sizeof(u_long);
        var->type = ASN_INTEGER;
        rc = ifOperStatus_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * ifLastChange(9)/TICKS/ASN_TIMETICKS/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFLASTCHANGE:
        var->val_len = sizeof(u_long);
        var->type = ASN_TIMETICKS;
        rc = ifLastChange_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * ifInOctets(10)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFINOCTETS:
        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = ifInOctets_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * ifInUcastPkts(11)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFINUCASTPKTS:
        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = ifInUcastPkts_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * ifInNUcastPkts(12)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFINNUCASTPKTS:
        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = ifInNUcastPkts_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * ifInDiscards(13)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFINDISCARDS:
        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = ifInDiscards_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * ifInErrors(14)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFINERRORS:
        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = ifInErrors_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * ifInUnknownProtos(15)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFINUNKNOWNPROTOS:
        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = ifInUnknownProtos_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * ifOutOctets(16)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFOUTOCTETS:
        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = ifOutOctets_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * ifOutUcastPkts(17)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFOUTUCASTPKTS:
        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = ifOutUcastPkts_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * ifOutNUcastPkts(18)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFOUTNUCASTPKTS:
        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = ifOutNUcastPkts_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * ifOutDiscards(19)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFOUTDISCARDS:
        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = ifOutDiscards_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * ifOutErrors(20)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFOUTERRORS:
        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = ifOutErrors_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * ifOutQLen(21)/GAUGE/ASN_GAUGE/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFOUTQLEN:
        var->val_len = sizeof(u_long);
        var->type = ASN_GAUGE;
        rc = ifOutQLen_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * ifSpecific(22)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/A/w/e/r/d/h 
         */
    case COLUMN_IFSPECIFIC:
        var->type = ASN_OBJECT_ID;
        rc = ifSpecific_get(rowreq_ctx, (oid **) & var->val.string,
                            &var->val_len);
        break;

    default:
        snmp_log(LOG_ERR, "unknown column %d in _ifTable_get_column\n",
                 column);
        break;
    }

    return rc;
}                               /* _ifTable_get_column */

int
_mfd_ifTable_get_values(netsnmp_mib_handler *handler,
                        netsnmp_handler_registration *reginfo,
                        netsnmp_agent_request_info *agtreq_info,
                        netsnmp_request_info *requests)
{
    ifTable_rowreq_ctx *rowreq_ctx = (ifTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);
    netsnmp_table_request_info *tri;
    u_char         *old_string;
    void            (*dataFreeHook) (void *);
    int             rc;

    DEBUGMSGTL(("internal:ifTable:_mfd_ifTable_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 = _ifTable_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_ifTable_get_values */



#if !(defined(NETSNMP_NO_WRITE_SUPPORT) || defined(NETSNMP_DISABLE_SET_SUPPORT))

/***********************************************************************
 *
 * SET processing
 *
 ***********************************************************************/

/*----------------------------------------------------------------------
 *
 * SET: Syntax checks
 *
 *---------------------------------------------------------------------*/
/*
 * @internal
 * Check the syntax for a particular column
 */
NETSNMP_STATIC_INLINE int
_ifTable_check_column(ifTable_rowreq_ctx * rowreq_ctx,
                      netsnmp_variable_list * var, int column)
{
    int             rc = SNMPERR_SUCCESS;

    DEBUGMSGTL(("internal:ifTable:_ifTable_check_column",
                "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {
        /*
         * (INDEX) ifIndex(1)/InterfaceIndex/ASN_INTEGER/long(long)//l/A/w/e/R/d/H 
         */
    case COLUMN_IFINDEX:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;

        /*
         * ifDescr(2)/DisplayString/ASN_OCTET_STR/char(char)//L/A/w/e/R/d/H 
         */
    case COLUMN_IFDESCR:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ifType(3)/IANAifType/ASN_INTEGER/long(u_long)//l/A/w/E/r/d/h 
         */
    case COLUMN_IFTYPE:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ifMtu(4)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFMTU:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ifSpeed(5)/GAUGE/ASN_GAUGE/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFSPEED:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ifPhysAddress(6)/PhysAddress/ASN_OCTET_STR/char(char)//L/A/w/e/r/d/H 
         */
    case COLUMN_IFPHYSADDRESS:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ifAdminStatus(7)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_IFADMINSTATUS:
        /** special case: we are using exernal storage w/smaller data size
         ** for storage, so we can't use sizeof on data context. So we
         ** just check that it's the expected size. The enum tests below
         ** will ensure that there is no data overflow. */
        rc = netsnmp_check_vb_type_and_size(var, ASN_INTEGER,
                                            sizeof(u_long));
        /*
         * check that the value is one of defined enums 
         */
        if ((SNMPERR_SUCCESS == rc)
            && (*var->val.integer != IFADMINSTATUS_UP)
            && (*var->val.integer != IFADMINSTATUS_DOWN)
            && (*var->val.integer != IFADMINSTATUS_TESTING)
            ) {
            rc = SNMP_ERR_WRONGVALUE;
        }
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("ifTable:_ifTable_check_column:ifAdminStatus",
                        "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = ifAdminStatus_check_value(rowreq_ctx,
                                           *((u_long *) var->val.string));
            if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
                && (MFD_NOT_VALID_NOW != rc)) {
                snmp_log(LOG_ERR,
                         "bad rc %d from ifAdminStatus_check_value\n", rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * ifOperStatus(8)/INTEGER/ASN_INTEGER/long(u_long)//l/A/w/E/r/d/h 
         */
    case COLUMN_IFOPERSTATUS:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ifLastChange(9)/TICKS/ASN_TIMETICKS/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFLASTCHANGE:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ifInOctets(10)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFINOCTETS:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ifInUcastPkts(11)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFINUCASTPKTS:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ifInNUcastPkts(12)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFINNUCASTPKTS:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ifInDiscards(13)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFINDISCARDS:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ifInErrors(14)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFINERRORS:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ifInUnknownProtos(15)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFINUNKNOWNPROTOS:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ifOutOctets(16)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFOUTOCTETS:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ifOutUcastPkts(17)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFOUTUCASTPKTS:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ifOutNUcastPkts(18)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFOUTNUCASTPKTS:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ifOutDiscards(19)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFOUTDISCARDS:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ifOutErrors(20)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFOUTERRORS:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ifOutQLen(21)/GAUGE/ASN_GAUGE/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IFOUTQLEN:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ifSpecific(22)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/A/w/e/r/d/h 
         */
    case COLUMN_IFSPECIFIC:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

    default:   /** We shouldn't get here */
        rc = SNMP_ERR_GENERR;
        snmp_log(LOG_ERR, "unknown column %d in _ifTable_check_column\n",
                 column);
    }

    return rc;
}                               /* _ifTable_check_column */

int
_mfd_ifTable_check_objects(netsnmp_mib_handler *handler,
                           netsnmp_handler_registration *reginfo,
                           netsnmp_agent_request_info *agtreq_info,
                           netsnmp_request_info *requests)
{
    ifTable_rowreq_ctx *rowreq_ctx = (ifTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);
    netsnmp_table_request_info *tri;
    int             rc;

    DEBUGMSGTL(("internal:ifTable:_mfd_ifTable_check_objects",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    for (; requests; requests = requests->next) {

        /*
         * get column number from table request info, and check that column
         */
        tri = netsnmp_extract_table_info(requests);
        if (NULL == tri)
            continue;

        rc = _ifTable_check_column(rowreq_ctx, requests->requestvb,
                                   tri->colnum);
        if (rc) {
            netsnmp_request_set_error(requests, SNMP_VALIDATE_ERR(rc));
            break;
        }

    }                           /* for results */

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ifTable_check_objects */

/*----------------------------------------------------------------------
 *
 * SET: check dependencies
 *
 *---------------------------------------------------------------------*/
/*
 * @internal
 * Check dependencies wrapper
 */
static int
_mfd_ifTable_check_dependencies(netsnmp_mib_handler *handler,
                                netsnmp_handler_registration *reginfo,
                                netsnmp_agent_request_info *agtreq_info,
                                netsnmp_request_info *requests)
{
    int             rc;
    ifTable_rowreq_ctx *rowreq_ctx = (ifTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);
    DEBUGMSGTL(("internal:ifTable:_mfd_ifTable_check_dependencies",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    rc = ifTable_check_dependencies(rowreq_ctx);
    if (rc) {
        DEBUGMSGTL(("ifTable:mfd", "error %d from "
                    "ifTable_check_dependencies\n", rc));
        netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc));
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ifTable_check_dependencies */

/*----------------------------------------------------------------------
 *
 * SET: Undo setup
 *
 *---------------------------------------------------------------------*/
/*
 * @internal
 * Set the value for a particular column
 */
NETSNMP_STATIC_INLINE int
_ifTable_undo_setup_column(ifTable_rowreq_ctx * rowreq_ctx, int column)
{
    int             rc = SNMPERR_SUCCESS;

    DEBUGMSGTL(("internal:ifTable:_ifTable_undo_setup_column",
                "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * ifAdminStatus(7)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_IFADMINSTATUS:
        rowreq_ctx->column_set_flags |= COLUMN_IFADMINSTATUS_FLAG;
        rc = ifAdminStatus_undo_setup(rowreq_ctx);
        break;

    default:
        snmp_log(LOG_ERR,
                 "unknown column %d in _ifTable_undo_setup_column\n",
                 column);
        break;
    }

    return rc;
}                               /* _ifTable_undo_setup_column */

int
_mfd_ifTable_undo_setup_allocate(ifTable_rowreq_ctx *rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    if (NULL == rowreq_ctx)
        return MFD_ERROR;

    /*
     * other tables share our container/context and call
     * this function. so we need to check and see if
     * someone else already allocated the ifentry
     */
    if (NULL == rowreq_ctx->undo) {
        rowreq_ctx->undo = ifTable_allocate_data();
        if (NULL == rowreq_ctx->undo) {
            /** msg already logged */
            rc = SNMP_ERR_RESOURCEUNAVAILABLE;
        }
        else {
            rowreq_ctx->undo->ifentry =
                netsnmp_access_interface_entry_create(rowreq_ctx->data.ifentry->
                                                      name,
                                                      rowreq_ctx->data.ifentry->
                                                      index);
            if (NULL == rowreq_ctx->undo->ifentry) {
                rc = SNMP_ERR_RESOURCEUNAVAILABLE;
                ifTable_release_data(rowreq_ctx->undo);
                rowreq_ctx->undo = NULL;
            }
            else {
                netsnmp_access_interface_entry_copy(rowreq_ctx->undo->ifentry,
                                                    rowreq_ctx->data.ifentry);
                netsnmp_assert(0 == rowreq_ctx->undo_ref_count);
            }
        }
    }
    ++rowreq_ctx->undo_ref_count;
    DEBUGMSGTL(("internal:ifTable:_mfd_ifTable_undo_setup_allocate",
                "++undo_refcount = %d\n",rowreq_ctx->undo_ref_count));

    return rc;
}

/**
 * @internal
 * undo setup
 */
int
_mfd_ifTable_undo_setup(netsnmp_mib_handler *handler,
                        netsnmp_handler_registration *reginfo,
                        netsnmp_agent_request_info *agtreq_info,
                        netsnmp_request_info *requests)
{
    int             rc;
    ifTable_rowreq_ctx *rowreq_ctx = (ifTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);

    DEBUGMSGTL(("internal:ifTable:_mfd_ifTable_undo_setup", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * allocate undo context
     */
    rc = _mfd_ifTable_undo_setup_allocate(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        netsnmp_request_set_error_all(requests, rc);
        return SNMP_ERR_NOERROR;
    }

    /*
     * row undo setup
     */
    rc = ifTable_undo_setup(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        DEBUGMSGTL(("ifTable:mfd", "error %d from "
                    "ifTable_undo_setup\n", rc));
        netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc));
    } else {
        /*
         * column undo setup
         */
        netsnmp_table_request_info *tri;
        for (; requests; requests = requests->next) {
            /*
             * set column data
             */
            tri = netsnmp_extract_table_info(requests);
            if (NULL == tri)
                continue;

            rc = _ifTable_undo_setup_column(rowreq_ctx, tri->colnum);
            if (MFD_SUCCESS != rc) {
                DEBUGMSGTL(("ifTable:mfd", "error %d from "
                            "ifTable_undo_setup_column\n", rc));
                netsnmp_set_request_error(agtreq_info, requests,
                                          SNMP_VALIDATE_ERR(rc));
            }
        }                       /* for results */
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ifTable_undo_setup */

void
_mfd_ifTable_undo_setup_release(ifTable_rowreq_ctx *rowreq_ctx)
{
    netsnmp_assert(rowreq_ctx->undo_ref_count > 0);
    --rowreq_ctx->undo_ref_count;
    snmp_log(LOG_ERR, "undo_refcount at %d\n", rowreq_ctx->undo_ref_count);

    if (0 == rowreq_ctx->undo_ref_count) {
        netsnmp_access_interface_entry_free(rowreq_ctx->undo->ifentry);
        ifTable_release_data(rowreq_ctx->undo);
        rowreq_ctx->undo = NULL;
    }
}

/**
 * @internal
 * undo setup
 */
int
_mfd_ifTable_undo_cleanup(netsnmp_mib_handler *handler,
                          netsnmp_handler_registration *reginfo,
                          netsnmp_agent_request_info *agtreq_info,
                          netsnmp_request_info *requests)
{
    ifTable_rowreq_ctx *rowreq_ctx = (ifTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);
    int             rc;

    DEBUGMSGTL(("internal:ifTable:_mfd_ifTable_undo_cleanup", "called\n"));

    /*
     * failed row create in early stages has no rowreq_ctx
     */
    if (NULL == rowreq_ctx)
        return MFD_SUCCESS;

    /*
     * call user cleanup
     */
    rc = ifTable_undo_cleanup(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        /*
         * nothing we can do about it but log it
         */
        DEBUGMSGTL(("ifTable:mfd", "error %d from "
                    "ifTable_undo_cleanup\n", rc));
    }

    /*
     * release undo context, if needed
     */
    _mfd_ifTable_undo_setup_release(rowreq_ctx);


    return SNMP_ERR_NOERROR;
}                               /* _mfd_ifTable_undo_cleanup */

/*----------------------------------------------------------------------
 *
 * SET: Set values
 *
 *---------------------------------------------------------------------*/
/*
 * @internal
 * Set the value for a particular column
 */
NETSNMP_STATIC_INLINE int
_ifTable_set_column(ifTable_rowreq_ctx * rowreq_ctx,
                    netsnmp_variable_list * var, int column)
{
    int             rc = SNMPERR_SUCCESS;

    DEBUGMSGTL(("internal:ifTable:_ifTable_set_column",
                "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * ifAdminStatus(7)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_IFADMINSTATUS:
        rowreq_ctx->column_set_flags |= COLUMN_IFADMINSTATUS_FLAG;
        rc = ifAdminStatus_set(rowreq_ctx, *((u_long *) var->val.string));
        break;

    default:
        snmp_log(LOG_ERR, "unknown column %d in _ifTable_set_column\n",
                 column);
        rc = SNMP_ERR_GENERR;
        break;
    }

    return rc;
}                               /* _ifTable_set_column */

int
_mfd_ifTable_set_values(netsnmp_mib_handler *handler,
                        netsnmp_handler_registration *reginfo,
                        netsnmp_agent_request_info *agtreq_info,
                        netsnmp_request_info *requests)
{
    ifTable_rowreq_ctx *rowreq_ctx = (ifTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);
    netsnmp_table_request_info *tri;
    int             rc = SNMP_ERR_NOERROR;

    DEBUGMSGTL(("internal:ifTable:_mfd_ifTable_set_values", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    rowreq_ctx->column_set_flags = 0;
    for (; requests; requests = requests->next) {
        /*
         * set column data
         */
        tri = netsnmp_extract_table_info(requests);
        if (NULL == tri)
            continue;

        rc = _ifTable_set_column(rowreq_ctx,
                                 requests->requestvb, tri->colnum);
        if (MFD_SUCCESS != rc) {
            DEBUGMSGTL(("ifTable:mfd", "error %d from "
                        "ifTable_set_column\n", rc));
            netsnmp_set_request_error(agtreq_info, requests,
                                      SNMP_VALIDATE_ERR(rc));
        }
    }                           /* for results */

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ifTable_set_values */

/*----------------------------------------------------------------------
 *
 * SET: commit
 *
 *---------------------------------------------------------------------*/
/**
 * @internal
 * commit the values
 */
int
_mfd_ifTable_commit(netsnmp_mib_handler *handler,
                    netsnmp_handler_registration *reginfo,
                    netsnmp_agent_request_info *agtreq_info,
                    netsnmp_request_info *requests)
{
    int             rc;
    ifTable_rowreq_ctx *rowreq_ctx = (ifTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);

    DEBUGMSGTL(("internal:ifTable:_mfd_ifTable_commit", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    rc = ifTable_commit(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        DEBUGMSGTL(("ifTable:mfd", "error %d from "
                    "ifTable_commit\n", rc));
        netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc));
    }

    if (rowreq_ctx->rowreq_flags & MFD_ROW_DIRTY) {
        /*
         * if we successfully commited this row, set the dirty flag. Use the
         * current value + 1 (i.e. dirty = # rows changed).
         * this is checked in post_request...
         */
        ifTable_dirty_set(ifTable_dirty_get() + 1);     /* set table dirty flag */
    }

    if (rowreq_ctx->rowreq_flags & MFD_ROW_DIRTY) {
        /*
         * if we successfully commited this row, set the dirty flag. Use the
         * current value + 1 (i.e. dirty = # rows changed).
         * this is checked in post_request...
         */
        ifTable_dirty_set(ifTable_dirty_get() + 1);     /* set table dirty flag */
    }

    return SNMP_ERR_NOERROR;
}

int
_mfd_ifTable_undo_commit(netsnmp_mib_handler *handler,
                         netsnmp_handler_registration *reginfo,
                         netsnmp_agent_request_info *agtreq_info,
                         netsnmp_request_info *requests)
{
    int             rc;
    ifTable_rowreq_ctx *rowreq_ctx = (ifTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);

    DEBUGMSGTL(("internal:ifTable:_mfd_ifTable_undo_commit", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    if (rowreq_ctx->rowreq_flags & MFD_ROW_DIRTY) {
        u_int           d = ifTable_dirty_get();

        netsnmp_assert(d != 0);
        if (d)
            ifTable_dirty_set(d - 1);
    }

    rc = ifTable_undo_commit(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        /*
         * nothing we can do about it but log it
         */
        DEBUGMSGTL(("ifTable:mfd", "error %d from "
                    "ifTable_undo_commit\n", rc));
    }

    if (rowreq_ctx->rowreq_flags & MFD_ROW_DIRTY) {
        snmp_log(LOG_WARNING,
                 "ifTable row dirty flag still set after undo_commit\n");
        rowreq_ctx->rowreq_flags &= ~MFD_ROW_DIRTY;
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ifTable_commit */

/*----------------------------------------------------------------------
 *
 * SET: Undo
 *
 *---------------------------------------------------------------------*/
/**
 * @internal
 * undo the value for a particular column
 */
NETSNMP_STATIC_INLINE int
_ifTable_undo_column(ifTable_rowreq_ctx * rowreq_ctx,
                     netsnmp_variable_list * var, int column)
{
    int             rc = SNMPERR_SUCCESS;

    DEBUGMSGTL(("internal:ifTable:_ifTable_undo_column",
                "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * ifAdminStatus(7)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_IFADMINSTATUS:
        rc = ifAdminStatus_undo(rowreq_ctx);
        break;

    default:
        snmp_log(LOG_ERR, "unknown column %d in _ifTable_undo_column\n",
                 column);
        break;
    }

    return rc;
}                               /* _ifTable_undo_column */

int
_mfd_ifTable_undo_values(netsnmp_mib_handler *handler,
                         netsnmp_handler_registration *reginfo,
                         netsnmp_agent_request_info *agtreq_info,
                         netsnmp_request_info *requests)
{
    int             rc;
    ifTable_rowreq_ctx *rowreq_ctx = (ifTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);
    netsnmp_table_request_info *tri;

    DEBUGMSGTL(("internal:ifTable:_mfd_ifTable_undo_values", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    rc = ifTable_undo(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        /*
         * nothing we can do about it but log it
         */
        DEBUGMSGTL(("ifTable:mfd", "error %d from " "ifTable_undo\n", rc));
    }

    for (; requests; requests = requests->next) {
        /*
         * set column data
         */
        tri = netsnmp_extract_table_info(requests);
        if (NULL == tri)
            continue;

        rc = _ifTable_undo_column(rowreq_ctx, requests->requestvb,
                                  tri->colnum);
        if (MFD_SUCCESS != rc) {
            /*
             * nothing we can do about it but log it
             */
            DEBUGMSGTL(("ifTable:mfd", "error %d from "
                        "ifTable_undo_column\n", rc));
        }
    }                           /* for results */

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ifTable_undo_values */

/*----------------------------------------------------------------------
 *
 * SET: irreversible commit
 *
 *---------------------------------------------------------------------*/
/**
 * @internal
 * commit irreversible actions
 */
int
_mfd_ifTable_irreversible_commit(netsnmp_mib_handler *handler,
                                 netsnmp_handler_registration *reginfo,
                                 netsnmp_agent_request_info *agtreq_info,
                                 netsnmp_request_info *requests)
{
    ifTable_rowreq_ctx *rowreq_ctx = (ifTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);

    DEBUGMSGTL(("internal:ifTable:_mfd_ifTable_irreversible:commit",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * check for and handle row creation/deletion
     * and update column exist flags...
     */
    if (rowreq_ctx->rowreq_flags & MFD_ROW_DELETED) {
        CONTAINER_REMOVE(ifTable_if_ctx.container, rowreq_ctx);
    } else {
        if (rowreq_ctx->column_set_flags) {
            rowreq_ctx->column_set_flags = 0;
        }
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ifTable_irreversible_commit */
#endif /* NETSNMP_NO_WRITE_SUPPORT || NETSNMP_DISABLE_SET_SUPPORT */

/***********************************************************************
 *
 * DATA ACCESS
 *
 ***********************************************************************/
static void     _container_free(netsnmp_container *container);

/**
 * @internal
 */
static int
_cache_load(netsnmp_cache * cache, void *vmagic)
{
    DEBUGMSGTL(("internal:ifTable:_cache_load", "called\n"));

    if ((NULL == cache) || (NULL == cache->magic)) {
        snmp_log(LOG_ERR, "invalid cache for ifTable_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 ifTable_container_load((netsnmp_container *) cache->magic);
}                               /* _cache_load */

/**
 * @internal
 */
static void
_cache_free(netsnmp_cache * cache, void *magic)
{
    netsnmp_container *container;

    DEBUGMSGTL(("internal:ifTable:_cache_free", "called\n"));

    if ((NULL == cache) || (NULL == cache->magic)) {
        snmp_log(LOG_ERR, "invalid cache in ifTable_cache_free\n");
        return;
    }

    container = (netsnmp_container *) cache->magic;

    _container_free(container);
}                               /* _cache_free */

/**
 * @internal
 */
static void
_container_item_free(ifTable_rowreq_ctx * rowreq_ctx, void *context)
{
    DEBUGMSGTL(("internal:ifTable:_container_item_free", "called\n"));

    if (NULL == rowreq_ctx)
        return;

    ifTable_release_rowreq_ctx(rowreq_ctx);
}                               /* _container_item_free */

/**
 * @internal
 */
static void
_container_free(netsnmp_container *container)
{
    DEBUGMSGTL(("internal:ifTable:_container_free", "called\n"));

    if (NULL == container) {
        snmp_log(LOG_ERR, "invalid container in ifTable_container_free\n");
        return;
    }

    /*
     * call user code
     */
    ifTable_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
_ifTable_container_init(ifTable_interface_ctx * if_ctx)
{
    DEBUGMSGTL(("internal:ifTable:_ifTable_container_init", "called\n"));

    /*
     * cache init
     */
    if_ctx->cache = netsnmp_cache_create(30,    /* timeout in seconds */
                                         _cache_load, _cache_free,
                                         ifTable_oid, ifTable_oid_size);

    if (NULL == if_ctx->cache) {
        snmp_log(LOG_ERR, "error creating cache for ifTable\n");
        return;
    }

    if_ctx->cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET;

    ifTable_container_init(&if_ctx->container, if_ctx->cache);
    if (NULL == if_ctx->container)
        if_ctx->container =
            netsnmp_container_find("ifTable:table_container");
    if (NULL == if_ctx->container) {
        snmp_log(LOG_ERR, "error creating container in "
                 "ifTable_container_init\n");
        return;
    }

    if_ctx->container->container_name = strdup("ifTable container");
    if (NULL != if_ctx->cache)
        if_ctx->cache->magic = (void *) if_ctx->container;
}                               /* _ifTable_container_init */

/**
 * @internal
 * shutdown the container with functions or wrappers
 */
void
_ifTable_container_shutdown(ifTable_interface_ctx * if_ctx)
{
    DEBUGMSGTL(("internal:ifTable:_ifTable_container_shutdown",
                "called\n"));

    ifTable_container_shutdown(if_ctx->container);

    _container_free(if_ctx->container);

}                               /* _ifTable_container_shutdown */


#ifndef NETSNMP_FEATURE_REMOVE_IFTABLE_EXTERNAL_ACCESS
ifTable_rowreq_ctx *
ifTable_row_find_by_mib_index(ifTable_mib_index * mib_idx)
{
    ifTable_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 = ifTable_index_to_oid(&oid_idx, mib_idx);
    if (MFD_SUCCESS != rc)
        return NULL;

    rowreq_ctx = (ifTable_rowreq_ctx*)CONTAINER_FIND(ifTable_if_ctx.container, &oid_idx);

    return rowreq_ctx;
}
#endif /* NETSNMP_FEATURE_REMOVE_IFTABLE_EXTERNAL_ACCESS */
