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


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

#include "ipAddressTable_interface.h"

#include <ctype.h>

/**********************************************************************
 **********************************************************************
 ***
 *** Table ipAddressTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * IP-MIB::ipAddressTable is subid 34 of ip.
 * Its status is Current.
 * OID: .1.3.6.1.2.1.4.34, length: 8
 */
typedef struct ipAddressTable_interface_ctx_s {

    netsnmp_container *container;
    netsnmp_cache  *cache;

    ipAddressTable_registration *user_ctx;

    netsnmp_table_registration_info tbl_info;

    netsnmp_baby_steps_access_methods access_multiplexer;

    u_int           table_dirty;

} ipAddressTable_interface_ctx;

static ipAddressTable_interface_ctx ipAddressTable_if_ctx;

static void     _ipAddressTable_container_init(ipAddressTable_interface_ctx
                                               * if_ctx);
static void
                _ipAddressTable_container_shutdown(ipAddressTable_interface_ctx * if_ctx);


netsnmp_container *
ipAddressTable_container_get(void)
{
    return ipAddressTable_if_ctx.container;
}

ipAddressTable_registration *
ipAddressTable_registration_get(void)
{
    return ipAddressTable_if_ctx.user_ctx;
}

ipAddressTable_registration *
ipAddressTable_registration_set(ipAddressTable_registration * newreg)
{
    ipAddressTable_registration *old = ipAddressTable_if_ctx.user_ctx;
    ipAddressTable_if_ctx.user_ctx = newreg;
    return old;
}

int
ipAddressTable_container_size(void)
{
    return CONTAINER_SIZE(ipAddressTable_if_ctx.container);
}

u_int
ipAddressTable_dirty_get(void)
{
    return ipAddressTable_if_ctx.table_dirty;
}

void
ipAddressTable_dirty_set(u_int status)
{
    DEBUGMSGTL(("ipAddressTable:ipAddressTable_dirty_set",
                "called. was %d, now %d\n",
                ipAddressTable_if_ctx.table_dirty, status));
    ipAddressTable_if_ctx.table_dirty = status;
}

/*
 * mfd multiplexer modes
 */
static Netsnmp_Node_Handler _mfd_ipAddressTable_pre_request;
static Netsnmp_Node_Handler _mfd_ipAddressTable_post_request;
static Netsnmp_Node_Handler _mfd_ipAddressTable_object_lookup;
static Netsnmp_Node_Handler _mfd_ipAddressTable_get_values;
#ifndef NETSNMP_DISABLE_SET_SUPPORT
static Netsnmp_Node_Handler _mfd_ipAddressTable_check_objects;
static Netsnmp_Node_Handler _mfd_ipAddressTable_undo_setup;
static Netsnmp_Node_Handler _mfd_ipAddressTable_set_values;
static Netsnmp_Node_Handler _mfd_ipAddressTable_undo_cleanup;
static Netsnmp_Node_Handler _mfd_ipAddressTable_undo_values;
static Netsnmp_Node_Handler _mfd_ipAddressTable_commit;
static Netsnmp_Node_Handler _mfd_ipAddressTable_undo_commit;
static Netsnmp_Node_Handler _mfd_ipAddressTable_irreversible_commit;
static Netsnmp_Node_Handler _mfd_ipAddressTable_check_dependencies;

NETSNMP_STATIC_INLINE int
                _ipAddressTable_undo_column(ipAddressTable_rowreq_ctx * rowreq_ctx,
                                            netsnmp_variable_list * var,
                                            int column);
#endif

NETSNMP_STATIC_INLINE int
                _ipAddressTable_check_indexes(ipAddressTable_rowreq_ctx * rowreq_ctx);

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

    DEBUGMSGTL(("internal:ipAddressTable:_ipAddressTable_initialize_interface", "called\n"));


    /*************************************************
     *
     * save interface context for ipAddressTable
     */
    /*
     * Setting up the table's definition
     */
    netsnmp_table_helper_add_indexes(tbl_info, ASN_INTEGER,
                                               /** index: ipAddressAddrType */
                                     ASN_OCTET_STR,
                                                 /** index: ipAddressAddr */
                                     0);

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

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

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

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

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

    /*
     * no wrappers yet
     */
    access_multiplexer->pre_request = _mfd_ipAddressTable_pre_request;
    access_multiplexer->post_request = _mfd_ipAddressTable_post_request;


