/*
 * Note: this file originally auto-generated by mib2c using
 *       version : 1.67 $ of : mfd-interface.m2c,v $ 
 *
 * $Id$
 */
/*
 * *********************************************************************
 * *********************************************************************
 * *********************************************************************
 * ***                                                               ***
 * ***  NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE  ***
 * ***                                                               ***
 * ***                                                               ***
 * ***       THIS FILE DOES NOT CONTAIN ANY USER EDITABLE CODE.      ***
 * ***                                                               ***
 * ***                                                               ***
 * ***       THE GENERATED CODE IS INTERNAL IMPLEMENTATION, AND      ***
 * ***                                                               ***
 * ***                                                               ***
 * ***    IS SUBJECT TO CHANGE WITHOUT WARNING IN FUTURE RELEASES.   ***
 * ***                                                               ***
 * ***                                                               ***
 * *********************************************************************
 * *********************************************************************
 * *********************************************************************
 */

/*
 * standard Net-SNMP includes 
 */
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

/*
 * include our parent header 
 */
#include "inetNetToMediaTable.h"


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

#include "inetNetToMediaTable_interface.h"

#include <ctype.h>

/**********************************************************************
 **********************************************************************
 ***
 *** Table inetNetToMediaTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * IP-MIB::inetNetToMediaTable is subid 35 of ip.
 * Its status is Current.
 * OID: .1.3.6.1.2.1.4.35, length: 8
 */
typedef struct inetNetToMediaTable_interface_ctx_s {

    netsnmp_container *container;
    netsnmp_cache  *cache;

    inetNetToMediaTable_registration *user_ctx;

    netsnmp_table_registration_info tbl_info;

    netsnmp_baby_steps_access_methods access_multiplexer;

    u_int           table_dirty;

} inetNetToMediaTable_interface_ctx;

static inetNetToMediaTable_interface_ctx inetNetToMediaTable_if_ctx;

static void
                _inetNetToMediaTable_container_init(inetNetToMediaTable_interface_ctx *
                                                    if_ctx);
static void
                _inetNetToMediaTable_container_shutdown(inetNetToMediaTable_interface_ctx *
                                                        if_ctx);


netsnmp_container *
inetNetToMediaTable_container_get(void)
{
    return inetNetToMediaTable_if_ctx.container;
}

inetNetToMediaTable_registration *
inetNetToMediaTable_registration_get(void)
{
    return inetNetToMediaTable_if_ctx.user_ctx;
}

inetNetToMediaTable_registration *
inetNetToMediaTable_registration_set(inetNetToMediaTable_registration *
                                     newreg)
{
    inetNetToMediaTable_registration *old =
        inetNetToMediaTable_if_ctx.user_ctx;
    inetNetToMediaTable_if_ctx.user_ctx = newreg;
    return old;
}

int
inetNetToMediaTable_container_size(void)
{
    return CONTAINER_SIZE(inetNetToMediaTable_if_ctx.container);
}

u_int
inetNetToMediaTable_dirty_get(void)
{
    return inetNetToMediaTable_if_ctx.table_dirty;
}

void
inetNetToMediaTable_dirty_set(u_int status)
{
    DEBUGMSGTL(("inetNetToMediaTable:inetNetToMediaTable_dirty_set",
                "called. was %d, now %d\n",
                inetNetToMediaTable_if_ctx.table_dirty, status));
    inetNetToMediaTable_if_ctx.table_dirty = status;
}

/*
 * mfd multiplexer modes
 */
static Netsnmp_Node_Handler _mfd_inetNetToMediaTable_pre_request;
static Netsnmp_Node_Handler _mfd_inetNetToMediaTable_post_request;
static Netsnmp_Node_Handler _mfd_inetNetToMediaTable_object_lookup;
static Netsnmp_Node_Handler _mfd_inetNetToMediaTable_get_values;
#ifndef NETSNMP_DISABLE_SET_SUPPORT
static Netsnmp_Node_Handler _mfd_inetNetToMediaTable_check_objects;
static Netsnmp_Node_Handler _mfd_inetNetToMediaTable_undo_setup;
static Netsnmp_Node_Handler _mfd_inetNetToMediaTable_set_values;
static Netsnmp_Node_Handler _mfd_inetNetToMediaTable_undo_cleanup;
static Netsnmp_Node_Handler _mfd_inetNetToMediaTable_undo_values;
static Netsnmp_Node_Handler _mfd_inetNetToMediaTable_commit;
static Netsnmp_Node_Handler _mfd_inetNetToMediaTable_undo_commit;
static Netsnmp_Node_Handler _mfd_inetNetToMediaTable_irreversible_commit;
static Netsnmp_Node_Handler _mfd_inetNetToMediaTable_check_dependencies;

