/*
 * 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 retrieval. 
     */
    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;
}