#ifndef NETSNMP_DISABLE_SET_SUPPORT
    /*
     * REQUIRED wrappers for set request handling
     */
    access_multiplexer->object_syntax_checks =
        _mfd_ipAddressTable_check_objects;
    access_multiplexer->undo_setup = _mfd_ipAddressTable_undo_setup;
    access_multiplexer->undo_cleanup = _mfd_ipAddressTable_undo_cleanup;
    access_multiplexer->set_values = _mfd_ipAddressTable_set_values;
    access_multiplexer->undo_sets = _mfd_ipAddressTable_undo_values;

    /*
     * no wrappers yet
     */
    access_multiplexer->commit = _mfd_ipAddressTable_commit;
    access_multiplexer->undo_commit = _mfd_ipAddressTable_undo_commit;
    access_multiplexer->irreversible_commit =
        _mfd_ipAddressTable_irreversible_commit;

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

    /*************************************************
     *
     * Create a registration, save our reg data, register table.
     */
    DEBUGMSGTL(("ipAddressTable:init_ipAddressTable",
                "Registering ipAddressTable as a mibs-for-dummies table.\n"));
    handler =
        netsnmp_baby_steps_access_multiplexer_get(access_multiplexer);
    reginfo =
        netsnmp_handler_registration_create("ipAddressTable", handler,
                                            ipAddressTable_oid,
                                            ipAddressTable_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 ipAddressTable\n");
        return;
    }
    reginfo->my_reg_void = &ipAddressTable_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,
                                            ipAddressTable_if_ctx.
                                            container,
                                            TABLE_CONTAINER_KEY_NETSNMP_INDEX);
    netsnmp_inject_handler(reginfo, handler);

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

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

}                               /* _ipAddressTable_initialize_interface */

/**
 * @internal
 * Shutdown the table ipAddressTable
 */
void
_ipAddressTable_shutdown_interface(ipAddressTable_registration * reg_ptr)
{
    /*
     * shutdown the container
     */
    _ipAddressTable_container_shutdown(&ipAddressTable_if_ctx);
}

void
ipAddressTable_valid_columns_set(netsnmp_column_info *vc)
{
    ipAddressTable_if_ctx.tbl_info.valid_columns = vc;
}                               /* ipAddressTable_valid_columns_set */

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

    /*
     * temp storage for parsing indexes
     */
    /*
     * ipAddressAddrType(1)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h
     */
    netsnmp_variable_list var_ipAddressAddrType;
    /*
     * ipAddressAddr(2)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h
     */
    netsnmp_variable_list var_ipAddressAddr;

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

    /*
     * chain temp index varbinds together
     */
    var_ipAddressAddrType.next_variable = &var_ipAddressAddr;
    var_ipAddressAddr.next_variable = NULL;


    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_index_to_oid",
                "called\n"));

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

    /*
     * ipAddressAddr(2)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h 
     */
    snmp_set_var_value(&var_ipAddressAddr,
                       (u_char *) & mib_idx->ipAddressAddr,
                       mib_idx->ipAddressAddr_len *
                       sizeof(mib_idx->ipAddressAddr[0]));


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

    return err;
}                               /* ipAddressTable_index_to_oid */

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

    /*
     * temp storage for parsing indexes
     */
    /*
     * ipAddressAddrType(1)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h
     */
    netsnmp_variable_list var_ipAddressAddrType;
    /*
     * ipAddressAddr(2)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h
     */
    netsnmp_variable_list var_ipAddressAddr;

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

    /*
     * chain temp index varbinds together
     */
    var_ipAddressAddrType.next_variable = &var_ipAddressAddr;
    var_ipAddressAddr.next_variable = NULL;


    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_index_from_oid",
                "called\n"));

    /*
     * parse the oid into the individual index components
     */
    err = parse_oid_indexes(oid_idx->oids, oid_idx->len,
                            &var_ipAddressAddrType);
    if (err == SNMP_ERR_NOERROR) {
        /*
         * copy out values
         */
        mib_idx->ipAddressAddrType =
            *((u_long *) var_ipAddressAddrType.val.string);
        /*
         * NOTE: val_len is in bytes, ipAddressAddr_len might not be
         */
        if (var_ipAddressAddr.val_len > sizeof(mib_idx->ipAddressAddr))
            err = SNMP_ERR_GENERR;
        else {
            memcpy(mib_idx->ipAddressAddr, var_ipAddressAddr.val.string,
                   var_ipAddressAddr.val_len);
            mib_idx->ipAddressAddr_len =
                var_ipAddressAddr.val_len /
                sizeof(mib_idx->ipAddressAddr[0]);
        }


    }

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

    return err;
}                               /* ipAddressTable_index_from_oid */