NETSNMP_STATIC_INLINE int
                _inetNetToMediaTable_undo_column(inetNetToMediaTable_rowreq_ctx *
                                                 rowreq_ctx,
                                                 netsnmp_variable_list *
                                                 var, int column);
#endif

NETSNMP_STATIC_INLINE int
                _inetNetToMediaTable_check_indexes(inetNetToMediaTable_rowreq_ctx *
                                                   rowreq_ctx);

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

    DEBUGMSGTL(("internal:inetNetToMediaTable:_inetNetToMediaTable_initialize_interface", "called\n"));


    /*************************************************
     *
     * save interface context for inetNetToMediaTable
     */
    /*
     * Setting up the table's definition
     */
    netsnmp_table_helper_add_indexes(tbl_info, ASN_INTEGER,
                                               /** index: inetNetToMediaIfIndex */
                                     ASN_INTEGER,
                                               /** index: inetNetToMediaNetAddressType */
                                     ASN_OCTET_STR,
                                                 /** index: inetNetToMediaNetAddress */
                                     0);

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

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

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

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

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

    /*
     * no wrappers yet
     */
    access_multiplexer->pre_request = _mfd_inetNetToMediaTable_pre_request;
    access_multiplexer->post_request =
        _mfd_inetNetToMediaTable_post_request;


#ifndef NETSNMP_DISABLE_SET_SUPPORT
    /*
     * REQUIRED wrappers for set request handling
     */
    access_multiplexer->object_syntax_checks =
        _mfd_inetNetToMediaTable_check_objects;
    access_multiplexer->undo_setup = _mfd_inetNetToMediaTable_undo_setup;
    access_multiplexer->undo_cleanup =
        _mfd_inetNetToMediaTable_undo_cleanup;
    access_multiplexer->set_values = _mfd_inetNetToMediaTable_set_values;
    access_multiplexer->undo_sets = _mfd_inetNetToMediaTable_undo_values;

    /*
     * no wrappers yet
     */
    access_multiplexer->commit = _mfd_inetNetToMediaTable_commit;
    access_multiplexer->undo_commit = _mfd_inetNetToMediaTable_undo_commit;
    access_multiplexer->irreversible_commit =
        _mfd_inetNetToMediaTable_irreversible_commit;

    /*
     * REQUIRED for tables with dependencies
     */
    access_multiplexer->consistency_checks =
        _mfd_inetNetToMediaTable_check_dependencies;
#endif

    /*************************************************
     *
     * Create a registration, save our reg data, register table.
     */
    DEBUGMSGTL(("inetNetToMediaTable:init_inetNetToMediaTable",
                "Registering inetNetToMediaTable as a mibs-for-dummies table.\n"));
    handler =
        netsnmp_baby_steps_access_multiplexer_get(access_multiplexer);
    reginfo =
        netsnmp_handler_registration_create("inetNetToMediaTable", handler,
                                            inetNetToMediaTable_oid,
                                            inetNetToMediaTable_oid_size,
                                            HANDLER_CAN_BABY_STEP
#ifndef NETSNMP_DISABLE_SET_SUPPORT
                                          | HANDLER_CAN_RWRITE
#endif
                                          );
    if (NULL == reginfo) {
        snmp_log(LOG_ERR, "error registering table inetNetToMediaTable\n");
        return;
    }
    reginfo->my_reg_void = &inetNetToMediaTable_if_ctx;

    /*************************************************
     *
     * set up baby steps handler, create it and inject it
     */
    if (access_multiplexer->object_lookup)
        mfd_modes |= BABY_STEP_OBJECT_LOOKUP;
    if (access_multiplexer->pre_request)
        mfd_modes |= BABY_STEP_PRE_REQUEST;
    if (access_multiplexer->post_request)
        mfd_modes |= BABY_STEP_POST_REQUEST;

#ifndef NETSNMP_DISABLE_SET_SUPPORT
    if (access_multiplexer->set_values)
        mfd_modes |= BABY_STEP_SET_VALUES;
    if (access_multiplexer->irreversible_commit)
        mfd_modes |= BABY_STEP_IRREVERSIBLE_COMMIT;
    if (access_multiplexer->object_syntax_checks)
        mfd_modes |= BABY_STEP_CHECK_OBJECT;

    if (access_multiplexer->undo_setup)
        mfd_modes |= BABY_STEP_UNDO_SETUP;
    if (access_multiplexer->undo_cleanup)
        mfd_modes |= BABY_STEP_UNDO_CLEANUP;
    if (access_multiplexer->undo_sets)
        mfd_modes |= BABY_STEP_UNDO_SETS;

    if (access_multiplexer->row_creation)
        mfd_modes |= BABY_STEP_ROW_CREATE;
    if (access_multiplexer->consistency_checks)
        mfd_modes |= BABY_STEP_CHECK_CONSISTENCY;
    if (access_multiplexer->commit)
        mfd_modes |= BABY_STEP_COMMIT;
    if (access_multiplexer->undo_commit)
        mfd_modes |= BABY_STEP_UNDO_COMMIT;
