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


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

#include "tcpConnectionTable_interface.h"

#include <ctype.h>

/**********************************************************************
 **********************************************************************
 ***
 *** Table tcpConnectionTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * TCP-MIB::tcpConnectionTable is subid 19 of tcp.
 * Its status is Current.
 * OID: .1.3.6.1.2.1.6.19, length: 8
 */
typedef struct tcpConnectionTable_interface_ctx_s {

    netsnmp_container *container;
    netsnmp_cache  *cache;

    tcpConnectionTable_registration *user_ctx;

    netsnmp_table_registration_info tbl_info;

    netsnmp_baby_steps_access_methods access_multiplexer;

    u_int           table_dirty;

} tcpConnectionTable_interface_ctx;

static tcpConnectionTable_interface_ctx tcpConnectionTable_if_ctx;

static void
                _tcpConnectionTable_container_init(tcpConnectionTable_interface_ctx *
                                                   if_ctx);
static void
                _tcpConnectionTable_container_shutdown(tcpConnectionTable_interface_ctx *
                                                       if_ctx);


netsnmp_container *
tcpConnectionTable_container_get(void)
{
    return tcpConnectionTable_if_ctx.container;
}

tcpConnectionTable_registration *
tcpConnectionTable_registration_get(void)
{
    return tcpConnectionTable_if_ctx.user_ctx;
}

tcpConnectionTable_registration *
tcpConnectionTable_registration_set(tcpConnectionTable_registration *
                                    newreg)
{
    tcpConnectionTable_registration *old =
        tcpConnectionTable_if_ctx.user_ctx;
    tcpConnectionTable_if_ctx.user_ctx = newreg;
    return old;
}

int
tcpConnectionTable_container_size(void)
{
    return CONTAINER_SIZE(tcpConnectionTable_if_ctx.container);
}

u_int
tcpConnectionTable_dirty_get(void)
{
    return tcpConnectionTable_if_ctx.table_dirty;
}

void
tcpConnectionTable_dirty_set(u_int status)
{
    DEBUGMSGTL(("tcpConnectionTable:tcpConnectionTable_dirty_set",
                "called. was %d, now %d\n",
                tcpConnectionTable_if_ctx.table_dirty, status));
    tcpConnectionTable_if_ctx.table_dirty = status;
}

/*
 * mfd multiplexer modes
 */
static Netsnmp_Node_Handler _mfd_tcpConnectionTable_pre_request;
static Netsnmp_Node_Handler _mfd_tcpConnectionTable_post_request;
static Netsnmp_Node_Handler _mfd_tcpConnectionTable_object_lookup;
static Netsnmp_Node_Handler _mfd_tcpConnectionTable_get_values;
#ifndef NETSNMP_DISABLE_SET_SUPPORT
static Netsnmp_Node_Handler _mfd_tcpConnectionTable_check_objects;
static Netsnmp_Node_Handler _mfd_tcpConnectionTable_undo_setup;
static Netsnmp_Node_Handler _mfd_tcpConnectionTable_set_values;
static Netsnmp_Node_Handler _mfd_tcpConnectionTable_undo_cleanup;
static Netsnmp_Node_Handler _mfd_tcpConnectionTable_undo_values;
static Netsnmp_Node_Handler _mfd_tcpConnectionTable_commit;
static Netsnmp_Node_Handler _mfd_tcpConnectionTable_undo_commit;
static Netsnmp_Node_Handler _mfd_tcpConnectionTable_irreversible_commit;
static Netsnmp_Node_Handler _mfd_tcpConnectionTable_check_dependencies;

NETSNMP_STATIC_INLINE int
                _tcpConnectionTable_undo_column(tcpConnectionTable_rowreq_ctx * rowreq_ctx,
                                                netsnmp_variable_list *
                                                var, int column);
