/*
 * 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 "etherStatsTable.h"


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

#include "etherStatsTable_interface.h"

#include <ctype.h>

/**********************************************************************
 **********************************************************************
 ***
 *** Table etherStatsTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * RMON-MIB::etherStatsTable is subid 1 of statistics.
 * Its status is Current.
 * OID: .1.3.6.1.2.1.16.1.1, length: 9
 */
typedef struct etherStatsTable_interface_ctx_s {

    netsnmp_container *container;
    netsnmp_cache  *cache;

    etherStatsTable_registration *user_ctx;

    netsnmp_table_registration_info tbl_info;

    netsnmp_baby_steps_access_methods access_multiplexer;

    u_int           table_dirty;

} etherStatsTable_interface_ctx;

static etherStatsTable_interface_ctx etherStatsTable_if_ctx;

static void    
_etherStatsTable_container_init(etherStatsTable_interface_ctx * if_ctx);
static void    
_etherStatsTable_container_shutdown(etherStatsTable_interface_ctx *
                                    if_ctx);


netsnmp_container *
etherStatsTable_container_get(void)
{
    return etherStatsTable_if_ctx.container;
}

etherStatsTable_registration *
etherStatsTable_registration_get(void)
{
    return etherStatsTable_if_ctx.user_ctx;
}

etherStatsTable_registration *
etherStatsTable_registration_set(etherStatsTable_registration * newreg)
{
    etherStatsTable_registration *old = etherStatsTable_if_ctx.user_ctx;
    etherStatsTable_if_ctx.user_ctx = newreg;
    return old;
}

int
etherStatsTable_container_size(void)
{
    return CONTAINER_SIZE(etherStatsTable_if_ctx.container);
}

u_int
etherStatsTable_dirty_get(void)
{
    return etherStatsTable_if_ctx.table_dirty;
}

void
etherStatsTable_dirty_set(u_int status)
{
    DEBUGMSGTL(("etherStatsTable:etherStatsTable_dirty_set",
                "called. was %d, now %d\n",
                etherStatsTable_if_ctx.table_dirty, status));
    etherStatsTable_if_ctx.table_dirty = status;
}

/*
 * mfd multiplexer modes
 */
static Netsnmp_Node_Handler _mfd_etherStatsTable_pre_request;
static Netsnmp_Node_Handler _mfd_etherStatsTable_post_request;
static Netsnmp_Node_Handler _mfd_etherStatsTable_object_lookup;
static Netsnmp_Node_Handler _mfd_etherStatsTable_get_values;
static Netsnmp_Node_Handler _mfd_etherStatsTable_check_objects;
static Netsnmp_Node_Handler _mfd_etherStatsTable_undo_setup;
static Netsnmp_Node_Handler _mfd_etherStatsTable_set_values;
static Netsnmp_Node_Handler _mfd_etherStatsTable_undo_cleanup;
static Netsnmp_Node_Handler _mfd_etherStatsTable_undo_values;
static Netsnmp_Node_Handler _mfd_etherStatsTable_commit;
static Netsnmp_Node_Handler _mfd_etherStatsTable_undo_commit;
static Netsnmp_Node_Handler _mfd_etherStatsTable_irreversible_commit;

NETSNMP_STATIC_INLINE int
_etherStatsTable_undo_column(etherStatsTable_rowreq_ctx * rowreq_ctx,
                             netsnmp_variable_list * var, int column);

NETSNMP_STATIC_INLINE int
_etherStatsTable_check_indexes(etherStatsTable_rowreq_ctx * rowreq_ctx);