/*
 *********************************************************************
 * @internal
 * allocate resources for a ipAddressTable_rowreq_ctx
 */
ipAddressTable_rowreq_ctx *
ipAddressTable_allocate_rowreq_ctx(ipAddressTable_data * data,
                                   void *user_init_ctx)
{
    ipAddressTable_rowreq_ctx *rowreq_ctx =
        SNMP_MALLOC_TYPEDEF(ipAddressTable_rowreq_ctx);

    DEBUGMSGTL(("internal:ipAddressTable:ipAddressTable_allocate_rowreq_ctx", "called\n"));

    if (NULL == rowreq_ctx) {
        snmp_log(LOG_ERR, "Couldn't allocate memory for a "
                 "ipAddressTable_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 = ipAddressTable_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->ipAddressTable_data_list = NULL;

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

    return rowreq_ctx;
}                               /* ipAddressTable_allocate_rowreq_ctx */

/*
 * @internal
 * release resources for a ipAddressTable_rowreq_ctx
 */
void
ipAddressTable_release_rowreq_ctx(ipAddressTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("internal:ipAddressTable:ipAddressTable_release_rowreq_ctx", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    ipAddressTable_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))
        ipAddressTable_release_data(rowreq_ctx->data);

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

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

    DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_pre_request",
                "called\n"));

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ipAddressTable_pre_request */

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

    DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_post_request",
                "called\n"));

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

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ipAddressTable_post_request */

/**
 * @internal
 * wrapper
 */