#endif

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

    DEBUGMSGTL(("internal:tcpConnectionTable:_tcpConnectionTable_initialize_interface", "called\n"));


    /*************************************************
     *
     * save interface context for tcpConnectionTable
     */
    /*
     * Setting up the table's definition
     */
    netsnmp_table_helper_add_indexes(tbl_info, ASN_INTEGER,
                                               /** index: tcpConnectionLocalAddressType */
                                     ASN_OCTET_STR,
                                                 /** index: tcpConnectionLocalAddress */
                                     ASN_UNSIGNED,
                                                /** index: tcpConnectionLocalPort */
                                     ASN_INTEGER,
                                               /** index: tcpConnectionRemAddressType */
                                     ASN_OCTET_STR,
                                                 /** index: tcpConnectionRemAddress */
                                     ASN_UNSIGNED,
                                                /** index: tcpConnectionRemPort */
                                     0);

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

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

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

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

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

    /*
     * no wrappers yet
     */
    access_multiplexer->pre_request = _mfd_tcpConnectionTable_pre_request;
    access_multiplexer->post_request =
        _mfd_tcpConnectionTable_post_request;


#ifndef NETSNMP_DISABLE_SET_SUPPORT
    /*
     * REQUIRED wrappers for set request handling
     */
    access_multiplexer->object_syntax_checks =
        _mfd_tcpConnectionTable_check_objects;
    access_multiplexer->undo_setup = _mfd_tcpConnectionTable_undo_setup;
    access_multiplexer->undo_cleanup =
        _mfd_tcpConnectionTable_undo_cleanup;
    access_multiplexer->set_values = _mfd_tcpConnectionTable_set_values;
    access_multiplexer->undo_sets = _mfd_tcpConnectionTable_undo_values;

    /*
     * no wrappers yet
     */
    access_multiplexer->commit = _mfd_tcpConnectionTable_commit;
    access_multiplexer->undo_commit = _mfd_tcpConnectionTable_undo_commit;
    access_multiplexer->irreversible_commit =
        _mfd_tcpConnectionTable_irreversible_commit;

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

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

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

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

}                               /* _tcpConnectionTable_initialize_interface */

/**
 * @internal
 * Shutdown the table tcpConnectionTable
 */
void
_tcpConnectionTable_shutdown_interface(tcpConnectionTable_registration *
                                       reg_ptr)
{
    /*
     * shutdown the container
     */
    _tcpConnectionTable_container_shutdown(&tcpConnectionTable_if_ctx);
}