etherStatsTable_data *etherStatsTable_allocate_data(void);

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

    DEBUGMSGTL(("internal:etherStatsTable:_etherStatsTable_initialize_interface", "called\n"));


    /*************************************************
     *
     * save interface context for etherStatsTable
     */
    /*
     * Setting up the table's definition
     */
    netsnmp_table_helper_add_indexes(tbl_info, ASN_INTEGER,
                                               /** index: etherStatsIndex */
                                     0);

    /*
     * Define the minimum and maximum accessible columns.  This
     * optimizes retrival. 
     */
    tbl_info->min_column = ETHERSTATSTABLE_MIN_COL;
    tbl_info->max_column = ETHERSTATSTABLE_MAX_COL;

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

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

    /*
     * set up the container
     */
    _etherStatsTable_container_init(&etherStatsTable_if_ctx);
    if (NULL == etherStatsTable_if_ctx.container) {
        snmp_log(LOG_ERR,
                 "could not initialize container for etherStatsTable\n");
        return;
    }

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

    /*
     * no wrappers yet
     */
    access_multiplexer->pre_request = _mfd_etherStatsTable_pre_request;
    access_multiplexer->post_request = _mfd_etherStatsTable_post_request;


    /*
     * REQUIRED wrappers for set request handling
     */
    access_multiplexer->object_syntax_checks =
        _mfd_etherStatsTable_check_objects;
    access_multiplexer->undo_setup = _mfd_etherStatsTable_undo_setup;
    access_multiplexer->undo_cleanup = _mfd_etherStatsTable_undo_cleanup;
    access_multiplexer->set_values = _mfd_etherStatsTable_set_values;
    access_multiplexer->undo_sets = _mfd_etherStatsTable_undo_values;

    /*
     * no wrappers yet
     */
    access_multiplexer->commit = _mfd_etherStatsTable_commit;
    access_multiplexer->undo_commit = _mfd_etherStatsTable_undo_commit;
    access_multiplexer->irreversible_commit =
        _mfd_etherStatsTable_irreversible_commit;

    /*************************************************
     *
     * Create a registration, save our reg data, register table.
     */
    DEBUGMSGTL(("etherStatsTable:init_etherStatsTable",
                "Registering etherStatsTable as a mibs-for-dummies table.\n"));
    handler =
        netsnmp_baby_steps_access_multiplexer_get(access_multiplexer);
    reginfo =
        netsnmp_handler_registration_create("etherStatsTable", handler,
                                            etherStatsTable_oid,
                                            etherStatsTable_oid_size,
                                            HANDLER_CAN_BABY_STEP |
                                            HANDLER_CAN_RWRITE);
    if (NULL == reginfo) {
        snmp_log(LOG_ERR, "error registering table etherStatsTable\n");
        return;
    }
    reginfo->my_reg_void = &etherStatsTable_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,
                                            etherStatsTable_if_ctx.
                                            container,
                                            TABLE_CONTAINER_KEY_NETSNMP_INDEX);
    netsnmp_inject_handler(reginfo, handler);

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

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

}                               /* _etherStatsTable_initialize_interface */

/**
 * @internal
 * Shutdown the table etherStatsTable
 */
void
_etherStatsTable_shutdown_interface(etherStatsTable_registration * reg_ptr)
{
    /*
     * shutdown the container
     */
    _etherStatsTable_container_shutdown(&etherStatsTable_if_ctx);
}

void
etherStatsTable_valid_columns_set(netsnmp_column_info *vc)
{
    etherStatsTable_if_ctx.tbl_info.valid_columns = vc;
}                               /* etherStatsTable_valid_columns_set */

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

    /*
     * temp storage for parsing indexes
     */
    /*
     * etherStatsIndex(1)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/R/d/h
     */
    netsnmp_variable_list var_etherStatsIndex;

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

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


    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsTable_index_to_oid",
                "called\n"));

    /*
     * etherStatsIndex(1)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/R/d/h 
     */
    snmp_set_var_value(&var_etherStatsIndex,
                       (u_char *) & mib_idx->etherStatsIndex,
                       sizeof(mib_idx->etherStatsIndex));


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

    return err;
}                               /* etherStatsTable_index_to_oid */

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

    /*
     * temp storage for parsing indexes
     */
    /*
     * etherStatsIndex(1)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/R/d/h
     */
    netsnmp_variable_list var_etherStatsIndex;

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

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


    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsTable_index_from_oid",
                "called\n"));

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


    }

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

    return err;
}                               /* etherStatsTable_index_from_oid */


/*
 * etherStatsTable_allocate_data
 *
 * Purpose: create new etherStatsTable_data.
 */
etherStatsTable_data *
etherStatsTable_allocate_data(void)
{
    etherStatsTable_data *rtn = SNMP_MALLOC_TYPEDEF(etherStatsTable_data);

    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsTable_allocate_data",
                "called\n"));

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

    return rtn;
}                               /* etherStatsTable_allocate_data */

/*
 * etherStatsTable_release_data
 *
 * Purpose: release etherStatsTable data.
 */
void
etherStatsTable_release_data(etherStatsTable_data * data)
{
    DEBUGMSGTL(("verbose:etherStatsTable:etherStatsTable_release_data",
                "called\n"));

    free(data);
}                               /* etherStatsTable_release_data */

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

    DEBUGMSGTL(("internal:etherStatsTable:etherStatsTable_allocate_rowreq_ctx", "called\n"));

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

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

    rowreq_ctx->etherStatsTable_data_list = NULL;

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

    return rowreq_ctx;
}                               /* etherStatsTable_allocate_rowreq_ctx */

/*
 * @internal
 * release resources for a etherStatsTable_rowreq_ctx
 */