#endif

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

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

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

}                               /* _inetNetToMediaTable_initialize_interface */

/**
 * @internal
 * Shutdown the table inetNetToMediaTable
 */
void
_inetNetToMediaTable_shutdown_interface(inetNetToMediaTable_registration *
                                        reg_ptr)
{
    /*
     * shutdown the container
     */
    _inetNetToMediaTable_container_shutdown(&inetNetToMediaTable_if_ctx);
}

void
inetNetToMediaTable_valid_columns_set(netsnmp_column_info *vc)
{
    inetNetToMediaTable_if_ctx.tbl_info.valid_columns = vc;
}                               /* inetNetToMediaTable_valid_columns_set */

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

    /*
     * temp storage for parsing indexes
     */
    /*
     * inetNetToMediaIfIndex(1)/InterfaceIndex/ASN_INTEGER/long(long)//l/a/w/e/R/d/H
     */
    netsnmp_variable_list var_inetNetToMediaIfIndex;
    /*
     * inetNetToMediaNetAddressType(2)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h
     */
    netsnmp_variable_list var_inetNetToMediaNetAddressType;
    /*
     * inetNetToMediaNetAddress(3)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h
     */
    netsnmp_variable_list var_inetNetToMediaNetAddress;

    /*
     * set up varbinds
     */
    memset(&var_inetNetToMediaIfIndex, 0x00,
           sizeof(var_inetNetToMediaIfIndex));
    var_inetNetToMediaIfIndex.type = ASN_INTEGER;
    memset(&var_inetNetToMediaNetAddressType, 0x00,
           sizeof(var_inetNetToMediaNetAddressType));
    var_inetNetToMediaNetAddressType.type = ASN_INTEGER;
    memset(&var_inetNetToMediaNetAddress, 0x00,
           sizeof(var_inetNetToMediaNetAddress));
    var_inetNetToMediaNetAddress.type = ASN_OCTET_STR;

    /*
     * chain temp index varbinds together
     */
    var_inetNetToMediaIfIndex.next_variable =
        &var_inetNetToMediaNetAddressType;
    var_inetNetToMediaNetAddressType.next_variable =
        &var_inetNetToMediaNetAddress;
    var_inetNetToMediaNetAddress.next_variable = NULL;


    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaTable_index_to_oid", "called\n"));

    /*
     * inetNetToMediaIfIndex(1)/InterfaceIndex/ASN_INTEGER/long(long)//l/a/w/e/R/d/H 
     */
    snmp_set_var_value(&var_inetNetToMediaIfIndex,
                       (u_char *) & mib_idx->inetNetToMediaIfIndex,
                       sizeof(mib_idx->inetNetToMediaIfIndex));

    /*
     * inetNetToMediaNetAddressType(2)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h 
     */
    snmp_set_var_value(&var_inetNetToMediaNetAddressType,
                       (u_char *) & mib_idx->inetNetToMediaNetAddressType,
                       sizeof(mib_idx->inetNetToMediaNetAddressType));

    /*
     * inetNetToMediaNetAddress(3)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h 
     */
    snmp_set_var_value(&var_inetNetToMediaNetAddress,
                       (u_char *) & mib_idx->inetNetToMediaNetAddress,
                       mib_idx->inetNetToMediaNetAddress_len *
                       sizeof(mib_idx->inetNetToMediaNetAddress[0]));


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

    return err;
}                               /* inetNetToMediaTable_index_to_oid */

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

    /*
     * temp storage for parsing indexes
     */
    /*
     * inetNetToMediaIfIndex(1)/InterfaceIndex/ASN_INTEGER/long(long)//l/a/w/e/R/d/H
     */
    netsnmp_variable_list var_inetNetToMediaIfIndex;
    /*
     * inetNetToMediaNetAddressType(2)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h
     */
    netsnmp_variable_list var_inetNetToMediaNetAddressType;
    /*
     * inetNetToMediaNetAddress(3)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h
     */
    netsnmp_variable_list var_inetNetToMediaNetAddress;

    /*
     * set up varbinds
     */
    memset(&var_inetNetToMediaIfIndex, 0x00,
           sizeof(var_inetNetToMediaIfIndex));
    var_inetNetToMediaIfIndex.type = ASN_INTEGER;
    memset(&var_inetNetToMediaNetAddressType, 0x00,
           sizeof(var_inetNetToMediaNetAddressType));
    var_inetNetToMediaNetAddressType.type = ASN_INTEGER;
    memset(&var_inetNetToMediaNetAddress, 0x00,
           sizeof(var_inetNetToMediaNetAddress));
    var_inetNetToMediaNetAddress.type = ASN_OCTET_STR;

    /*
     * chain temp index varbinds together
     */
    var_inetNetToMediaIfIndex.next_variable =
        &var_inetNetToMediaNetAddressType;
    var_inetNetToMediaNetAddressType.next_variable =
        &var_inetNetToMediaNetAddress;
    var_inetNetToMediaNetAddress.next_variable = NULL;


    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaTable_index_from_oid", "called\n"));

    /*
     * parse the oid into the individual index components
     */
    err = parse_oid_indexes(oid_idx->oids, oid_idx->len,
                            &var_inetNetToMediaIfIndex);
    if (err == SNMP_ERR_NOERROR) {
        /*
         * copy out values
         */
        mib_idx->inetNetToMediaIfIndex =
            *((long *) var_inetNetToMediaIfIndex.val.string);
        mib_idx->inetNetToMediaNetAddressType =
            *((u_long *) var_inetNetToMediaNetAddressType.val.string);
        /*
         * NOTE: val_len is in bytes, inetNetToMediaNetAddress_len might not be
         */
        if (var_inetNetToMediaNetAddress.val_len >
            sizeof(mib_idx->inetNetToMediaNetAddress))
            err = SNMP_ERR_GENERR;
        else {
            memcpy(mib_idx->inetNetToMediaNetAddress,
                   var_inetNetToMediaNetAddress.val.string,
                   var_inetNetToMediaNetAddress.val_len);
            mib_idx->inetNetToMediaNetAddress_len =
                var_inetNetToMediaNetAddress.val_len /
                sizeof(mib_idx->inetNetToMediaNetAddress[0]);
        }


    }

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

    return err;
}                               /* inetNetToMediaTable_index_from_oid */