void
tcpConnectionTable_valid_columns_set(netsnmp_column_info *vc)
{
    tcpConnectionTable_if_ctx.tbl_info.valid_columns = vc;
}                               /* tcpConnectionTable_valid_columns_set */

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

    /*
     * temp storage for parsing indexes
     */
    /*
     * tcpConnectionLocalAddressType(1)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h
     */
    netsnmp_variable_list var_tcpConnectionLocalAddressType;
    /*
     * tcpConnectionLocalAddress(2)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h
     */
    netsnmp_variable_list var_tcpConnectionLocalAddress;
    /*
     * tcpConnectionLocalPort(3)/InetPortNumber/ASN_UNSIGNED/u_long(u_long)//l/a/w/e/R/d/H
     */
    netsnmp_variable_list var_tcpConnectionLocalPort;
    /*
     * tcpConnectionRemAddressType(4)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h
     */
    netsnmp_variable_list var_tcpConnectionRemAddressType;
    /*
     * tcpConnectionRemAddress(5)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h
     */
    netsnmp_variable_list var_tcpConnectionRemAddress;
    /*
     * tcpConnectionRemPort(6)/InetPortNumber/ASN_UNSIGNED/u_long(u_long)//l/a/w/e/R/d/H
     */
    netsnmp_variable_list var_tcpConnectionRemPort;

    /*
     * set up varbinds
     */
    memset(&var_tcpConnectionLocalAddressType, 0x00,
           sizeof(var_tcpConnectionLocalAddressType));
    var_tcpConnectionLocalAddressType.type = ASN_INTEGER;
    memset(&var_tcpConnectionLocalAddress, 0x00,
           sizeof(var_tcpConnectionLocalAddress));
    var_tcpConnectionLocalAddress.type = ASN_OCTET_STR;
    memset(&var_tcpConnectionLocalPort, 0x00,
           sizeof(var_tcpConnectionLocalPort));
    var_tcpConnectionLocalPort.type = ASN_UNSIGNED;
    memset(&var_tcpConnectionRemAddressType, 0x00,
           sizeof(var_tcpConnectionRemAddressType));
    var_tcpConnectionRemAddressType.type = ASN_INTEGER;
    memset(&var_tcpConnectionRemAddress, 0x00,
           sizeof(var_tcpConnectionRemAddress));
    var_tcpConnectionRemAddress.type = ASN_OCTET_STR;
    memset(&var_tcpConnectionRemPort, 0x00,
           sizeof(var_tcpConnectionRemPort));
    var_tcpConnectionRemPort.type = ASN_UNSIGNED;

    /*
     * chain temp index varbinds together
     */
    var_tcpConnectionLocalAddressType.next_variable =
        &var_tcpConnectionLocalAddress;
    var_tcpConnectionLocalAddress.next_variable =
        &var_tcpConnectionLocalPort;
    var_tcpConnectionLocalPort.next_variable =
        &var_tcpConnectionRemAddressType;
    var_tcpConnectionRemAddressType.next_variable =
        &var_tcpConnectionRemAddress;
    var_tcpConnectionRemAddress.next_variable = &var_tcpConnectionRemPort;
    var_tcpConnectionRemPort.next_variable = NULL;


    DEBUGMSGTL(("verbose:tcpConnectionTable:tcpConnectionTable_index_to_oid", "called\n"));

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

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

    /*
     * tcpConnectionLocalPort(3)/InetPortNumber/ASN_UNSIGNED/u_long(u_long)//l/a/w/e/R/d/H 
     */
    snmp_set_var_value(&var_tcpConnectionLocalPort,
                       (u_char *) & mib_idx->tcpConnectionLocalPort,
                       sizeof(mib_idx->tcpConnectionLocalPort));

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

    /*
     * tcpConnectionRemAddress(5)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h 
     */
    snmp_set_var_value(&var_tcpConnectionRemAddress,
                       (u_char *) & mib_idx->tcpConnectionRemAddress,
                       mib_idx->tcpConnectionRemAddress_len *
                       sizeof(mib_idx->tcpConnectionRemAddress[0]));

    /*
     * tcpConnectionRemPort(6)/InetPortNumber/ASN_UNSIGNED/u_long(u_long)//l/a/w/e/R/d/H 
     */
    snmp_set_var_value(&var_tcpConnectionRemPort,
                       (u_char *) & mib_idx->tcpConnectionRemPort,
                       sizeof(mib_idx->tcpConnectionRemPort));


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

    return err;
}                               /* tcpConnectionTable_index_to_oid */

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

    /*
     * temp storage for parsing indexes
     */
    /*
     * tcpConnectionLocalAddressType(1)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h
     */
    netsnmp_variable_list var_tcpConnectionLocalAddressType;
    /*
     * tcpConnectionLocalAddress(2)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h
     */
    netsnmp_variable_list var_tcpConnectionLocalAddress;
    /*
     * tcpConnectionLocalPort(3)/InetPortNumber/ASN_UNSIGNED/u_long(u_long)//l/a/w/e/R/d/H
     */
    netsnmp_variable_list var_tcpConnectionLocalPort;
    /*
     * tcpConnectionRemAddressType(4)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h
     */
    netsnmp_variable_list var_tcpConnectionRemAddressType;
    /*
     * tcpConnectionRemAddress(5)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h
     */
    netsnmp_variable_list var_tcpConnectionRemAddress;
    /*
     * tcpConnectionRemPort(6)/InetPortNumber/ASN_UNSIGNED/u_long(u_long)//l/a/w/e/R/d/H
     */
    netsnmp_variable_list var_tcpConnectionRemPort;

    /*
     * set up varbinds
     */
    memset(&var_tcpConnectionLocalAddressType, 0x00,
           sizeof(var_tcpConnectionLocalAddressType));
    var_tcpConnectionLocalAddressType.type = ASN_INTEGER;
    memset(&var_tcpConnectionLocalAddress, 0x00,
           sizeof(var_tcpConnectionLocalAddress));
    var_tcpConnectionLocalAddress.type = ASN_OCTET_STR;
    memset(&var_tcpConnectionLocalPort, 0x00,
           sizeof(var_tcpConnectionLocalPort));
    var_tcpConnectionLocalPort.type = ASN_UNSIGNED;
    memset(&var_tcpConnectionRemAddressType, 0x00,
           sizeof(var_tcpConnectionRemAddressType));
    var_tcpConnectionRemAddressType.type = ASN_INTEGER;
    memset(&var_tcpConnectionRemAddress, 0x00,
           sizeof(var_tcpConnectionRemAddress));
    var_tcpConnectionRemAddress.type = ASN_OCTET_STR;
    memset(&var_tcpConnectionRemPort, 0x00,
           sizeof(var_tcpConnectionRemPort));
    var_tcpConnectionRemPort.type = ASN_UNSIGNED;

    /*
     * chain temp index varbinds together
     */
    var_tcpConnectionLocalAddressType.next_variable =
        &var_tcpConnectionLocalAddress;
    var_tcpConnectionLocalAddress.next_variable =
        &var_tcpConnectionLocalPort;
    var_tcpConnectionLocalPort.next_variable =
        &var_tcpConnectionRemAddressType;
    var_tcpConnectionRemAddressType.next_variable =
        &var_tcpConnectionRemAddress;
    var_tcpConnectionRemAddress.next_variable = &var_tcpConnectionRemPort;
    var_tcpConnectionRemPort.next_variable = NULL;


    DEBUGMSGTL(("verbose:tcpConnectionTable:tcpConnectionTable_index_from_oid", "called\n"));

    /*
     * parse the oid into the individual index components
     */
    err = parse_oid_indexes(oid_idx->oids, oid_idx->len,
                            &var_tcpConnectionLocalAddressType);
    if (err == SNMP_ERR_NOERROR) {
        /*
         * copy out values
         */
        mib_idx->tcpConnectionLocalAddressType =
            *((u_long *) var_tcpConnectionLocalAddressType.val.string);
        /*
         * NOTE: val_len is in bytes, tcpConnectionLocalAddress_len might not be
         */
        if (var_tcpConnectionLocalAddress.val_len >
            sizeof(mib_idx->tcpConnectionLocalAddress))
            err = SNMP_ERR_GENERR;
        else {
            memcpy(mib_idx->tcpConnectionLocalAddress,
                   var_tcpConnectionLocalAddress.val.string,
                   var_tcpConnectionLocalAddress.val_len);
            mib_idx->tcpConnectionLocalAddress_len =
                var_tcpConnectionLocalAddress.val_len /
                sizeof(mib_idx->tcpConnectionLocalAddress[0]);
        }
        mib_idx->tcpConnectionLocalPort =
            *((u_long *) var_tcpConnectionLocalPort.val.string);
        mib_idx->tcpConnectionRemAddressType =
            *((u_long *) var_tcpConnectionRemAddressType.val.string);
        /*
         * NOTE: val_len is in bytes, tcpConnectionRemAddress_len might not be
         */
        if (var_tcpConnectionRemAddress.val_len >
            sizeof(mib_idx->tcpConnectionRemAddress))
            err = SNMP_ERR_GENERR;
        else {
            memcpy(mib_idx->tcpConnectionRemAddress,
                   var_tcpConnectionRemAddress.val.string,
                   var_tcpConnectionRemAddress.val_len);
            mib_idx->tcpConnectionRemAddress_len =
                var_tcpConnectionRemAddress.val_len /
                sizeof(mib_idx->tcpConnectionRemAddress[0]);
        }
        mib_idx->tcpConnectionRemPort =
            *((u_long *) var_tcpConnectionRemPort.val.string);


    }

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

    return err;
}                               /* tcpConnectionTable_index_from_oid */