void
etherStatsTable_release_rowreq_ctx(etherStatsTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("internal:etherStatsTable:etherStatsTable_release_rowreq_ctx", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    etherStatsTable_rowreq_ctx_cleanup(rowreq_ctx);

    if (rowreq_ctx->undo)
        etherStatsTable_release_data(rowreq_ctx->undo);

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

    SNMP_FREE(rowreq_ctx);
}                               /* etherStatsTable_release_rowreq_ctx */

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

    DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_pre_request", "called\n"));

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_etherStatsTable_pre_request */

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

    DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_post_request", "called\n"));

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

    /*
     * wait for last call before calling user
     */
    if (1 != netsnmp_row_merge_status_last(reginfo, agtreq_info)) {
        DEBUGMSGTL(("internal:etherStatsTable",
                    "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) && etherStatsTable_dirty_get()) {
        /*
         * we shouldn't get here. the undo steps should also clear
         * the dirty flags.
         */
        snmp_log(LOG_WARNING,
                 "etherStatsTable dirty flag set in post_request "
                 "but status != SUCCESS.\n");
    }

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_etherStatsTable_post_request */

/**
 * @internal
 * wrapper
 */
static etherStatsTable_rowreq_ctx *
_mfd_etherStatsTable_rowreq_from_index(netsnmp_index * oid_idx,
                                       int *rc_ptr)
{
    etherStatsTable_rowreq_ctx *rowreq_ctx;
    etherStatsTable_mib_index mib_idx;
    int             rc;

    DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_rowreq_from_index", "called\n"));

    if (NULL == rc_ptr)
        rc_ptr = &rc;
    *rc_ptr = MFD_SUCCESS;

    memset(&mib_idx, 0x0, sizeof(mib_idx));

    /*
     * try to parse oid
     */
    *rc_ptr = etherStatsTable_index_from_oid(oid_idx, &mib_idx);
    if (MFD_SUCCESS != *rc_ptr) {
        DEBUGMSGT(("etherStatsTable", "error parsing index\n"));
        return NULL;
    }

    /*
     * allocate new context
     */
    rowreq_ctx = etherStatsTable_allocate_rowreq_ctx(NULL);
    if (NULL == rowreq_ctx) {
        *rc_ptr = MFD_ERROR;
        return NULL;            /* msg already logged */
    }

    memcpy(&rowreq_ctx->tbl_idx, &mib_idx, sizeof(mib_idx));

    /*
     * check indexes
     */
    *rc_ptr = _etherStatsTable_check_indexes(rowreq_ctx);
    if (MFD_SUCCESS != *rc_ptr) {
        netsnmp_assert((*rc_ptr == SNMP_ERR_NOCREATION) ||
                       (*rc_ptr == SNMP_ERR_INCONSISTENTNAME));
        etherStatsTable_release_rowreq_ctx(rowreq_ctx);
        return NULL;
    }

    /*
     * copy indexes
     */
    rowreq_ctx->oid_idx.len = oid_idx->len;
    memcpy(rowreq_ctx->oid_idx.oids, oid_idx->oids,
           oid_idx->len * sizeof(oid));

    return rowreq_ctx;
}                               /* _mfd_etherStatsTable_rowreq_from_index */


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

    DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_object_lookup", "called\n"));

    /*
     * get our context from mfd
     * etherStatsTable_interface_ctx *if_ctx =
     *             (etherStatsTable_interface_ctx *)reginfo->my_reg_void;
     */

    if (NULL == rowreq_ctx) {
        netsnmp_table_request_info *tblreq_info;
        netsnmp_index   oid_idx;

        tblreq_info = netsnmp_extract_table_info(requests);
        if (NULL == tblreq_info) {
            snmp_log(LOG_ERR, "request had no table info\n");
            return MFD_ERROR;
        }

        /*
         * try create rowreq
         */
        oid_idx.oids = tblreq_info->index_oid;
        oid_idx.len = tblreq_info->index_oid_len;

        rowreq_ctx = _mfd_etherStatsTable_rowreq_from_index(&oid_idx, &rc);
        if (MFD_SUCCESS == rc) {
            netsnmp_assert(NULL != rowreq_ctx);
            rowreq_ctx->rowreq_flags |= MFD_ROW_CREATED;
            /*
             * add rowreq_ctx to request data lists
             */
            netsnmp_container_table_row_insert(requests,
                                               (netsnmp_index *)
                                               rowreq_ctx);
        }
    }

    if (MFD_SUCCESS != rc)
        netsnmp_request_set_error_all(requests, rc);
    else
        etherStatsTable_row_prep(rowreq_ctx);

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

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

    DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_get_column",
                "called for %d\n", column));


    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * (INDEX) etherStatsIndex(1)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/R/d/h 
         */
    case COLUMN_ETHERSTATSINDEX:
        var->type = ASN_INTEGER;
        var->val_len = sizeof(long);
        (*var->val.integer) = rowreq_ctx->tbl_idx.etherStatsIndex;
        break;

        /*
         * etherStatsDataSource(2)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/A/W/e/r/d/h 
         */
    case COLUMN_ETHERSTATSDATASOURCE:
        if (!
            (COLUMN_ETHERSTATSDATASOURCE_FLAG & rowreq_ctx->
             column_exists_flags)) {
            DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_get_column", "column %d (etherStatsDataSource) doesn't exist\n", column));
            return MFD_SKIP;
        }

        var->type = ASN_OBJECT_ID;
        rc = etherStatsDataSource_get(rowreq_ctx,
                                      (oid **) & var->val.string,
                                      &var->val_len);
        break;

        /*
         * etherStatsDropEvents(3)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSDROPEVENTS:
        if (!
            (COLUMN_ETHERSTATSDROPEVENTS_FLAG & rowreq_ctx->
             column_exists_flags)) {
            DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_get_column", "column %d (etherStatsDropEvents) doesn't exist\n", column));
            return MFD_SKIP;
        }

        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = etherStatsDropEvents_get(rowreq_ctx,
                                      (u_long *) var->val.string);
        break;

        /*
         * etherStatsOctets(4)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSOCTETS:
        if (!
            (COLUMN_ETHERSTATSOCTETS_FLAG & rowreq_ctx->
             column_exists_flags)) {
            DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_get_column", "column %d (etherStatsOctets) doesn't exist\n", column));
            return MFD_SKIP;
        }

        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = etherStatsOctets_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * etherStatsPkts(5)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSPKTS:
        if (!
            (COLUMN_ETHERSTATSPKTS_FLAG & rowreq_ctx->
             column_exists_flags)) {
            DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_get_column", "column %d (etherStatsPkts) doesn't exist\n", column));
            return MFD_SKIP;
        }

        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = etherStatsPkts_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * etherStatsBroadcastPkts(6)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSBROADCASTPKTS:
        if (!
            (COLUMN_ETHERSTATSBROADCASTPKTS_FLAG & rowreq_ctx->
             column_exists_flags)) {
            DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_get_column", "column %d (etherStatsBroadcastPkts) doesn't exist\n", column));
            return MFD_SKIP;
        }

        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = etherStatsBroadcastPkts_get(rowreq_ctx,
                                         (u_long *) var->val.string);
        break;

        /*
         * etherStatsMulticastPkts(7)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSMULTICASTPKTS:
        if (!
            (COLUMN_ETHERSTATSMULTICASTPKTS_FLAG & rowreq_ctx->
             column_exists_flags)) {
            DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_get_column", "column %d (etherStatsMulticastPkts) doesn't exist\n", column));
            return MFD_SKIP;
        }

        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = etherStatsMulticastPkts_get(rowreq_ctx,
                                         (u_long *) var->val.string);
        break;

        /*
         * etherStatsCRCAlignErrors(8)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSCRCALIGNERRORS:
        if (!
            (COLUMN_ETHERSTATSCRCALIGNERRORS_FLAG & rowreq_ctx->
             column_exists_flags)) {
            DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_get_column", "column %d (etherStatsCRCAlignErrors) doesn't exist\n", column));
            return MFD_SKIP;
        }

        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = etherStatsCRCAlignErrors_get(rowreq_ctx,
                                          (u_long *) var->val.string);
        break;

        /*
         * etherStatsUndersizePkts(9)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSUNDERSIZEPKTS:
        if (!
            (COLUMN_ETHERSTATSUNDERSIZEPKTS_FLAG & rowreq_ctx->
             column_exists_flags)) {
            DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_get_column", "column %d (etherStatsUndersizePkts) doesn't exist\n", column));
            return MFD_SKIP;
        }

        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = etherStatsUndersizePkts_get(rowreq_ctx,
                                         (u_long *) var->val.string);
        break;

        /*
         * etherStatsOversizePkts(10)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSOVERSIZEPKTS:
        if (!
            (COLUMN_ETHERSTATSOVERSIZEPKTS_FLAG & rowreq_ctx->
             column_exists_flags)) {
            DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_get_column", "column %d (etherStatsOversizePkts) doesn't exist\n", column));
            return MFD_SKIP;
        }

        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = etherStatsOversizePkts_get(rowreq_ctx,
                                        (u_long *) var->val.string);
        break;

        /*
         * etherStatsFragments(11)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSFRAGMENTS:
        if (!
            (COLUMN_ETHERSTATSFRAGMENTS_FLAG & rowreq_ctx->
             column_exists_flags)) {
            DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_get_column", "column %d (etherStatsFragments) doesn't exist\n", column));
            return MFD_SKIP;
        }

        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = etherStatsFragments_get(rowreq_ctx,
                                     (u_long *) var->val.string);
        break;

        /*
         * etherStatsJabbers(12)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSJABBERS:
        if (!
            (COLUMN_ETHERSTATSJABBERS_FLAG & rowreq_ctx->
             column_exists_flags)) {
            DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_get_column", "column %d (etherStatsJabbers) doesn't exist\n", column));
            return MFD_SKIP;
        }

        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = etherStatsJabbers_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * etherStatsCollisions(13)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSCOLLISIONS:
        if (!
            (COLUMN_ETHERSTATSCOLLISIONS_FLAG & rowreq_ctx->
             column_exists_flags)) {
            DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_get_column", "column %d (etherStatsCollisions) doesn't exist\n", column));
            return MFD_SKIP;
        }

        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = etherStatsCollisions_get(rowreq_ctx,
                                      (u_long *) var->val.string);
        break;

        /*
         * etherStatsPkts64Octets(14)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSPKTS64OCTETS:
        if (!
            (COLUMN_ETHERSTATSPKTS64OCTETS_FLAG & rowreq_ctx->
             column_exists_flags)) {
            DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_get_column", "column %d (etherStatsPkts64Octets) doesn't exist\n", column));
            return MFD_SKIP;
        }

        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = etherStatsPkts64Octets_get(rowreq_ctx,
                                        (u_long *) var->val.string);
        break;

        /*
         * etherStatsPkts65to127Octets(15)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSPKTS65TO127OCTETS:
        if (!
            (COLUMN_ETHERSTATSPKTS65TO127OCTETS_FLAG & rowreq_ctx->
             column_exists_flags)) {
            DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_get_column", "column %d (etherStatsPkts65to127Octets) doesn't exist\n", column));
            return MFD_SKIP;
        }

        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = etherStatsPkts65to127Octets_get(rowreq_ctx,
                                             (u_long *) var->val.string);
        break;

        /*
         * etherStatsPkts128to255Octets(16)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSPKTS128TO255OCTETS:
        if (!
            (COLUMN_ETHERSTATSPKTS128TO255OCTETS_FLAG & rowreq_ctx->
             column_exists_flags)) {
            DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_get_column", "column %d (etherStatsPkts128to255Octets) doesn't exist\n", column));
            return MFD_SKIP;
        }

        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = etherStatsPkts128to255Octets_get(rowreq_ctx,
                                              (u_long *) var->val.string);
        break;

        /*
         * etherStatsPkts256to511Octets(17)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSPKTS256TO511OCTETS:
        if (!
            (COLUMN_ETHERSTATSPKTS256TO511OCTETS_FLAG & rowreq_ctx->
             column_exists_flags)) {
            DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_get_column", "column %d (etherStatsPkts256to511Octets) doesn't exist\n", column));
            return MFD_SKIP;
        }

        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = etherStatsPkts256to511Octets_get(rowreq_ctx,
                                              (u_long *) var->val.string);
        break;

        /*
         * etherStatsPkts512to1023Octets(18)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSPKTS512TO1023OCTETS:
        if (!
            (COLUMN_ETHERSTATSPKTS512TO1023OCTETS_FLAG & rowreq_ctx->
             column_exists_flags)) {
            DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_get_column", "column %d (etherStatsPkts512to1023Octets) doesn't exist\n", column));
            return MFD_SKIP;
        }

        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = etherStatsPkts512to1023Octets_get(rowreq_ctx,
                                               (u_long *) var->val.string);
        break;

        /*
         * etherStatsPkts1024to1518Octets(19)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSPKTS1024TO1518OCTETS:
        if (!
            (COLUMN_ETHERSTATSPKTS1024TO1518OCTETS_FLAG & rowreq_ctx->
             column_exists_flags)) {
            DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_get_column", "column %d (etherStatsPkts1024to1518Octets) doesn't exist\n", column));
            return MFD_SKIP;
        }

        var->val_len = sizeof(u_long);
        var->type = ASN_COUNTER;
        rc = etherStatsPkts1024to1518Octets_get(rowreq_ctx,
                                                (u_long *) var->val.
                                                string);
        break;

        /*
         * etherStatsOwner(20)/OwnerString/ASN_OCTET_STR/char(char)//L/A/W/e/R/d/h 
         */
    case COLUMN_ETHERSTATSOWNER:
        if (!
            (COLUMN_ETHERSTATSOWNER_FLAG & rowreq_ctx->
             column_exists_flags)) {
            DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_get_column", "column %d (etherStatsOwner) doesn't exist\n", column));
            return MFD_SKIP;
        }

        var->type = ASN_OCTET_STR;
        rc = etherStatsOwner_get(rowreq_ctx, (char **) &var->val.string,
                                 &var->val_len);
        break;

        /*
         * etherStatsStatus(21)/EntryStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_ETHERSTATSSTATUS:
        if (!
            (COLUMN_ETHERSTATSSTATUS_FLAG & rowreq_ctx->
             column_exists_flags)) {
            DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_get_column", "column %d (etherStatsStatus) doesn't exist\n", column));
            return MFD_SKIP;
        }

        var->val_len = sizeof(u_long);
        var->type = ASN_INTEGER;
        rc = etherStatsStatus_get(rowreq_ctx, (u_long *) var->val.string);
        break;

    default:
        if (ETHERSTATSTABLE_MIN_COL <= column
            && column <= ETHERSTATSTABLE_MAX_COL) {
            DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_get_column", "assume column %d is reserved\n", column));
            rc = MFD_SKIP;
        } else {
            snmp_log(LOG_ERR,
                     "unknown column %d in _etherStatsTable_get_column.\n",
                     column);
        }
        break;
    }

    return rc;
}                               /* _etherStatsTable_get_column */

int
_mfd_etherStatsTable_get_values(netsnmp_mib_handler *handler,
                                netsnmp_handler_registration *reginfo,
                                netsnmp_agent_request_info *agtreq_info,
                                netsnmp_request_info *requests)
{
    etherStatsTable_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:etherStatsTable:_mfd_etherStatsTable_get_values",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    DEBUGMSGTL(("9:etherStatsTable:_mfd_etherStatsTable_get_values",
                "exists %u\n", rowreq_ctx->column_exists_flags));

    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 = _etherStatsTable_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_etherStatsTable_get_values */