static ipAddressTable_rowreq_ctx *
_mfd_ipAddressTable_rowreq_from_index(netsnmp_index * oid_idx, int *rc_ptr)
{
    ipAddressTable_rowreq_ctx *rowreq_ctx;
    ipAddressTable_mib_index mib_idx;
    int             rc;

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

    /*
     * allocate new context
     */
    rowreq_ctx = ipAddressTable_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 = _ipAddressTable_check_indexes(rowreq_ctx);
    if (MFD_SUCCESS != *rc_ptr) {
        netsnmp_assert((*rc_ptr == SNMP_ERR_NOCREATION) ||
                       (*rc_ptr == SNMP_ERR_INCONSISTENTNAME));
        ipAddressTable_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_ipAddressTable_rowreq_from_index */


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

    DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_object_lookup", "called\n"));

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

    if (NULL == rowreq_ctx) {
#define NETSNMP_IPADDRESSTABLE_CREATE_SUPPORT 1
#ifndef NETSNMP_IPADDRESSTABLE_CREATE_SUPPORT
        rc = SNMP_ERR_NOCREATION;
#else
        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_ipAddressTable_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);
        }
#endif
    }

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

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

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

    DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_get_column",
                "called for %d\n", column));


    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * ipAddressIfIndex(3)/InterfaceIndex/ASN_INTEGER/long(long)//l/A/W/e/R/d/H 
         */
    case COLUMN_IPADDRESSIFINDEX:
        var->val_len = sizeof(long);
        var->type = ASN_INTEGER;
        rc = ipAddressIfIndex_get(rowreq_ctx, (long *) var->val.string);
        break;

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

        /*
         * ipAddressPrefix(5)/RowPointer/ASN_OBJECT_ID/oid(oid)//L/A/w/e/r/D/h 
         */
    case COLUMN_IPADDRESSPREFIX:
        var->type = ASN_OBJECT_ID;
        rc = ipAddressPrefix_get(rowreq_ctx, (oid **) & var->val.string,
                                 &var->val_len);
        break;

        /*
         * ipAddressOrigin(6)/IpAddressOriginTC/ASN_INTEGER/long(u_long)//l/A/w/E/r/d/h 
         */
    case COLUMN_IPADDRESSORIGIN:
        var->val_len = sizeof(u_long);
        var->type = ASN_INTEGER;
        rc = ipAddressOrigin_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * ipAddressStatus(7)/IpAddressStatusTC/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_IPADDRESSSTATUS:
        var->val_len = sizeof(u_long);
        var->type = ASN_INTEGER;
        rc = ipAddressStatus_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * ipAddressCreated(8)/TimeStamp/ASN_TIMETICKS/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IPADDRESSCREATED:
        var->val_len = sizeof(u_long);
        var->type = ASN_TIMETICKS;
        rc = ipAddressCreated_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * ipAddressLastChanged(9)/TimeStamp/ASN_TIMETICKS/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IPADDRESSLASTCHANGED:
        var->val_len = sizeof(u_long);
        var->type = ASN_TIMETICKS;
        rc = ipAddressLastChanged_get(rowreq_ctx,
                                      (u_long *) var->val.string);
        break;

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

        /*
         * ipAddressStorageType(11)/StorageType/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_IPADDRESSSTORAGETYPE:
        var->val_len = sizeof(u_long);
        var->type = ASN_INTEGER;
        rc = ipAddressStorageType_get(rowreq_ctx,
                                      (u_long *) var->val.string);
        break;

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

    return rc;
}                               /* _ipAddressTable_get_column */