/*
 *********************************************************************
 * @internal
 * allocate resources for a tcpConnectionTable_rowreq_ctx
 */
tcpConnectionTable_rowreq_ctx *
tcpConnectionTable_allocate_rowreq_ctx(tcpConnectionTable_data * data,
                                       void *user_init_ctx)
{
    tcpConnectionTable_rowreq_ctx *rowreq_ctx =
        SNMP_MALLOC_TYPEDEF(tcpConnectionTable_rowreq_ctx);

    DEBUGMSGTL(("internal:tcpConnectionTable:tcpConnectionTable_allocate_rowreq_ctx", "called\n"));

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

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

    return rowreq_ctx;
}                               /* tcpConnectionTable_allocate_rowreq_ctx */

/*
 * @internal
 * release resources for a tcpConnectionTable_rowreq_ctx
 */
void
tcpConnectionTable_release_rowreq_ctx(tcpConnectionTable_rowreq_ctx *
                                      rowreq_ctx)
{
    DEBUGMSGTL(("internal:tcpConnectionTable:tcpConnectionTable_release_rowreq_ctx", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    tcpConnectionTable_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))
        tcpConnectionTable_release_data(rowreq_ctx->data);

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

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

    DEBUGMSGTL(("internal:tcpConnectionTable:_mfd_tcpConnectionTable_pre_request", "called\n"));

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_tcpConnectionTable_pre_request */

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

    DEBUGMSGTL(("internal:tcpConnectionTable:_mfd_tcpConnectionTable_post_request", "called\n"));

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

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_tcpConnectionTable_post_request */

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

    DEBUGMSGTL(("internal:tcpConnectionTable:_mfd_tcpConnectionTable_object_lookup", "called\n"));

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

    if (NULL == rowreq_ctx) {
        rc = SNMP_ERR_NOCREATION;
    }

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

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

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

    DEBUGMSGTL(("internal:tcpConnectionTable:_mfd_tcpConnectionTable_get_column", "called for %d\n", column));


    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

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

        /*
         * tcpConnectionProcess(8)/UNSIGNED32/ASN_UNSIGNED/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_TCPCONNECTIONPROCESS:
        var->val_len = sizeof(u_long);
        var->type = ASN_UNSIGNED;
        rc = tcpConnectionProcess_get(rowreq_ctx,
                                      (u_long *) var->val.string);
        break;

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

    return rc;
}                               /* _tcpConnectionTable_get_column */

int
_mfd_tcpConnectionTable_get_values(netsnmp_mib_handler *handler,
                                   netsnmp_handler_registration *reginfo,
                                   netsnmp_agent_request_info *agtreq_info,
                                   netsnmp_request_info *requests)
{
    tcpConnectionTable_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:tcpConnectionTable:_mfd_tcpConnectionTable_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 = _tcpConnectionTable_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_tcpConnectionTable_get_values */


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

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

    DEBUGMSGTL(("internal:tcpConnectionTable:_tcpConnectionTable_check_column", "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {
        /*
         * (INDEX) tcpConnectionLocalAddressType(1)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h 
         */
    case COLUMN_TCPCONNECTIONLOCALADDRESSTYPE:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;
        /*
         * (INDEX) tcpConnectionLocalAddress(2)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h 
         */
    case COLUMN_TCPCONNECTIONLOCALADDRESS:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;
        /*
         * (INDEX) tcpConnectionLocalPort(3)/InetPortNumber/ASN_UNSIGNED/u_long(u_long)//l/a/w/e/R/d/H 
         */
    case COLUMN_TCPCONNECTIONLOCALPORT:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;
        /*
         * (INDEX) tcpConnectionRemAddressType(4)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h 
         */
    case COLUMN_TCPCONNECTIONREMADDRESSTYPE:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;
        /*
         * (INDEX) tcpConnectionRemAddress(5)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h 
         */
    case COLUMN_TCPCONNECTIONREMADDRESS:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;
        /*
         * (INDEX) tcpConnectionRemPort(6)/InetPortNumber/ASN_UNSIGNED/u_long(u_long)//l/a/w/e/R/d/H 
         */
    case COLUMN_TCPCONNECTIONREMPORT:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;

        /*
         * tcpConnectionState(7)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_TCPCONNECTIONSTATE:
        rc = netsnmp_check_vb_type(var, ASN_INTEGER);
        /*
         * check that the value is one of defined enums 
         */
        if ((SNMPERR_SUCCESS == rc)
            && (*var->val.integer != TCPCONNECTIONSTATE_CLOSED)
            && (*var->val.integer != TCPCONNECTIONSTATE_LISTEN)
            && (*var->val.integer != TCPCONNECTIONSTATE_SYNSENT)
            && (*var->val.integer != TCPCONNECTIONSTATE_SYNRECEIVED)
            && (*var->val.integer != TCPCONNECTIONSTATE_ESTABLISHED)
            && (*var->val.integer != TCPCONNECTIONSTATE_FINWAIT1)
            && (*var->val.integer != TCPCONNECTIONSTATE_FINWAIT2)
            && (*var->val.integer != TCPCONNECTIONSTATE_CLOSEWAIT)
            && (*var->val.integer != TCPCONNECTIONSTATE_LASTACK)
            && (*var->val.integer != TCPCONNECTIONSTATE_CLOSING)
            && (*var->val.integer != TCPCONNECTIONSTATE_TIMEWAIT)
            && (*var->val.integer != TCPCONNECTIONSTATE_DELETETCB)
            ) {
            rc = SNMP_ERR_WRONGVALUE;
        }
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("tcpConnectionTable:_tcpConnectionTable_check_column:tcpConnectionState", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = tcpConnectionState_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 tcpConnectionState_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * tcpConnectionProcess(8)/UNSIGNED32/ASN_UNSIGNED/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_TCPCONNECTIONPROCESS:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

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

    return rc;
}                               /* _tcpConnectionTable_check_column */

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

    DEBUGMSGTL(("internal:tcpConnectionTable:_mfd_tcpConnectionTable_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 = _tcpConnectionTable_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_tcpConnectionTable_check_objects */


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

    netsnmp_assert(NULL != rowreq_ctx);

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_tcpConnectionTable_check_dependencies */

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

    DEBUGMSGTL(("internal:tcpConnectionTable:_tcpConnectionTable_undo_setup_column", "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * tcpConnectionState(7)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_TCPCONNECTIONSTATE:
        rowreq_ctx->column_set_flags |= COLUMN_TCPCONNECTIONSTATE_FLAG;
        rc = tcpConnectionState_undo_setup(rowreq_ctx);
        break;

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

    return rc;
}                               /* _tcpConnectionTable_undo_setup_column */


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

    DEBUGMSGTL(("internal:tcpConnectionTable:_mfd_tcpConnectionTable_undo_setup", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_tcpConnectionTable_undo_setup */

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

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

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


    return SNMP_ERR_NOERROR;
}                               /* _mfd_tcpConnectionTable_undo_cleanup */

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

    DEBUGMSGTL(("internal:tcpConnectionTable:_tcpConnectionTable_set_column", "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

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

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

    return rc;
}                               /* _tcpConnectionTable_set_column */

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_tcpConnectionTable_set_values */

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

    DEBUGMSGTL(("internal:tcpConnectionTable:_mfd_tcpConnectionTable_commit", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    rc = tcpConnectionTable_commit(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        DEBUGMSGTL(("tcpConnectionTable:mfd", "error %d from "
                    "tcpConnectionTable_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...
         */
        tcpConnectionTable_dirty_set(tcpConnectionTable_dirty_get() + 1);       /* set table dirty flag */
    }

    return SNMP_ERR_NOERROR;
}

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

    DEBUGMSGTL(("internal:tcpConnectionTable:_mfd_tcpConnectionTable_undo_commit", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

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

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_tcpConnectionTable_commit */

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

    DEBUGMSGTL(("internal:tcpConnectionTable:_tcpConnectionTable_undo_column", "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * tcpConnectionState(7)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_TCPCONNECTIONSTATE:
        rc = tcpConnectionState_undo(rowreq_ctx);
        break;

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

    return rc;
}                               /* _tcpConnectionTable_undo_column */

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

    DEBUGMSGTL(("internal:tcpConnectionTable:_mfd_tcpConnectionTable_undo_values", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_tcpConnectionTable_undo_values */

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

    DEBUGMSGTL(("internal:tcpConnectionTable:_mfd_tcpConnectionTable_irreversible:commit", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_tcpConnectionTable_irreversible_commit */
#endif

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

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

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

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

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

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

    container = (netsnmp_container *) cache->magic;

    _container_free(container);
}                               /* _cache_free */

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

    if (NULL == rowreq_ctx)
        return;

    tcpConnectionTable_release_rowreq_ctx(rowreq_ctx);
}                               /* _container_item_free */

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

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

    /*
     * call user code
     */
    tcpConnectionTable_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
_tcpConnectionTable_container_init(tcpConnectionTable_interface_ctx *
                                   if_ctx)
{
    DEBUGMSGTL(("internal:tcpConnectionTable:_tcpConnectionTable_container_init", "called\n"));

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

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

    if_ctx->cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET;

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

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

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

    tcpConnectionTable_container_shutdown(if_ctx->container);

    _container_free(if_ctx->container);

}                               /* _tcpConnectionTable_container_shutdown */


tcpConnectionTable_rowreq_ctx *
tcpConnectionTable_row_find_by_mib_index(tcpConnectionTable_mib_index *
                                         mib_idx)
{
    tcpConnectionTable_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 = tcpConnectionTable_index_to_oid(&oid_idx, mib_idx);
    if (MFD_SUCCESS != rc)
        return NULL;

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

    return rowreq_ctx;
}