/*
 *********************************************************************
 * @internal
 * allocate resources for a inetNetToMediaTable_rowreq_ctx
 */
inetNetToMediaTable_rowreq_ctx *
inetNetToMediaTable_allocate_rowreq_ctx(inetNetToMediaTable_data * data,
                                        void *user_init_ctx)
{
    inetNetToMediaTable_rowreq_ctx *rowreq_ctx =
        SNMP_MALLOC_TYPEDEF(inetNetToMediaTable_rowreq_ctx);

    DEBUGMSGTL(("internal:inetNetToMediaTable:inetNetToMediaTable_allocate_rowreq_ctx", "called\n"));

    if (NULL == rowreq_ctx) {
        snmp_log(LOG_ERR, "Couldn't allocate memory for a "
                 "inetNetToMediaTable_rowreq_ctx.\n");
        return NULL;
    } else {
        if (NULL != data) {
            /*
             * track if we got data from user
             */
            rowreq_ctx->rowreq_flags |= MFD_ROW_DATA_FROM_USER;
            rowreq_ctx->data = data;
        } else if (NULL ==
                   (rowreq_ctx->data =
                    inetNetToMediaTable_allocate_data())) {
            SNMP_FREE(rowreq_ctx);
            return NULL;
        }
    }

    /*
     * undo context will be allocated when needed (in *_undo_setup)
     */

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

    rowreq_ctx->inetNetToMediaTable_data_list = NULL;

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

    return rowreq_ctx;
}                               /* inetNetToMediaTable_allocate_rowreq_ctx */

/*
 * @internal
 * release resources for a inetNetToMediaTable_rowreq_ctx
 */