int
_mfd_ipAddressTable_get_values(netsnmp_mib_handler *handler,
                               netsnmp_handler_registration *reginfo,
                               netsnmp_agent_request_info *agtreq_info,
                               netsnmp_request_info *requests)
{
    ipAddressTable_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:ipAddressTable:_mfd_ipAddressTable_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 = _ipAddressTable_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_ipAddressTable_get_values */

NETSNMP_STATIC_INLINE int
_ipAddressTable_check_indexes(ipAddressTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = SNMPERR_SUCCESS;

    DEBUGMSGTL(("internal:ipAddressTable:_ipAddressTable_check_indexes",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);


    /*
     * (INDEX) ipAddressAddrType(1)/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.ipAddressAddrType !=
            INETADDRESSTYPE_UNKNOWN)
        && (rowreq_ctx->tbl_idx.ipAddressAddrType != INETADDRESSTYPE_IPV4)
        && (rowreq_ctx->tbl_idx.ipAddressAddrType != INETADDRESSTYPE_IPV6)
        && (rowreq_ctx->tbl_idx.ipAddressAddrType != INETADDRESSTYPE_IPV4Z)
        && (rowreq_ctx->tbl_idx.ipAddressAddrType != INETADDRESSTYPE_IPV6Z)
        && (rowreq_ctx->tbl_idx.ipAddressAddrType != INETADDRESSTYPE_DNS)
        ) {
        rc = SNMP_ERR_WRONGVALUE;
    }
    if (MFD_SUCCESS != rc)
        return rc;
    rc = ipAddressAddrType_check_index(rowreq_ctx);
    if (MFD_SUCCESS != rc)
        return SNMP_ERR_NOCREATION;

    /*
     * (INDEX) ipAddressAddr(2)/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.ipAddressAddr_len < 0)
            || (rowreq_ctx->tbl_idx.ipAddressAddr_len > 255))
        ) {
        rc = SNMP_ERR_WRONGLENGTH;
    }
    if (MFD_SUCCESS != rc)
        return rc;
    rc = ipAddressAddr_check_index(rowreq_ctx);
    if (MFD_SUCCESS != rc)
        return SNMP_ERR_NOCREATION;

    /*
     * if individual parts look ok, check them as a whole
     */
    return ipAddressTable_validate_index(ipAddressTable_if_ctx.user_ctx,
                                         rowreq_ctx);
}                               /* _ipAddressTable_check_indexes */

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

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

    DEBUGMSGTL(("internal:ipAddressTable:_ipAddressTable_check_column",
                "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {
        /*
         * (INDEX) ipAddressAddrType(1)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h 
         */
    case COLUMN_IPADDRESSADDRTYPE:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;
        /*
         * (INDEX) ipAddressAddr(2)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h 
         */
    case COLUMN_IPADDRESSADDR:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;

        /*
         * ipAddressIfIndex(3)/InterfaceIndex/ASN_INTEGER/long(long)//l/A/W/e/R/d/H 
         */
    case COLUMN_IPADDRESSIFINDEX:
        rc = netsnmp_check_vb_type(var, ASN_INTEGER);
        /*
         * check defined range(s). 
         */
        if ((SNMPERR_SUCCESS == rc)
            && ((*var->val.integer < 1)
                || (*var->val.integer > 2147483647))
            ) {
            rc = SNMP_ERR_WRONGVALUE;
        }
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("ipAddressTable:_ipAddressTable_check_column:ipAddressIfIndex", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = ipAddressIfIndex_check_value(rowreq_ctx,
                                              *((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 ipAddressIfIndex_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * ipAddressType(4)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_IPADDRESSTYPE:
        rc = netsnmp_check_vb_type(var, ASN_INTEGER);
        /*
         * check that the value is one of defined enums 
         */
        if ((SNMPERR_SUCCESS == rc)
            && (*var->val.integer != IPADDRESSTYPE_UNICAST)
            && (*var->val.integer != IPADDRESSTYPE_ANYCAST)
            && (*var->val.integer != IPADDRESSTYPE_BROADCAST)
            ) {
            rc = SNMP_ERR_WRONGVALUE;
        }
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("ipAddressTable:_ipAddressTable_check_column:ipAddressType", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = ipAddressType_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 ipAddressType_check_value\n", rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * ipAddressPrefix(5)/RowPointer/ASN_OBJECT_ID/oid(oid)//L/A/w/e/r/D/h 
         */
    case COLUMN_IPADDRESSPREFIX:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ipAddressOrigin(6)/IpAddressOriginTC/ASN_INTEGER/long(u_long)//l/A/w/E/r/d/h 
         */
    case COLUMN_IPADDRESSORIGIN:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ipAddressStatus(7)/IpAddressStatusTC/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_IPADDRESSSTATUS:
        rc = netsnmp_check_vb_type(var, ASN_INTEGER);
        /*
         * check that the value is one of defined enums 
         */
        if ((SNMPERR_SUCCESS == rc)
            && (*var->val.integer != IPADDRESSSTATUSTC_PREFERRED)
            && (*var->val.integer != IPADDRESSSTATUSTC_INVALID)
            && (*var->val.integer != IPADDRESSSTATUSTC_INACCESSIBLE)
            && (*var->val.integer != IPADDRESSSTATUSTC_UNKNOWN)
            && (*var->val.integer != IPADDRESSSTATUSTC_TENTATIVE)
            && (*var->val.integer != IPADDRESSSTATUSTC_DUPLICATE)
            ) {
            rc = SNMP_ERR_WRONGVALUE;
        }
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("ipAddressTable:_ipAddressTable_check_column:ipAddressStatus", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = ipAddressStatus_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 ipAddressStatus_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * ipAddressCreated(8)/TimeStamp/ASN_TIMETICKS/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IPADDRESSCREATED:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ipAddressLastChanged(9)/TimeStamp/ASN_TIMETICKS/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IPADDRESSLASTCHANGED:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ipAddressRowStatus(10)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_IPADDRESSROWSTATUS:
        rc = netsnmp_check_vb_rowstatus_value(var);
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("ipAddressTable:_ipAddressTable_check_column:ipAddressRowStatus", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = ipAddressRowStatus_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 ipAddressRowStatus_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * ipAddressStorageType(11)/StorageType/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_IPADDRESSSTORAGETYPE:
        rc = netsnmp_check_vb_type(var, ASN_INTEGER);
        /*
         * check that the value is one of defined enums 
         */
        if ((SNMPERR_SUCCESS == rc)
            && (*var->val.integer != STORAGETYPE_OTHER)
            && (*var->val.integer != STORAGETYPE_VOLATILE)
            && (*var->val.integer != STORAGETYPE_NONVOLATILE)
            && (*var->val.integer != STORAGETYPE_PERMANENT)
            && (*var->val.integer != STORAGETYPE_READONLY)
            ) {
            rc = SNMP_ERR_WRONGVALUE;
        }
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("ipAddressTable:_ipAddressTable_check_column:ipAddressStorageType", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = ipAddressStorageType_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 ipAddressStorageType_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 _ipAddressTable_check_column\n",
                 column);
    }

    return rc;
}                               /* _ipAddressTable_check_column */

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

    DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_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 = _ipAddressTable_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_ipAddressTable_check_objects */


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

    netsnmp_assert(NULL != rowreq_ctx);

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ipAddressTable_check_dependencies */

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

    DEBUGMSGTL(("internal:ipAddressTable:_ipAddressTable_undo_setup_column", "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * ipAddressIfIndex(3)/InterfaceIndex/ASN_INTEGER/long(long)//l/A/W/e/R/d/H 
         */
    case COLUMN_IPADDRESSIFINDEX:
        rowreq_ctx->column_set_flags |= COLUMN_IPADDRESSIFINDEX_FLAG;
        rc = ipAddressIfIndex_undo_setup(rowreq_ctx);
        break;

        /*
         * ipAddressType(4)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_IPADDRESSTYPE:
        rowreq_ctx->column_set_flags |= COLUMN_IPADDRESSTYPE_FLAG;
        rc = ipAddressType_undo_setup(rowreq_ctx);
        break;

        /*
         * ipAddressStatus(7)/IpAddressStatusTC/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_IPADDRESSSTATUS:
        rowreq_ctx->column_set_flags |= COLUMN_IPADDRESSSTATUS_FLAG;
        rc = ipAddressStatus_undo_setup(rowreq_ctx);
        break;

        /*
         * ipAddressRowStatus(10)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_IPADDRESSROWSTATUS:
        rowreq_ctx->column_set_flags |= COLUMN_IPADDRESSROWSTATUS_FLAG;
        rc = ipAddressRowStatus_undo_setup(rowreq_ctx);
        break;

        /*
         * ipAddressStorageType(11)/StorageType/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_IPADDRESSSTORAGETYPE:
        rowreq_ctx->column_set_flags |= COLUMN_IPADDRESSSTORAGETYPE_FLAG;
        rc = ipAddressStorageType_undo_setup(rowreq_ctx);
        break;

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

    return rc;
}                               /* _ipAddressTable_undo_setup_column */


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

    DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_undo_setup",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ipAddressTable_undo_setup */

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

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

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


    return SNMP_ERR_NOERROR;
}                               /* _mfd_ipAddressTable_undo_cleanup */

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

    DEBUGMSGTL(("internal:ipAddressTable:_ipAddressTable_set_column",
                "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * ipAddressIfIndex(3)/InterfaceIndex/ASN_INTEGER/long(long)//l/A/W/e/R/d/H 
         */
    case COLUMN_IPADDRESSIFINDEX:
        rowreq_ctx->column_set_flags |= COLUMN_IPADDRESSIFINDEX_FLAG;
        rc = ipAddressIfIndex_set(rowreq_ctx, *((long *) var->val.string));
        break;

        /*
         * ipAddressType(4)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_IPADDRESSTYPE:
        rowreq_ctx->column_set_flags |= COLUMN_IPADDRESSTYPE_FLAG;
        rc = ipAddressType_set(rowreq_ctx, *((u_long *) var->val.string));
        break;

        /*
         * ipAddressStatus(7)/IpAddressStatusTC/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_IPADDRESSSTATUS:
        rowreq_ctx->column_set_flags |= COLUMN_IPADDRESSSTATUS_FLAG;
        rc = ipAddressStatus_set(rowreq_ctx,
                                 *((u_long *) var->val.string));
        break;

        /*
         * ipAddressRowStatus(10)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_IPADDRESSROWSTATUS:
        rowreq_ctx->column_set_flags |= COLUMN_IPADDRESSROWSTATUS_FLAG;
        rc = ipAddressRowStatus_set(rowreq_ctx,
                                    *((u_long *) var->val.string));
        break;

        /*
         * ipAddressStorageType(11)/StorageType/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_IPADDRESSSTORAGETYPE:
        rowreq_ctx->column_set_flags |= COLUMN_IPADDRESSSTORAGETYPE_FLAG;
        rc = ipAddressStorageType_set(rowreq_ctx,
                                      *((u_long *) var->val.string));
        break;

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

    return rc;
}                               /* _ipAddressTable_set_column */

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ipAddressTable_set_values */

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

    DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_commit",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    rc = ipAddressTable_commit(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        DEBUGMSGTL(("ipAddressTable:mfd", "error %d from "
                    "ipAddressTable_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...
         */
        ipAddressTable_dirty_set(ipAddressTable_dirty_get() + 1);       /* set table dirty flag */
    }

    return SNMP_ERR_NOERROR;
}

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

    DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_undo_commit",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

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

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ipAddressTable_commit */

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

    DEBUGMSGTL(("internal:ipAddressTable:_ipAddressTable_undo_column",
                "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * ipAddressIfIndex(3)/InterfaceIndex/ASN_INTEGER/long(long)//l/A/W/e/R/d/H 
         */
    case COLUMN_IPADDRESSIFINDEX:
        rc = ipAddressIfIndex_undo(rowreq_ctx);
        break;

        /*
         * ipAddressType(4)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_IPADDRESSTYPE:
        rc = ipAddressType_undo(rowreq_ctx);
        break;

        /*
         * ipAddressStatus(7)/IpAddressStatusTC/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_IPADDRESSSTATUS:
        rc = ipAddressStatus_undo(rowreq_ctx);
        break;

        /*
         * ipAddressRowStatus(10)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_IPADDRESSROWSTATUS:
        rc = ipAddressRowStatus_undo(rowreq_ctx);
        break;

        /*
         * ipAddressStorageType(11)/StorageType/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_IPADDRESSSTORAGETYPE:
        rc = ipAddressStorageType_undo(rowreq_ctx);
        break;

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

    return rc;
}                               /* _ipAddressTable_undo_column */

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

    DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_undo_values",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ipAddressTable_undo_values */

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

    DEBUGMSGTL(("internal:ipAddressTable:_mfd_ipAddressTable_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(ipAddressTable_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(ipAddressTable_if_ctx.container, rowreq_ctx);
        }
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ipAddressTable_irreversible_commit */
#endif

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

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

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

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

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

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

    container = (netsnmp_container *) cache->magic;

    _container_free(container);
}                               /* _cache_free */

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

    if (NULL == rowreq_ctx)
        return;

    ipAddressTable_release_rowreq_ctx(rowreq_ctx);
}                               /* _container_item_free */

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

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

    /*
     * call user code
     */
    ipAddressTable_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
_ipAddressTable_container_init(ipAddressTable_interface_ctx * if_ctx)
{
    DEBUGMSGTL(("internal:ipAddressTable:_ipAddressTable_container_init",
                "called\n"));

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

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

    if_ctx->cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET;

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

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

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

    ipAddressTable_container_shutdown(if_ctx->container);

    _container_free(if_ctx->container);

}                               /* _ipAddressTable_container_shutdown */


ipAddressTable_rowreq_ctx *
ipAddressTable_row_find_by_mib_index(ipAddressTable_mib_index * mib_idx)
{
    ipAddressTable_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 = ipAddressTable_index_to_oid(&oid_idx, mib_idx);
    if (MFD_SUCCESS != rc)
        return NULL;

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

    return rowreq_ctx;
}