NETSNMP_STATIC_INLINE int
_etherStatsTable_check_indexes(etherStatsTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = SNMPERR_SUCCESS;

    DEBUGMSGTL(("internal:etherStatsTable:_etherStatsTable_check_indexes",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);


    /*
     * (INDEX) etherStatsIndex(1)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/R/d/h 
     */
    /*
     * check defined range(s). 
     */
    if ((SNMPERR_SUCCESS == rc)
        && ((rowreq_ctx->tbl_idx.etherStatsIndex < 1)
            || (rowreq_ctx->tbl_idx.etherStatsIndex > 65535))
        ) {
        rc = SNMP_ERR_WRONGVALUE;
    }
    if (MFD_SUCCESS != rc)
        return rc;
    rc = etherStatsIndex_check_index(rowreq_ctx);
    if (MFD_SUCCESS != rc)
        return SNMP_ERR_NOCREATION;

    /*
     * if individual parts look ok, check them as a whole
     */
    return etherStatsTable_validate_index(etherStatsTable_if_ctx.user_ctx,
                                          rowreq_ctx);
}                               /* _etherStatsTable_check_indexes */

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

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

    DEBUGMSGTL(("internal:etherStatsTable:_etherStatsTable_check_column",
                "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {
        /*
         * (INDEX) etherStatsIndex(1)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/R/d/h 
         */
    case COLUMN_ETHERSTATSINDEX:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;

        /*
         * etherStatsDataSource(2)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/A/W/e/r/d/h 
         */
    case COLUMN_ETHERSTATSDATASOURCE:
        rc = netsnmp_check_vb_type_and_max_size(var, ASN_OBJECT_ID,
                                                sizeof(rowreq_ctx->data.
                                                       etherStatsDataSource));
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("etherStatsTable:_etherStatsTable_check_column:etherStatsDataSource", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = etherStatsDataSource_check_value(rowreq_ctx,
                                                  (oid *) var->val.string,
                                                  var->val_len);
            if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
                && (MFD_NOT_VALID_NOW != rc)) {
                snmp_log(LOG_ERR,
                         "bad rc %d from etherStatsDataSource_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * etherStatsDropEvents(3)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSDROPEVENTS:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * etherStatsOctets(4)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSOCTETS:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * etherStatsPkts(5)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSPKTS:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * etherStatsBroadcastPkts(6)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSBROADCASTPKTS:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * etherStatsMulticastPkts(7)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSMULTICASTPKTS:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * etherStatsCRCAlignErrors(8)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSCRCALIGNERRORS:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * etherStatsUndersizePkts(9)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_ETHERSTATSUNDERSIZEPKTS:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

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

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

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

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

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

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

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

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

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

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

        /*
         * etherStatsOwner(20)/OwnerString/ASN_OCTET_STR/char(char)//L/A/W/e/R/d/h 
         */
    case COLUMN_ETHERSTATSOWNER:
        rc = netsnmp_check_vb_type_and_max_size(var, ASN_OCTET_STR,
                                                sizeof(rowreq_ctx->data.
                                                       etherStatsOwner));
        /*
         * check defined range(s). 
         */
        if ((SNMPERR_SUCCESS == rc)
            && ((var->val_len < 0) || (var->val_len > 127))
            ) {
            rc = SNMP_ERR_WRONGLENGTH;
        }
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("etherStatsTable:_etherStatsTable_check_column:etherStatsOwner", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = etherStatsOwner_check_value(rowreq_ctx,
                                             (char *) var->val.string,
                                             var->val_len);
            if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
                && (MFD_NOT_VALID_NOW != rc)) {
                snmp_log(LOG_ERR,
                         "bad rc %d from etherStatsOwner_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * etherStatsStatus(21)/EntryStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_ETHERSTATSSTATUS:
        rc = netsnmp_check_vb_type_and_size(var, ASN_INTEGER,
                                            sizeof(rowreq_ctx->data.
                                                   etherStatsStatus));
        /*
         * check that the value is one of defined enums 
         */
        if ((SNMPERR_SUCCESS == rc)
            && (*var->val.integer != ENTRYSTATUS_VALID)
            && (*var->val.integer != ENTRYSTATUS_CREATEREQUEST)
            && (*var->val.integer != ENTRYSTATUS_UNDERCREATION)
            && (*var->val.integer != ENTRYSTATUS_INVALID)
            ) {
            rc = SNMP_ERR_WRONGVALUE;
        }
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("etherStatsTable:_etherStatsTable_check_column:etherStatsStatus", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = etherStatsStatus_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 etherStatsStatus_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

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

    return rc;
}                               /* _etherStatsTable_check_column */

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

    DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_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 = _etherStatsTable_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_etherStatsTable_check_objects */


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

    DEBUGMSGTL(("internal:etherStatsTable:_etherStatsTable_undo_setup_column", "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * etherStatsDataSource(2)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/A/W/e/r/d/h 
         */
    case COLUMN_ETHERSTATSDATASOURCE:
        rowreq_ctx->column_set_flags |= COLUMN_ETHERSTATSDATASOURCE_FLAG;
        rc = etherStatsDataSource_undo_setup(rowreq_ctx);
        break;

        /*
         * etherStatsOwner(20)/OwnerString/ASN_OCTET_STR/char(char)//L/A/W/e/R/d/h 
         */
    case COLUMN_ETHERSTATSOWNER:
        rowreq_ctx->column_set_flags |= COLUMN_ETHERSTATSOWNER_FLAG;
        rc = etherStatsOwner_undo_setup(rowreq_ctx);
        break;

        /*
         * etherStatsStatus(21)/EntryStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_ETHERSTATSSTATUS:
        rowreq_ctx->column_set_flags |= COLUMN_ETHERSTATSSTATUS_FLAG;
        rc = etherStatsStatus_undo_setup(rowreq_ctx);
        break;

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

    return rc;
}                               /* _etherStatsTable_undo_setup_column */


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

    DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_undo_setup",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * allocate undo context
     */
    rowreq_ctx->undo = etherStatsTable_allocate_data();
    if (NULL == rowreq_ctx->undo) {
        /** msg already logged */
        netsnmp_request_set_error_all(requests,
                                      SNMP_ERR_RESOURCEUNAVAILABLE);
        return SNMP_ERR_NOERROR;
    }

    /*
     * row undo setup
     */
    rowreq_ctx->column_set_flags = 0;
    rc = etherStatsTable_undo_setup(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        DEBUGMSGTL(("etherStatsTable:mfd", "error %d from "
                    "etherStatsTable_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 = _etherStatsTable_undo_setup_column(rowreq_ctx,
                                                    tri->colnum);
            if (MFD_SUCCESS != rc) {
                DEBUGMSGTL(("etherStatsTable:mfd", "error %d from "
                            "etherStatsTable_undo_setup_column\n", rc));
                netsnmp_set_request_error(agtreq_info, requests,
                                          SNMP_VALIDATE_ERR(rc));
            }
        }                       /* for results */
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_etherStatsTable_undo_setup */

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

    DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_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 = etherStatsTable_undo_cleanup(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        /*
         * nothing we can do about it but log it
         */
        DEBUGMSGTL(("etherStatsTable:mfd", "error %d from "
                    "etherStatsTable_undo_cleanup\n", rc));
    }

    /*
     * release undo context, if needed
     */
    if (rowreq_ctx->undo) {
        etherStatsTable_release_data(rowreq_ctx->undo);
        rowreq_ctx->undo = NULL;
    }


    return SNMP_ERR_NOERROR;
}                               /* _mfd_etherStatsTable_undo_cleanup */

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

    DEBUGMSGTL(("internal:etherStatsTable:_etherStatsTable_set_column",
                "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * etherStatsDataSource(2)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/A/W/e/r/d/h 
         */
    case COLUMN_ETHERSTATSDATASOURCE:
        rowreq_ctx->column_set_flags |= COLUMN_ETHERSTATSDATASOURCE_FLAG;
        rc = etherStatsDataSource_set(rowreq_ctx, (oid *) var->val.string,
                                      var->val_len);
        break;

        /*
         * etherStatsOwner(20)/OwnerString/ASN_OCTET_STR/char(char)//L/A/W/e/R/d/h 
         */
    case COLUMN_ETHERSTATSOWNER:
        rowreq_ctx->column_set_flags |= COLUMN_ETHERSTATSOWNER_FLAG;
        rc = etherStatsOwner_set(rowreq_ctx, (char *) var->val.string,
                                 var->val_len);
        break;

        /*
         * etherStatsStatus(21)/EntryStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_ETHERSTATSSTATUS:
        rowreq_ctx->column_set_flags |= COLUMN_ETHERSTATSSTATUS_FLAG;
        rc = etherStatsStatus_set(rowreq_ctx,
                                  *((u_long *) var->val.string));
        break;

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

    return rc;
}                               /* _etherStatsTable_set_column */

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

    DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_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 = _etherStatsTable_set_column(rowreq_ctx,
                                         requests->requestvb, tri->colnum);
        if (MFD_SUCCESS != rc) {
            DEBUGMSGTL(("etherStatsTable:mfd", "error %d from "
                        "etherStatsTable_set_column\n", rc));
            netsnmp_set_request_error(agtreq_info, requests,
                                      SNMP_VALIDATE_ERR(rc));
        }
    }                           /* for results */

    return SNMP_ERR_NOERROR;
}                               /* _mfd_etherStatsTable_set_values */

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

    DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_commit",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    rc = etherStatsTable_commit(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        DEBUGMSGTL(("etherStatsTable:mfd", "error %d from "
                    "etherStatsTable_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...
         */
        etherStatsTable_dirty_set(etherStatsTable_dirty_get() + 1);     /* set table dirty flag */
    }

    return SNMP_ERR_NOERROR;
}

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

    DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_undo_commit", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

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

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_etherStatsTable_commit */

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

    DEBUGMSGTL(("internal:etherStatsTable:_etherStatsTable_undo_column",
                "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * etherStatsDataSource(2)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/A/W/e/r/d/h 
         */
    case COLUMN_ETHERSTATSDATASOURCE:
        rc = etherStatsDataSource_undo(rowreq_ctx);
        break;

        /*
         * etherStatsOwner(20)/OwnerString/ASN_OCTET_STR/char(char)//L/A/W/e/R/d/h 
         */
    case COLUMN_ETHERSTATSOWNER:
        rc = etherStatsOwner_undo(rowreq_ctx);
        break;

        /*
         * etherStatsStatus(21)/EntryStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_ETHERSTATSSTATUS:
        rc = etherStatsStatus_undo(rowreq_ctx);
        break;

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

    return rc;
}                               /* _etherStatsTable_undo_column */

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

    DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_undo_values", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_etherStatsTable_undo_values */

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

    DEBUGMSGTL(("internal:etherStatsTable:_mfd_etherStatsTable_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) {
        if (!(rowreq_ctx->rowreq_flags & MFD_ROW_CREATED))
            CONTAINER_REMOVE(etherStatsTable_if_ctx.container, rowreq_ctx);
    } else {
        if (rowreq_ctx->column_set_flags) {
            DEBUGMSGTL(("internal:etherStatsTable:_mfd_irreversible_commit", "updating exists (%#x) w/set (%#x) = %#x\n", rowreq_ctx->column_exists_flags, rowreq_ctx->column_set_flags, (rowreq_ctx->column_exists_flags | rowreq_ctx->column_set_flags)));
            rowreq_ctx->column_exists_flags |=
                rowreq_ctx->column_set_flags;
            rowreq_ctx->column_set_flags = 0;
        }
        if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED) {
            rowreq_ctx->rowreq_flags &= ~MFD_ROW_CREATED;
            CONTAINER_INSERT(etherStatsTable_if_ctx.container, rowreq_ctx);
        }
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_etherStatsTable_irreversible_commit */

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

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

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

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

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

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

    container = (netsnmp_container *) cache->magic;

    _container_free(container);
}                               /* _cache_free */

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

    if (NULL == rowreq_ctx)
        return;

    etherStatsTable_release_rowreq_ctx(rowreq_ctx);
}                               /* _container_item_free */

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

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

    /*
     * call user code
     */
    etherStatsTable_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
_etherStatsTable_container_init(etherStatsTable_interface_ctx * if_ctx)
{
    DEBUGMSGTL(("internal:etherStatsTable:_etherStatsTable_container_init",
                "called\n"));

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

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

    if_ctx->cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET;

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

    if (NULL != if_ctx->cache)
        if_ctx->cache->magic = (void *) if_ctx->container;
}                               /* _etherStatsTable_container_init */

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

    etherStatsTable_container_shutdown(if_ctx->container);

    _container_free(if_ctx->container);

}                               /* _etherStatsTable_container_shutdown */


etherStatsTable_rowreq_ctx *
etherStatsTable_row_find_by_mib_index(etherStatsTable_mib_index * mib_idx)
{
    etherStatsTable_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 = etherStatsTable_index_to_oid(&oid_idx, mib_idx);
    if (MFD_SUCCESS != rc)
        return NULL;

    rowreq_ctx =
        CONTAINER_FIND(etherStatsTable_if_ctx.container, &oid_idx);

    return rowreq_ctx;
}