void
inetNetToMediaTable_release_rowreq_ctx(inetNetToMediaTable_rowreq_ctx *
                                       rowreq_ctx)
{
    DEBUGMSGTL(("internal:inetNetToMediaTable:inetNetToMediaTable_release_rowreq_ctx", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    inetNetToMediaTable_rowreq_ctx_cleanup(rowreq_ctx);

    /*
     * for non-transient data, don't free data we got from the user
     */
    if ((rowreq_ctx->data) &&
        !(rowreq_ctx->rowreq_flags & MFD_ROW_DATA_FROM_USER))
        inetNetToMediaTable_release_data(rowreq_ctx->data);

    if (rowreq_ctx->undo)
        inetNetToMediaTable_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);
}                               /* inetNetToMediaTable_release_rowreq_ctx */

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

    DEBUGMSGTL(("internal:inetNetToMediaTable:_mfd_inetNetToMediaTable_pre_request", "called\n"));

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_inetNetToMediaTable_pre_request */

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

    DEBUGMSGTL(("internal:inetNetToMediaTable:_mfd_inetNetToMediaTable_post_request", "called\n"));

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

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_inetNetToMediaTable_post_request */


/**
 * @internal
 * wrapper
 */
static inetNetToMediaTable_rowreq_ctx *
_mfd_inetNetToMediaTable_rowreq_from_index(netsnmp_index * oid_idx,
                                           int *rc_ptr)
{
    inetNetToMediaTable_rowreq_ctx *rowreq_ctx;
    inetNetToMediaTable_mib_index mib_idx;
    int             rc;

    DEBUGMSGTL(("internal:inetNetToMediaTable:_mfd_inetNetToMediaTable_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 = inetNetToMediaTable_index_from_oid(oid_idx, &mib_idx);
    if (MFD_SUCCESS != *rc_ptr) {
        DEBUGMSGT(("inetNetToMediaTable", "error parsing index\n"));
        return NULL;
    }

    /*
     * allocate new context
     */
    rowreq_ctx = inetNetToMediaTable_allocate_rowreq_ctx(NULL, 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 = _inetNetToMediaTable_check_indexes(rowreq_ctx);
    if (MFD_SUCCESS != *rc_ptr) {
        netsnmp_assert((*rc_ptr == SNMP_ERR_NOCREATION) ||
                       (*rc_ptr == SNMP_ERR_INCONSISTENTNAME));
        inetNetToMediaTable_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_inetNetToMediaTable_rowreq_from_index */


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

    DEBUGMSGTL(("internal:inetNetToMediaTable:_mfd_inetNetToMediaTable_object_lookup", "called\n"));

    /*
     * get our context from mfd
     * inetNetToMediaTable_interface_ctx *if_ctx =
     *             (inetNetToMediaTable_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_inetNetToMediaTable_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
        inetNetToMediaTable_row_prep(rowreq_ctx);

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

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

    DEBUGMSGTL(("internal:inetNetToMediaTable:_mfd_inetNetToMediaTable_get_column", "called for %d\n", column));


    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * inetNetToMediaPhysAddress(4)/PhysAddress/ASN_OCTET_STR/char(char)//L/A/W/e/R/d/H 
         */
    case COLUMN_INETNETTOMEDIAPHYSADDRESS:
        var->type = ASN_OCTET_STR;
        rc = inetNetToMediaPhysAddress_get(rowreq_ctx,
                                           (char **) &var->val.string,
                                           &var->val_len);
        break;

        /*
         * inetNetToMediaLastUpdated(5)/TimeStamp/ASN_TIMETICKS/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_INETNETTOMEDIALASTUPDATED:
        var->val_len = sizeof(u_long);
        var->type = ASN_TIMETICKS;
        rc = inetNetToMediaLastUpdated_get(rowreq_ctx,
                                           (u_long *) var->val.string);
        break;

        /*
         * inetNetToMediaType(6)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_INETNETTOMEDIATYPE:
        var->val_len = sizeof(u_long);
        var->type = ASN_INTEGER;
        rc = inetNetToMediaType_get(rowreq_ctx,
                                    (u_long *) var->val.string);
        break;

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

        /*
         * inetNetToMediaRowStatus(8)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_INETNETTOMEDIAROWSTATUS:
        var->val_len = sizeof(u_long);
        var->type = ASN_INTEGER;
        rc = inetNetToMediaRowStatus_get(rowreq_ctx,
                                         (u_long *) var->val.string);
        break;

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

    return rc;
}                               /* _inetNetToMediaTable_get_column */

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

    netsnmp_assert(NULL != rowreq_ctx);

    for (; requests; requests = requests->next) {
        /*
         * save old pointer, so we can free it if replaced
         */
        old_string = requests->requestvb->val.string;
        dataFreeHook = requests->requestvb->dataFreeHook;
        if (NULL == requests->requestvb->val.string) {
            requests->requestvb->val.string = requests->requestvb->buf;
            requests->requestvb->val_len =
                sizeof(requests->requestvb->buf);
        } else if (requests->requestvb->buf ==
                   requests->requestvb->val.string) {
            if (requests->requestvb->val_len !=
                sizeof(requests->requestvb->buf))
                requests->requestvb->val_len =
                    sizeof(requests->requestvb->buf);
        }

        /*
         * get column data
         */
        tri = netsnmp_extract_table_info(requests);
        if (NULL == tri)
            continue;

        rc = _inetNetToMediaTable_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_inetNetToMediaTable_get_values */

NETSNMP_STATIC_INLINE int
_inetNetToMediaTable_check_indexes(inetNetToMediaTable_rowreq_ctx *
                                   rowreq_ctx)
{
    int             rc = SNMPERR_SUCCESS;

    DEBUGMSGTL(("internal:inetNetToMediaTable:_inetNetToMediaTable_check_indexes", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);


    /*
     * (INDEX) inetNetToMediaIfIndex(1)/InterfaceIndex/ASN_INTEGER/long(long)//l/a/w/e/R/d/H 
     */
    /*
     * check defined range(s). 
     */
    if ((SNMPERR_SUCCESS == rc)
        && ((rowreq_ctx->tbl_idx.inetNetToMediaIfIndex < 1)
            || (rowreq_ctx->tbl_idx.inetNetToMediaIfIndex > 2147483647))
        ) {
        rc = SNMP_ERR_WRONGVALUE;
    }
    if (MFD_SUCCESS != rc)
        return rc;
    rc = inetNetToMediaIfIndex_check_index(rowreq_ctx);
    if (MFD_SUCCESS != rc)
        return SNMP_ERR_NOCREATION;

    /*
     * (INDEX) inetNetToMediaNetAddressType(2)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h 
     */
    /*
     * check that the value is one of defined enums 
     */
    if ((SNMPERR_SUCCESS == rc)
        && (rowreq_ctx->tbl_idx.inetNetToMediaNetAddressType !=
            INETADDRESSTYPE_UNKNOWN)
        && (rowreq_ctx->tbl_idx.inetNetToMediaNetAddressType !=
            INETADDRESSTYPE_IPV4)
        && (rowreq_ctx->tbl_idx.inetNetToMediaNetAddressType !=
            INETADDRESSTYPE_IPV6)
        && (rowreq_ctx->tbl_idx.inetNetToMediaNetAddressType !=
            INETADDRESSTYPE_IPV4Z)
        && (rowreq_ctx->tbl_idx.inetNetToMediaNetAddressType !=
            INETADDRESSTYPE_IPV6Z)
        && (rowreq_ctx->tbl_idx.inetNetToMediaNetAddressType !=
            INETADDRESSTYPE_DNS)
        ) {
        rc = SNMP_ERR_WRONGVALUE;
    }
    if (MFD_SUCCESS != rc)
        return rc;
    rc = inetNetToMediaNetAddressType_check_index(rowreq_ctx);
    if (MFD_SUCCESS != rc)
        return SNMP_ERR_NOCREATION;

    /*
     * (INDEX) inetNetToMediaNetAddress(3)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h 
     */
    /*
     * check defined range(s). 
     */
    if ((SNMPERR_SUCCESS == rc)
        && ((rowreq_ctx->tbl_idx.inetNetToMediaNetAddress_len < 0)
            || (rowreq_ctx->tbl_idx.inetNetToMediaNetAddress_len > 255))
        ) {
        rc = SNMP_ERR_WRONGLENGTH;
    }
    if (MFD_SUCCESS != rc)
        return rc;
    rc = inetNetToMediaNetAddress_check_index(rowreq_ctx);
    if (MFD_SUCCESS != rc)
        return SNMP_ERR_NOCREATION;

    /*
     * if individual parts look ok, check them as a whole
     */
    return inetNetToMediaTable_validate_index(inetNetToMediaTable_if_ctx.
                                              user_ctx, rowreq_ctx);
}                               /* _inetNetToMediaTable_check_indexes */

#ifndef NETSNMP_DISABLE_SET_SUPPORT
/***********************************************************************
 *
 * SET processing
 *
 ***********************************************************************/

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

    DEBUGMSGTL(("internal:inetNetToMediaTable:_inetNetToMediaTable_check_column", "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {
        /*
         * (INDEX) inetNetToMediaIfIndex(1)/InterfaceIndex/ASN_INTEGER/long(long)//l/a/w/e/R/d/H 
         */
    case COLUMN_INETNETTOMEDIAIFINDEX:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;
        /*
         * (INDEX) inetNetToMediaNetAddressType(2)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h 
         */
    case COLUMN_INETNETTOMEDIANETADDRESSTYPE:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;
        /*
         * (INDEX) inetNetToMediaNetAddress(3)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h 
         */
    case COLUMN_INETNETTOMEDIANETADDRESS:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;

        /*
         * inetNetToMediaPhysAddress(4)/PhysAddress/ASN_OCTET_STR/char(char)//L/A/W/e/R/d/H 
         */
    case COLUMN_INETNETTOMEDIAPHYSADDRESS:
        rc = netsnmp_check_vb_type(var, ASN_OCTET_STR);
        /*
         * check defined range(s). 
         */
        if ((SNMPERR_SUCCESS == rc)
            && ((var->val_len < 0) || (var->val_len > 65535))
            ) {
            rc = SNMP_ERR_WRONGLENGTH;
        }
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("inetNetToMediaTable:_inetNetToMediaTable_check_column:inetNetToMediaPhysAddress", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = inetNetToMediaPhysAddress_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 inetNetToMediaPhysAddress_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * inetNetToMediaLastUpdated(5)/TimeStamp/ASN_TIMETICKS/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_INETNETTOMEDIALASTUPDATED:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * inetNetToMediaType(6)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_INETNETTOMEDIATYPE:
        rc = netsnmp_check_vb_type(var, ASN_INTEGER);
        /*
         * check that the value is one of defined enums 
         */
        if ((SNMPERR_SUCCESS == rc)
            && (*var->val.integer != INETNETTOMEDIATYPE_OTHER)
            && (*var->val.integer != INETNETTOMEDIATYPE_INVALID)
            && (*var->val.integer != INETNETTOMEDIATYPE_DYNAMIC)
            && (*var->val.integer != INETNETTOMEDIATYPE_STATIC)
            && (*var->val.integer != INETNETTOMEDIATYPE_LOCAL)
            ) {
            rc = SNMP_ERR_WRONGVALUE;
        }
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("inetNetToMediaTable:_inetNetToMediaTable_check_column:inetNetToMediaType", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = inetNetToMediaType_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 inetNetToMediaType_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * inetNetToMediaState(7)/INTEGER/ASN_INTEGER/long(u_long)//l/A/w/E/r/d/h 
         */
    case COLUMN_INETNETTOMEDIASTATE:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * inetNetToMediaRowStatus(8)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_INETNETTOMEDIAROWSTATUS:
        rc = netsnmp_check_vb_rowstatus_value(var);
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("inetNetToMediaTable:_inetNetToMediaTable_check_column:inetNetToMediaRowStatus", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = inetNetToMediaRowStatus_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 inetNetToMediaRowStatus_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 _inetNetToMediaTable_check_column\n",
                 column);
    }

    return rc;
}                               /* _inetNetToMediaTable_check_column */

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

    DEBUGMSGTL(("internal:inetNetToMediaTable:_mfd_inetNetToMediaTable_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 = _inetNetToMediaTable_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_inetNetToMediaTable_check_objects */


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

    netsnmp_assert(NULL != rowreq_ctx);

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_inetNetToMediaTable_check_dependencies */

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

    DEBUGMSGTL(("internal:inetNetToMediaTable:_inetNetToMediaTable_undo_setup_column", "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * inetNetToMediaPhysAddress(4)/PhysAddress/ASN_OCTET_STR/char(char)//L/A/W/e/R/d/H 
         */
    case COLUMN_INETNETTOMEDIAPHYSADDRESS:
        rowreq_ctx->column_set_flags |=
            COLUMN_INETNETTOMEDIAPHYSADDRESS_FLAG;
        rc = inetNetToMediaPhysAddress_undo_setup(rowreq_ctx);
        break;

        /*
         * inetNetToMediaType(6)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_INETNETTOMEDIATYPE:
        rowreq_ctx->column_set_flags |= COLUMN_INETNETTOMEDIATYPE_FLAG;
        rc = inetNetToMediaType_undo_setup(rowreq_ctx);
        break;

        /*
         * inetNetToMediaRowStatus(8)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_INETNETTOMEDIAROWSTATUS:
        rowreq_ctx->column_set_flags |=
            COLUMN_INETNETTOMEDIAROWSTATUS_FLAG;
        rc = inetNetToMediaRowStatus_undo_setup(rowreq_ctx);
        break;

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

    return rc;
}                               /* _inetNetToMediaTable_undo_setup_column */


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

    DEBUGMSGTL(("internal:inetNetToMediaTable:_mfd_inetNetToMediaTable_undo_setup", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * allocate undo context
     */
    rowreq_ctx->undo = inetNetToMediaTable_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 = inetNetToMediaTable_undo_setup(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        DEBUGMSGTL(("inetNetToMediaTable:mfd", "error %d from "
                    "inetNetToMediaTable_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 = _inetNetToMediaTable_undo_setup_column(rowreq_ctx,
                                                        tri->colnum);
            if (MFD_SUCCESS != rc) {
                DEBUGMSGTL(("inetNetToMediaTable:mfd", "error %d from "
                            "inetNetToMediaTable_undo_setup_column\n",
                            rc));
                netsnmp_set_request_error(agtreq_info, requests,
                                          SNMP_VALIDATE_ERR(rc));
            }
        }                       /* for results */
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_inetNetToMediaTable_undo_setup */

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

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

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


    return SNMP_ERR_NOERROR;
}                               /* _mfd_inetNetToMediaTable_undo_cleanup */

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

    DEBUGMSGTL(("internal:inetNetToMediaTable:_inetNetToMediaTable_set_column", "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * inetNetToMediaPhysAddress(4)/PhysAddress/ASN_OCTET_STR/char(char)//L/A/W/e/R/d/H 
         */
    case COLUMN_INETNETTOMEDIAPHYSADDRESS:
        rowreq_ctx->column_set_flags |=
            COLUMN_INETNETTOMEDIAPHYSADDRESS_FLAG;
        rc = inetNetToMediaPhysAddress_set(rowreq_ctx,
                                           (char *) var->val.string,
                                           var->val_len);
        break;

        /*
         * inetNetToMediaType(6)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_INETNETTOMEDIATYPE:
        rowreq_ctx->column_set_flags |= COLUMN_INETNETTOMEDIATYPE_FLAG;
        rc = inetNetToMediaType_set(rowreq_ctx,
                                    *((u_long *) var->val.string));
        break;

        /*
         * inetNetToMediaRowStatus(8)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_INETNETTOMEDIAROWSTATUS:
        rowreq_ctx->column_set_flags |=
            COLUMN_INETNETTOMEDIAROWSTATUS_FLAG;
        rc = inetNetToMediaRowStatus_set(rowreq_ctx,
                                         *((u_long *) var->val.string));
        break;

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

    return rc;
}                               /* _inetNetToMediaTable_set_column */

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_inetNetToMediaTable_set_values */

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

    DEBUGMSGTL(("internal:inetNetToMediaTable:_mfd_inetNetToMediaTable_commit", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    rc = inetNetToMediaTable_commit(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        DEBUGMSGTL(("inetNetToMediaTable:mfd", "error %d from "
                    "inetNetToMediaTable_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...
         */
        inetNetToMediaTable_dirty_set(inetNetToMediaTable_dirty_get() + 1);     /* set table dirty flag */
    }

    return SNMP_ERR_NOERROR;
}

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

    DEBUGMSGTL(("internal:inetNetToMediaTable:_mfd_inetNetToMediaTable_undo_commit", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

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

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_inetNetToMediaTable_commit */

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

    DEBUGMSGTL(("internal:inetNetToMediaTable:_inetNetToMediaTable_undo_column", "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * inetNetToMediaPhysAddress(4)/PhysAddress/ASN_OCTET_STR/char(char)//L/A/W/e/R/d/H 
         */
    case COLUMN_INETNETTOMEDIAPHYSADDRESS:
        rc = inetNetToMediaPhysAddress_undo(rowreq_ctx);
        break;

        /*
         * inetNetToMediaType(6)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_INETNETTOMEDIATYPE:
        rc = inetNetToMediaType_undo(rowreq_ctx);
        break;

        /*
         * inetNetToMediaRowStatus(8)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_INETNETTOMEDIAROWSTATUS:
        rc = inetNetToMediaRowStatus_undo(rowreq_ctx);
        break;

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

    return rc;
}                               /* _inetNetToMediaTable_undo_column */

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

    DEBUGMSGTL(("internal:inetNetToMediaTable:_mfd_inetNetToMediaTable_undo_values", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_inetNetToMediaTable_undo_values */

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

    DEBUGMSGTL(("internal:inetNetToMediaTable:_mfd_inetNetToMediaTable_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(inetNetToMediaTable_if_ctx.container, rowreq_ctx);
    } else {
        if (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(inetNetToMediaTable_if_ctx.container,
                             rowreq_ctx);
        }
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_inetNetToMediaTable_irreversible_commit */
#endif

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

/**
 * @internal
 */
static int
_cache_load(netsnmp_cache * cache, void *vmagic)
{
    DEBUGTRACE;

    if ((NULL == cache) || (NULL == cache->magic)) {
        snmp_log(LOG_ERR,
                 "invalid cache for inetNetToMediaTable_cache_load\n");
        return -1;
    }
    DEBUGMSGTL(("inetNetToMediaTable/cache", "inetNetToMedia_load %p/%p\n",
                cache, cache->magic));

    netsnmp_assert((0 == cache->valid) || (1 == cache->expired));

    /*
     * call user code
     */
    return inetNetToMediaTable_container_load((netsnmp_container *) cache->
                                              magic);
}                               /* _cache_load */

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

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

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

    container = (netsnmp_container *) cache->magic;

    _container_free(container);
}                               /* _cache_free */

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

    if (NULL == rowreq_ctx)
        return;

    inetNetToMediaTable_release_rowreq_ctx(rowreq_ctx);
}                               /* _container_item_free */

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

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

    /*
     * call user code
     */
    inetNetToMediaTable_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
_inetNetToMediaTable_container_init(inetNetToMediaTable_interface_ctx *
                                    if_ctx)
{
    DEBUGMSGTL(("internal:inetNetToMediaTable:_inetNetToMediaTable_container_init", "called\n"));

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

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

    if_ctx->cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET;

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

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

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

    inetNetToMediaTable_container_shutdown(if_ctx->container);

    _container_free(if_ctx->container);

}                               /* _inetNetToMediaTable_container_shutdown */


inetNetToMediaTable_rowreq_ctx *
inetNetToMediaTable_row_find_by_mib_index(inetNetToMediaTable_mib_index *
                                          mib_idx)
{
    inetNetToMediaTable_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 = inetNetToMediaTable_index_to_oid(&oid_idx, mib_idx);
    if (MFD_SUCCESS != rc)
        return NULL;

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

    return rowreq_ctx;
}
