/*
 * Note: this file originally auto-generated by mib2c using
 *       version : 1.48 $ of : mfd-top.m2c,v $ 
 *
 * $Id$
 */
/** \page MFD helper for ipAddressTable
 *
 * \section intro Introduction
 * Introductory text.
 *
 */
/*
 * 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 <net-snmp/data_access/interface.h>

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

#include <net-snmp/agent/mib_modules.h>

#include "ipAddressTable_interface.h"

const oid       ipAddressTable_oid[] = { IPADDRESSTABLE_OID };
const int       ipAddressTable_oid_size = OID_LENGTH(ipAddressTable_oid);

ipAddressTable_registration ipAddressTable_user_context;
static ipAddressTable_registration *ipAddressTable_user_context_p;

void            initialize_table_ipAddressTable(void);
void            shutdown_table_ipAddressTable(void);


/**
 * Initializes the ipAddressTable module
 */
void
init_ipAddressTable(void)
{
    DEBUGMSGTL(("verbose:ipAddressTable:init_ipAddressTable", "called\n"));

    /*
     * TODO:300:o: Perform ipAddressTable one-time module initialization.
     */

    /*
     * here we initialize all the tables we're planning on supporting
     */
    if (should_init("ipAddressTable"))
        initialize_table_ipAddressTable();

}                               /* init_ipAddressTable */

/**
 * Shut-down the ipAddressTable module (agent is exiting)
 */
void
shutdown_ipAddressTable(void)
{
    if (should_init("ipAddressTable"))
        shutdown_table_ipAddressTable();

}

/**
 * Initialize the table ipAddressTable 
 *    (Define its contents and how it's structured)
 */
void
initialize_table_ipAddressTable(void)
{
    u_long          flags;

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

    /*
     * TODO:301:o: Perform ipAddressTable one-time table initialization.
     */

    /*
     * TODO:302:o: |->Initialize ipAddressTable user context
     * if you'd like to pass in a pointer to some data for this
     * table, allocate or set it up here.
     */
    ipAddressTable_user_context_p = NULL;

    /*
     * No support for any flags yet, but in the future you would
     * set any flags here.
     */
    flags = 0;

    /*
     * call interface initialization code
     */
    _ipAddressTable_initialize_interface(ipAddressTable_user_context_p, flags);
}                               /* initialize_table_ipAddressTable */

/**
 * Shutdown the table ipAddressTable 
 */
void
shutdown_table_ipAddressTable(void)
{
    /*
     * call interface shutdown code
     */
    _ipAddressTable_shutdown_interface(ipAddressTable_user_context_p);
    netsnmp_free_all_list_data(ipAddressTable_user_context_p);
    ipAddressTable_user_context_p = NULL;
}

/**
 * extra context initialization (eg default values)
 *
 * @param rowreq_ctx    : row request context
 * @param user_init_ctx : void pointer for user (parameter to rowreq_ctx_allocate)
 *
 * @retval MFD_SUCCESS  : no errors
 * @retval MFD_ERROR    : error (context allocate will fail)
 */
int
ipAddressTable_rowreq_ctx_init(ipAddressTable_rowreq_ctx * rowreq_ctx,
                               void *user_init_ctx)
{
    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_rowreq_ctx_init",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:210:o: |-> Perform extra ipAddressTable rowreq initialization. (eg DEFVALS)
     */

    return MFD_SUCCESS;
}                               /* ipAddressTable_rowreq_ctx_init */

/**
 * extra context cleanup
 *
 */
void
ipAddressTable_rowreq_ctx_cleanup(ipAddressTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_rowreq_ctx_cleanup",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:211:o: |-> Perform extra ipAddressTable rowreq cleanup.
     */
    if (NULL != rowreq_ctx->data) {
        ipAddressTable_release_data(rowreq_ctx->data);
        rowreq_ctx->data = NULL;
    }
}                               /* ipAddressTable_rowreq_ctx_cleanup */

/**
 * pre-request callback
 *
 * @param user_context
 *
 * @retval MFD_SUCCESS              : success.
 * @retval MFD_ERROR                : other error
 */
int
ipAddressTable_pre_request(ipAddressTable_registration * user_context)
{
    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_pre_request",
                "called\n"));

    /*
     * TODO:510:o: Perform ipAddressTable pre-request actions.
     */

    return MFD_SUCCESS;
}                               /* ipAddressTable_pre_request */

/**
 * post-request callback
 *
 * Note:
 *   New rows have been inserted into the container, and
 *   deleted rows have been removed from the container and
 *   released.
 *
 * @param user_context
 * @param rc : MFD_SUCCESS if all requests succeeded
 *
 * @retval MFD_SUCCESS : success.
 * @retval MFD_ERROR   : other error (ignored)
 */
int
ipAddressTable_post_request(ipAddressTable_registration * user_context,
                            int rc)
{
    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_post_request",
                "called\n"));

    /*
     * TODO:511:o: Perform ipAddressTable post-request actions.
     */

    /*
     * check to set if any rows were changed.
     */
    if (ipAddressTable_dirty_get()) {
        /*
         * check if request was successful. If so, this would be
         * a good place to save data to its persistent store.
         */
        if (MFD_SUCCESS == rc) {
            /*
             * save changed rows, if you haven't already
             */
        }

        ipAddressTable_dirty_set(0);    /* clear table dirty flag */
    }

    return MFD_SUCCESS;
}                               /* ipAddressTable_post_request */


/**********************************************************************
 **********************************************************************
 ***
 *** 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
 */

/*
 * ---------------------------------------------------------------------
 * * TODO:200:r: Implement ipAddressTable data context functions.
 */
/*
 * ipAddressTable_allocate_data
 *
 * Purpose: create new ipAddressTable_data.
 */
ipAddressTable_data *
ipAddressTable_allocate_data(void)
{
    /*
     * TODO:201:r: |-> allocate memory for the ipAddressTable data context.
     */
    ipAddressTable_data *rtn = netsnmp_access_ipaddress_entry_create();

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

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

    return rtn;
}                               /* ipAddressTable_allocate_data */

/*
 * ipAddressTable_release_data
 *
 * Purpose: release ipAddressTable data.
 */
void
ipAddressTable_release_data(ipAddressTable_data * data)
{
    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_release_data",
                "called\n"));

    /*
     * TODO:202:r: |-> release memory for the ipAddressTable data context.
     */
    netsnmp_access_ipaddress_entry_free(data);
}                               /* ipAddressTable_release_data */


/*---------------------------------------------------------------------
 * IP-MIB::ipAddressEntry.ipAddressAddrType
 * ipAddressAddrType is subid 1 of ipAddressEntry.
 * Its status is Current, and its access level is NoAccess.
 * OID: .1.3.6.1.2.1.4.34.1.1
 * Description:
The address type of ipAddressAddr.
 *
 * Attributes:
 *   accessible 0     isscalar 0     enums  1      hasdefval 0
 *   readable   0     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 * Enum range: 5/8. Values:  unknown(0), ipv4(1), ipv6(2), ipv4z(3), ipv6z(4), dns(16)
 *
 * Its syntax is InetAddressType (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 *
 *
 *
 * NOTE: NODE ipAddressAddrType IS NOT ACCESSIBLE
 *
 *
 */
/**
 * map a value from its original native format to the MIB format.
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_ERROR           : Any other error
 *
 * @note parameters follow the memset convention (dest, src).
 *
 * @note generation and use of this function can be turned off by re-running
 * mib2c after adding the following line to the file
 * default-node-ipAddressAddrType.m2d :
 *   @verbatim $m2c_node_skip_mapping = 1@endverbatim
 *
 * @remark
 *  If the values for your data type don't exactly match the
 *  possible values defined by the mib, you should map them here.
 *  Otherwise, just do a direct copy.
 */
int
ipAddressAddrType_map(long * mib_ipAddressAddrType_val_ptr,
                      long raw_ipAddressAddrType_val)
{
    netsnmp_assert(NULL != mib_ipAddressAddrType_val_ptr);

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

    /*
     * TODO:241:o: |-> Implement ipAddressAddrType enum mapping.
     * uses INTERNAL_* macros defined in the header files
     */
    switch (raw_ipAddressAddrType_val) {
    case INTERNAL_IPADDRESSTABLE_IPADDRESSADDRTYPE_IPV4:
        *mib_ipAddressAddrType_val_ptr = INETADDRESSTYPE_IPV4;
        break;

    case INTERNAL_IPADDRESSTABLE_IPADDRESSADDRTYPE_IPV6:
        *mib_ipAddressAddrType_val_ptr = INETADDRESSTYPE_IPV6;
        break;

    default:
        snmp_log(LOG_ERR, "couldn't map value %ld for ipAddressAddrType\n",
                 raw_ipAddressAddrType_val);
        *mib_ipAddressAddrType_val_ptr = INETADDRESSTYPE_UNKNOWN;
    }

    return MFD_SUCCESS;
}                               /* ipAddressAddrType_map */


/**
 * set mib index(es)
 *
 * @param tbl_idx mib index structure
 * @param ipAddressAddrType_val
 * @param ipAddressAddr_val_ptr
 * @param ipAddressAddr_val_ptr_len
 *
 * @retval MFD_SUCCESS     : success.
 * @retval MFD_ERROR       : other error.
 *
 * @remark
 *  This convenience function is useful for setting all the MIB index
 *  components with a single function call. It is assume that the C values
 *  have already been mapped from their native/rawformat to the MIB format.
 */
int
ipAddressTable_indexes_set_tbl_idx(ipAddressTable_mib_index * tbl_idx,
                                   long ipAddressAddrType_val,
                                   u_char *ipAddressAddr_val_ptr,
                                   size_t ipAddressAddr_val_ptr_len)
{
    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_indexes_set_tbl_idx", "called\n"));

    /*
     * ipAddressAddrType(1)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h 
     */
    /** WARNING: this code might not work for netsnmp_ipaddress_entry */
    ipAddressAddrType_map(&tbl_idx->ipAddressAddrType,
                          ipAddressAddrType_val);

    /*
     * ipAddressAddr(2)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h 
     */
    tbl_idx->ipAddressAddr_len = sizeof(tbl_idx->ipAddressAddr) / sizeof(tbl_idx->ipAddressAddr[0]);    /* max length */
    /** WARNING: this code might not work for netsnmp_ipaddress_entry */
    /*
     * make sure there is enough space for ipAddressAddr data
     */
    if (tbl_idx->ipAddressAddr_len < ipAddressAddr_val_ptr_len) {
        snmp_log(LOG_ERR, "not enough space for value\n");
        return MFD_ERROR;
    }
    tbl_idx->ipAddressAddr_len = ipAddressAddr_val_ptr_len;
    memcpy(tbl_idx->ipAddressAddr, ipAddressAddr_val_ptr,
           ipAddressAddr_val_ptr_len * sizeof(ipAddressAddr_val_ptr[0]));


    return MFD_SUCCESS;
}                               /* ipAddressTable_indexes_set_tbl_idx */

/**
 * @internal
 * set row context indexes
 *
 * @param reqreq_ctx the row context that needs updated indexes
 *
 * @retval MFD_SUCCESS     : success.
 * @retval MFD_ERROR       : other error.
 *
 * @remark
 *  This function sets the mib indexs, then updates the oid indexs
 *  from the mib index.
 */
int
ipAddressTable_indexes_set(ipAddressTable_rowreq_ctx * rowreq_ctx,
                           u_long ipAddressAddrType_val,
                           u_char *ipAddressAddr_val_ptr,
                           size_t ipAddressAddr_val_ptr_len)
{
    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_indexes_set",
                "called\n"));

    if (MFD_SUCCESS !=
        ipAddressTable_indexes_set_tbl_idx(&rowreq_ctx->tbl_idx,
                                           ipAddressAddrType_val,
                                           ipAddressAddr_val_ptr,
                                           ipAddressAddr_val_ptr_len))
        return MFD_ERROR;

    /*
     * convert mib index to oid index
     */
    rowreq_ctx->oid_idx.len = sizeof(rowreq_ctx->oid_tmp) / sizeof(oid);
    if (0 != ipAddressTable_index_to_oid(&rowreq_ctx->oid_idx,
                                         &rowreq_ctx->tbl_idx)) {
        return MFD_ERROR;
    }

    return MFD_SUCCESS;
}                               /* ipAddressTable_indexes_set */


/*---------------------------------------------------------------------
 * IP-MIB::ipAddressEntry.ipAddressIfIndex
 * ipAddressIfIndex is subid 3 of ipAddressEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.34.1.3
 * Description:
The index value which uniquely identifies the interface to
            which this entry is applicable.  The interface identified by
            a particular value of this index is the same interface as
            identified by the same value of the IF-MIB's ifIndex.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 1      hashint   1
 *   settable   1
 *   hint: d
 *
 * Ranges:  1 - 2147483647;
 *
 * Its syntax is InterfaceIndex (based on perltype INTEGER32)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (long)
 */
/**
 * Extract the current value of the ipAddressIfIndex data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipAddressIfIndex_val_ptr
 *        Pointer to storage for a long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ipAddressIfIndex_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
                     long *ipAddressIfIndex_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipAddressIfIndex_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipAddressIfIndex data.
     * copy (* ipAddressIfIndex_val_ptr ) from rowreq_ctx->data
     */
    (*ipAddressIfIndex_val_ptr) = rowreq_ctx->data->if_index;

    return MFD_SUCCESS;
}                               /* ipAddressIfIndex_get */

/*---------------------------------------------------------------------
 * IP-MIB::ipAddressEntry.ipAddressType
 * ipAddressType is subid 4 of ipAddressEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.34.1.4
 * Description:
The type of address.  broadcast(3) is not a valid value for
            IPv6 addresses (RFC3513).  
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: unicast
 *
 * Enum range: 2/8. Values:  unicast(1), anycast(2), broadcast(3)
 *
 * Its syntax is INTEGER (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Extract the current value of the ipAddressType data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipAddressType_val_ptr
 *        Pointer to storage for a long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ipAddressType_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
                  u_long * ipAddressType_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipAddressType_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipAddressType data.
     * copy (* ipAddressType_val_ptr ) from rowreq_ctx->data
     */
    (*ipAddressType_val_ptr) = rowreq_ctx->data->ia_type;

    return MFD_SUCCESS;
}                               /* ipAddressType_get */

/*---------------------------------------------------------------------
 * IP-MIB::ipAddressEntry.ipAddressPrefix
 * ipAddressPrefix is subid 5 of ipAddressEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.34.1.5
 * Description:
A pointer to the row in the prefix table to which this
            address belongs.  May be { 0 0 } if there is no such row.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *   defval: zeroDotZero
 *
 *
 * Its syntax is RowPointer (based on perltype OBJECTID)
 * The net-snmp type is ASN_OBJECT_ID. The C type decl is oid (oid)
 * This data type requires a length.
 */
/**
 * Extract the current value of the ipAddressPrefix data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipAddressPrefix_val_ptr_ptr
 *        Pointer to storage for a oid variable
 * @param ipAddressPrefix_val_ptr_len_ptr
 *        Pointer to a size_t. On entry, it will contain the size (in bytes)
 *        pointed to by ipAddressPrefix.
 *        On exit, this value should contain the data size (in bytes).
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
*
 * @note If you need more than (*ipAddressPrefix_val_ptr_len_ptr) bytes of memory,
 *       allocate it using malloc() and update ipAddressPrefix_val_ptr_ptr.
 *       <b>DO NOT</b> free the previous pointer.
 *       The MFD helper will release the memory you allocate.
 *
 * @remark If you call this function yourself, you are responsible
 *         for checking if the pointer changed, and freeing any
 *         previously allocated memory. (Not necessary if you pass
 *         in a pointer to static memory, obviously.)
 */
int
ipAddressPrefix_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
                    oid ** ipAddressPrefix_val_ptr_ptr,
                    size_t * ipAddressPrefix_val_ptr_len_ptr)
{
    oid            *dst, tmp_oid[MAX_OID_LEN] =
        { 1, 3, 6, 1, 2, 1, 4, 32, 1, 5 };
    u_char          tmp_buf[NETSNMP_ACCESS_IPADDRESS_BUF_SIZE];
    size_t          len;

   /** we should have a non-NULL pointer and enough storage */
    netsnmp_assert((NULL != ipAddressPrefix_val_ptr_ptr)
                   && (NULL != *ipAddressPrefix_val_ptr_ptr));
    netsnmp_assert(NULL != ipAddressPrefix_val_ptr_len_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipAddressPrefix data.
     * copy (* ipAddressPrefix_val_ptr_ptr ) data and (* ipAddressPrefix_val_ptr_len_ptr ) from rowreq_ctx->data
     */
    dst = &tmp_oid[10];
    *(dst++) = rowreq_ctx->data->if_index;
    *(dst++) = rowreq_ctx->tbl_idx.ipAddressAddrType;
    *(dst++) = rowreq_ctx->data->ia_address_len;
    netsnmp_ipaddress_prefix_copy(tmp_buf,
                                  (u_char *) rowreq_ctx->tbl_idx.ipAddressAddr,
                                  rowreq_ctx->data->ia_address_len,
                                  rowreq_ctx->data->ia_prefix_len);
    for (len = 0; len < rowreq_ctx->data->ia_address_len; ++len)
        *(dst++) = tmp_buf[len];
    *(dst++) = rowreq_ctx->data->ia_prefix_len;
    len = dst - tmp_oid;

    len *= sizeof((*ipAddressPrefix_val_ptr_ptr)[0]);
    if ((*ipAddressPrefix_val_ptr_len_ptr) < len) {
        (*ipAddressPrefix_val_ptr_ptr) = (oid*)malloc(len);
        if (NULL == (*ipAddressPrefix_val_ptr_ptr)) {
            snmp_log(LOG_ERR, "could not allocate memory\n");
            return MFD_ERROR;
        }
    }
    (*ipAddressPrefix_val_ptr_len_ptr) = len;
    memcpy((*ipAddressPrefix_val_ptr_ptr), tmp_oid, len);

    return MFD_SUCCESS;
}                               /* ipAddressPrefix_get */

/*---------------------------------------------------------------------
 * IP-MIB::ipAddressEntry.ipAddressOrigin
 * ipAddressOrigin is subid 6 of ipAddressEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.34.1.6
 * Description:
The origin of the address.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 * Enum range: 4/8. Values:  other(1), manual(2), dhcp(4), linklayer(5), random(6)
 *
 * Its syntax is IpAddressOriginTC (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Extract the current value of the ipAddressOrigin data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipAddressOrigin_val_ptr
 *        Pointer to storage for a long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ipAddressOrigin_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
                    u_long * ipAddressOrigin_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipAddressOrigin_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipAddressOrigin data.
     * copy (* ipAddressOrigin_val_ptr ) from rowreq_ctx->data
     */
    (*ipAddressOrigin_val_ptr) = rowreq_ctx->data->ia_origin;

    return MFD_SUCCESS;
}                               /* ipAddressOrigin_get */

/*---------------------------------------------------------------------
 * IP-MIB::ipAddressEntry.ipAddressStatus
 * ipAddressStatus is subid 7 of ipAddressEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.34.1.7
 * Description:
The status of the address, describing if the address can be
            used for communication.


            In the absence of other information, an IPv4 address is
            always preferred(1).
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: preferred
 *
 * Enum range: 5/8. Values:  preferred(1), invalid(3), inaccessible(4), unknown(5), tentative(6), duplicate(7)
 *
 * Its syntax is IpAddressStatusTC (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Extract the current value of the ipAddressStatus data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipAddressStatus_val_ptr
 *        Pointer to storage for a long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ipAddressStatus_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
                    u_long * ipAddressStatus_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipAddressStatus_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipAddressStatus data.
     * copy (* ipAddressStatus_val_ptr ) from rowreq_ctx->data
     */
    (*ipAddressStatus_val_ptr) = rowreq_ctx->data->ia_status;

    return MFD_SUCCESS;
}                               /* ipAddressStatus_get */

/*---------------------------------------------------------------------
 * IP-MIB::ipAddressEntry.ipAddressCreated
 * ipAddressCreated is subid 8 of ipAddressEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.34.1.8
 * Description:
The value of sysUpTime at the time this entry was created.
            If this entry was created prior to the last re-
            initialization of the local network management subsystem,
            then this object contains a zero value.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is TimeStamp (based on perltype TICKS)
 * The net-snmp type is ASN_TIMETICKS. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the ipAddressCreated data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipAddressCreated_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ipAddressCreated_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
                     u_long * ipAddressCreated_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipAddressCreated_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipAddressCreated data.
     * copy (* ipAddressCreated_val_ptr ) from rowreq_ctx->data
     */
    (*ipAddressCreated_val_ptr) = rowreq_ctx->ipAddressCreated;

    return MFD_SUCCESS;
}                               /* ipAddressCreated_get */

/*---------------------------------------------------------------------
 * IP-MIB::ipAddressEntry.ipAddressLastChanged
 * ipAddressLastChanged is subid 9 of ipAddressEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.34.1.9
 * Description:
The value of sysUpTime at the time this entry was last
            updated.  If this entry was updated prior to the last re-
            initialization of the local network management subsystem,
            then this object contains a zero value.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is TimeStamp (based on perltype TICKS)
 * The net-snmp type is ASN_TIMETICKS. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the ipAddressLastChanged data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipAddressLastChanged_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ipAddressLastChanged_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
                         u_long * ipAddressLastChanged_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipAddressLastChanged_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipAddressLastChanged data.
     * copy (* ipAddressLastChanged_val_ptr ) from rowreq_ctx->data
     */
    (*ipAddressLastChanged_val_ptr) = rowreq_ctx->ipAddressLastChanged;

    return MFD_SUCCESS;
}                               /* ipAddressLastChanged_get */

/*---------------------------------------------------------------------
 * IP-MIB::ipAddressEntry.ipAddressRowStatus
 * ipAddressRowStatus is subid 10 of ipAddressEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.34.1.10
 * Description:
The status of this conceptual row.


            The RowStatus TC requires that this DESCRIPTION clause
            states under which circumstances other objects in this row
            can be modified.  The value of this object has no effect on
            whether other objects in this conceptual row can be
            modified.


            A conceptual row can not be made active until the
            ipAddressIfIndex has been set to a valid index.  
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 * Enum range: 3/8. Values:  active(1), notInService(2), notReady(3), createAndGo(4), createAndWait(5), destroy(6)
 *
 * Its syntax is RowStatus (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Extract the current value of the ipAddressRowStatus data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipAddressRowStatus_val_ptr
 *        Pointer to storage for a long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ipAddressRowStatus_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
                       u_long * ipAddressRowStatus_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipAddressRowStatus_val_ptr);

    /** WARNING: this code might not work for netsnmp_ipaddress_entry */
    if(rowreq_ctx->data->if_index)
       (*ipAddressRowStatus_val_ptr) = rowreq_ctx->ipAddressRowStatus;
    else
       (*ipAddressRowStatus_val_ptr) = ROWSTATUS_NOTREADY;

    return MFD_SUCCESS;
}                               /* ipAddressRowStatus_get */

/*---------------------------------------------------------------------
 * IP-MIB::ipAddressEntry.ipAddressStorageType
 * ipAddressStorageType is subid 11 of ipAddressEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.34.1.11
 * Description:
The storage type for this conceptual row.  If this object
            has a value of 'permanent' then no other objects are
            required to be able to be modified.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: volatile
 *
 * Enum range: 4/8. Values:  other(1), volatile(2), nonVolatile(3), permanent(4), readOnly(5)
 *
 * Its syntax is StorageType (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Extract the current value of the ipAddressStorageType data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipAddressStorageType_val_ptr
 *        Pointer to storage for a long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ipAddressStorageType_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
                         u_long * ipAddressStorageType_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipAddressStorageType_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipAddressStorageType data.
     * copy (* ipAddressStorageType_val_ptr ) from rowreq_ctx->data
     */
    (*ipAddressStorageType_val_ptr) = rowreq_ctx->data->ia_storagetype;

    return MFD_SUCCESS;
}                               /* ipAddressStorageType_get */



/** @} */
/**********************************************************************
 **********************************************************************
 ***
 *** 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
 */
    /*
     * NOTE: if you update this chart, please update the versions in
     *       local/mib2c-conf.d/parent-set.m2i
     *       agent/mibgroup/helpers/baby_steps.c
     * while you're at it.
     */
    /*
     ***********************************************************************
     * Baby Steps Flow Chart (2004.06.05)                                  *
     *                                                                     *
     * +--------------+    +================+    U = unconditional path    *
     * |optional state|    ||required state||    S = path for success      *
     * +--------------+    +================+    E = path for error        *
     ***********************************************************************
     *
     *                        +--------------+
     *                        |     pre      |
     *                        |   request    |
     *                        +--------------+
     *                               | U
     * +-------------+        +==============+
     * |    row    |f|<-------||  object    ||
     * |  create   |1|      E ||  lookup    ||
     * +-------------+        +==============+
     *     E |   | S                 | S
     *       |   +------------------>|
     *       |                +==============+
     *       |              E ||   check    ||
     *       |<---------------||   values   ||
     *       |                +==============+
     *       |                       | S
     *       |                +==============+
     *       |       +<-------||   undo     ||
     *       |       |      E ||   setup    ||
     *       |       |        +==============+
     *       |       |               | S
     *       |       |        +==============+
     *       |       |        ||    set     ||-------------------------->+
     *       |       |        ||   value    || E                         |
     *       |       |        +==============+                           |
     *       |       |               | S                                 |
     *       |       |        +--------------+                           |
     *       |       |        |    check     |-------------------------->|
     *       |       |        |  consistency | E                         |
     *       |       |        +--------------+                           |
     *       |       |               | S                                 |
     *       |       |        +==============+         +==============+  |
     *       |       |        ||   commit   ||-------->||     undo   ||  |
     *       |       |        ||            || E       ||    commit  ||  |
     *       |       |        +==============+         +==============+  |
     *       |       |               | S                     U |<--------+
     *       |       |        +--------------+         +==============+
     *       |       |        | irreversible |         ||    undo    ||
     *       |       |        |    commit    |         ||     set    ||
     *       |       |        +--------------+         +==============+
     *       |       |               | U                     U |
     *       |       +-------------->|<------------------------+
     *       |                +==============+
     *       |                ||   undo     ||
     *       |                ||  cleanup   ||
     *       |                +==============+
     *       +---------------------->| U
     *                               |
     *                          (err && f1)------------------->+
     *                               |                         |
     *                        +--------------+         +--------------+
     *                        |    post      |<--------|      row     |
     *                        |   request    |       U |    release   |
     *                        +--------------+         +--------------+
     *
     */

/**
 * Setup up context with information needed to undo a set request.
 *
 * This function will be called before the individual node undo setup
 * functions are called. If you need to do any undo setup that is not
 * related to a specific column, you can do it here.
 *
 * Note that the undo context has been allocated with
 * ipAddressTable_allocate_data(), but may need extra
 * initialization similar to what you may have done in
 * ipAddressTable_rowreq_ctx_init().
 * Note that an individual node's undo_setup function will only be called
 * if that node is being set to a new value.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in the node's undo_setup
 * function, so it won't be done unless it is necessary.
 *
 * @param rowreq_ctx
 *        Pointer to the table context (ipAddressTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 */
int
ipAddressTable_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

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

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:451:M: |-> Setup ipAddressTable undo.
     * set up ipAddressTable undo information, in preparation for a set.
     * Undo storage is in (* ipAddressStorageType_val_ptr )*
     */
    /*
     * check for storage types that don't allow modification.
     * probably should try and do this earlier (and we could, by
     * adding code to the interface file), but this ought to suffice.
     */
    if (STORAGETYPE_READONLY == rowreq_ctx->data->ia_storagetype) {
        DEBUGMSGTL(("ipAddressTable", "can't change readonly row\n"));
        return MFD_NOT_VALID_EVER;
    }

    /*
     * save last changed
     */
    rowreq_ctx->ipAddressLastChanged_undo =
        rowreq_ctx->ipAddressLastChanged;


    /*
     * just copy everything
     */
    rc = netsnmp_access_ipaddress_entry_copy(rowreq_ctx->undo,
                                             rowreq_ctx->data);

    return rc;
}                               /* ipAddressTable_undo_setup */

/**
 * Undo a set request.
 *
 * This function will be called before the individual node undo
 * functions are called. If you need to do any undo that is not
 * related to a specific column, you can do it here.
 *
 * Note that an individual node's undo function will only be called
 * if that node is being set to a new value.
 *
 * If there is anything  specific to a particular column (e.g. releasing
 * memory for a string), you should do that setup in the node's undo
 * function, so it won't be done unless it is necessary.
 *
 * @param rowreq_ctx
 *        Pointer to the table context (ipAddressTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 */
int
ipAddressTable_undo(ipAddressTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

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

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:451:M: |-> ipAddressTable undo.
     * ipAddressTable undo information, in response to a failed set.
     * Undo storage is in (* ipAddressStorageType_val_ptr )*
     */

    return rc;
}                               /* ipAddressTable_undo_setup */

/**
 * Cleanup up context undo information.
 *
 * This function will be called after set/commit processing. If you
 * allocated any resources in undo_setup, this is the place to release
 * those resources.
 *
 * This function is called regardless of the success or failure of the set
 * request. If you need to perform different steps for cleanup depending
 * on success or failure, you can add a flag to the rowreq_ctx.
 *
 * @param rowreq_ctx
 *        Pointer to the table context (ipAddressTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error
 */
int
ipAddressTable_undo_cleanup(ipAddressTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

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

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:452:M: |-> Cleanup ipAddressTable undo.
     * Undo storage is in (* ipAddressStorageType_val_ptr )*
     */
    rowreq_ctx->ipAddressLastChanged =
        rowreq_ctx->ipAddressLastChanged_undo;

    return rc;
}                               /* ipAddressTable_undo_cleanup */

/**
 * commit new values.
 *
 * At this point, you should have done everything you can to ensure that
 * this commit will not fail.
 *
 * Should you need different behavior depending on which columns were
 * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
 * set. The definitions for the COLUMN_*_FLAG bits can be found in
 * ipAddressTable.h.
 * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error
 */
int
ipAddressTable_commit(ipAddressTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

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

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * commit ipAddressTable data
     * 1) check the column's flag to see if it was set.
     * 2) clear the flag when you handle that column
     * 3) set the column's flag in column_set_flags if it needs undo
     *    processing in case of a failure.
     */
    /*
     * did anything change?
     */
    if (0 == rowreq_ctx->column_set_flags) {
        DEBUGMSGTL(("ipAddressTable:ipAddressTable_commit",
                    "no change\n"));
        return MFD_SUCCESS;
    }

    /*
     * pass everything to data access
     * let data access know what columns are set
     */
    rowreq_ctx->data->flags = rowreq_ctx->column_set_flags;

    if (rowreq_ctx->column_set_flags & COLUMN_IPADDRESSROWSTATUS_FLAG) {
        if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED) {
            rowreq_ctx->data->flags |= NETSNMP_ACCESS_IPADDRESS_CREATE;
            rowreq_ctx->ipAddressCreated = netsnmp_get_agent_uptime();
        } else if (ROWSTATUS_DESTROY == rowreq_ctx->ipAddressRowStatus) {
            rowreq_ctx->data->flags |= NETSNMP_ACCESS_IPADDRESS_DELETE;
        } else
            rowreq_ctx->data->flags |= NETSNMP_ACCESS_IPADDRESS_CHANGE;
    } else
        rowreq_ctx->data->flags |= NETSNMP_ACCESS_IPADDRESS_CHANGE;

    /*
     * do it
     */
    rc = netsnmp_access_ipaddress_entry_set(rowreq_ctx->data);
    if (rc) {
        DEBUGMSGTL(("ipAddressTable",
                    "bad rc %d from IP address data access\n", rc));
        rc = MFD_ERROR;
    } else {
        rowreq_ctx->ipAddressLastChanged = netsnmp_get_agent_uptime();
    }

    /*
     * if we successfully commited this row, set the dirty flag.
     */
    if (MFD_SUCCESS == rc) {
        rowreq_ctx->rowreq_flags |= MFD_ROW_DIRTY;
    }

    return rc;
}                               /* ipAddressTable_commit */

/**
 * undo commit new values.
 *
 * Should you need different behavior depending on which columns were
 * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
 * set. The definitions for the COLUMN_*_FLAG bits can be found in
 * ipAddressTable.h.
 * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error
 */
int
ipAddressTable_undo_commit(ipAddressTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

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

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:485:M: |-> Undo ipAddressTable commit.
     * check the column's flag in rowreq_ctx->column_set_flags to see
     * if it was set during commit, then undo it.
     *
     * eg: if (rowreq_ctx->column_set_flags & COLUMN__FLAG) {}
     */
    if (rowreq_ctx->column_set_flags & COLUMN_IPADDRESSROWSTATUS_FLAG) {
        /*
         * if we created an addr, delete it. if we deleted it,
         * re-create it. If we changed it, change it back.
         */
        if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED) {
            rowreq_ctx->undo->flags |= NETSNMP_ACCESS_IPADDRESS_DELETE;
        } else if (ROWSTATUS_DESTROY == rowreq_ctx->ipAddressRowStatus) {
            rowreq_ctx->undo->flags |= NETSNMP_ACCESS_IPADDRESS_CREATE;
        } else
            rowreq_ctx->undo->flags |= NETSNMP_ACCESS_IPADDRESS_CHANGE;
    } else
        rowreq_ctx->undo->flags |= NETSNMP_ACCESS_IPADDRESS_CHANGE;

    /*
     * do it
     */
    rc = netsnmp_access_ipaddress_entry_set(rowreq_ctx->undo);
    if (rc) {
        DEBUGMSGTL(("ipAddressTable",
                    "bad rc %d from IP address data access\n", rc));
        rc = MFD_ERROR;
    }

    /*
     * if we successfully un-commited this row, clear the dirty flag.
     */
    if (MFD_SUCCESS == rc) {
        rowreq_ctx->rowreq_flags &= ~MFD_ROW_DIRTY;
    }

    return rc;
}                               /* ipAddressTable_undo_commit */

/*
 * TODO:440:M: Implement ipAddressTable node value checks.
 * TODO:450:M: Implement ipAddressTable undo functions.
 * TODO:460:M: Implement ipAddressTable set functions.
 * TODO:480:M: Implement ipAddressTable commit functions.
 */
/*---------------------------------------------------------------------
 * IP-MIB::ipAddressEntry.ipAddressIfIndex
 * ipAddressIfIndex is subid 3 of ipAddressEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.34.1.3
 * Description:
The index value which uniquely identifies the interface to
            which this entry is applicable.  The interface identified by
            a particular value of this index is the same interface as
            identified by the same value of the IF-MIB's ifIndex.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 1      hashint   1
 *   settable   1
 *   hint: d
 *
 * Ranges:  1 - 2147483647;
 *
 * Its syntax is InterfaceIndex (based on perltype INTEGER32)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (long)
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipAddressIfIndex_val
 *        A long containing the new value.
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * ipAddressTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_INTEGER
 *    The value is in (one of) the range set(s):  1 - 2147483647
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
ipAddressIfIndex_check_value(ipAddressTable_rowreq_ctx * rowreq_ctx,
                             long ipAddressIfIndex_val)
{
    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressIfIndex_check_value",
                "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:441:o: |-> Check for valid ipAddressIfIndex value.
     */
    /*
     * if the new value is the same as the old, accept it.
     */
    if (ipAddressIfIndex_val == (long)rowreq_ctx->data->if_index)
        return MFD_SUCCESS;

    /*
     * currently don't support moving addresses between interfaces, so
     * if this isn't a new row, return error.
     */
    if (!(rowreq_ctx->rowreq_flags & MFD_ROW_CREATED)) {
        DEBUGMSGT(("ipAddressTable",
                   "changing ifIndex value not supported\n"));
        return MFD_NOT_VALID_EVER;
    }

    /*
     * find name for ifIndex
     */
    if (NULL == netsnmp_access_interface_name_find(ipAddressIfIndex_val)) {
        DEBUGMSGT(("ipAddressTable", "cant find name for index %ld\n",
                   ipAddressIfIndex_val));
        return MFD_NOT_VALID_NOW;
    }

    return MFD_SUCCESS;         /* ipAddressIfIndex value not illegal */
}                               /* ipAddressIfIndex_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (ipAddressTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * ipAddressTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
ipAddressIfIndex_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressIfIndex_undo_setup",
                "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:455:o: |-> Setup ipAddressIfIndex undo.
     */
    /*
     * handled in ipAddressTable_undo_setup
     */

    return MFD_SUCCESS;
}                               /* ipAddressIfIndex_undo_setup */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param ipAddressIfIndex_val
 *        A long containing the new value.
 */
int
ipAddressIfIndex_set(ipAddressTable_rowreq_ctx * rowreq_ctx,
                     long ipAddressIfIndex_val)
{

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

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:461:M: |-> Set ipAddressIfIndex value.
     * set ipAddressIfIndex value in rowreq_ctx->data
     */
    if (rowreq_ctx->data->if_index != (oid)ipAddressIfIndex_val)
        rowreq_ctx->data->if_index  = (oid)ipAddressIfIndex_val;
    else
        rowreq_ctx->column_set_flags &= ~COLUMN_IPADDRESSIFINDEX_FLAG;

    return MFD_SUCCESS;
}                               /* ipAddressIfIndex_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
ipAddressIfIndex_undo(ipAddressTable_rowreq_ctx * rowreq_ctx)
{

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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up ipAddressIfIndex undo.
     */
    /*
     * copy ipAddressIfIndex data
     * set rowreq_ctx->data->ipAddressIfIndex from rowreq_ctx->undo->ipAddressIfIndex
     */
    rowreq_ctx->data->if_index = rowreq_ctx->undo->if_index;

    return MFD_SUCCESS;
}                               /* ipAddressIfIndex_undo */

/*---------------------------------------------------------------------
 * IP-MIB::ipAddressEntry.ipAddressType
 * ipAddressType is subid 4 of ipAddressEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.34.1.4
 * Description:
The type of address.  broadcast(3) is not a valid value for
            IPv6 addresses (RFC3513).  
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: unicast
 *
 * Enum range: 2/8. Values:  unicast(1), anycast(2), broadcast(3)
 *
 * Its syntax is INTEGER (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipAddressType_val
 *        A long containing the new value.
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * ipAddressTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_INTEGER
 *    The value is one of  unicast(1), anycast(2), broadcast(3)
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
ipAddressType_check_value(ipAddressTable_rowreq_ctx * rowreq_ctx,
                          u_long ipAddressType_val)
{
    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressType_check_value",
                "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:441:o: |-> Check for valid ipAddressType value.
     *
     * no support for anything but unicast yet
     */
    if (ipAddressType_val != IPADDRESSTYPE_UNICAST)
        return MFD_NOT_VALID_EVER;

    return MFD_SUCCESS;         /* ipAddressType value not illegal */
}                               /* ipAddressType_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (ipAddressTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * ipAddressTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
ipAddressType_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressType_undo_setup",
                "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:455:o: |-> Setup ipAddressType undo.
     */
    /*
     * handled in ipAddressTable_undo_setup
     */

    return MFD_SUCCESS;
}                               /* ipAddressType_undo_setup */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param ipAddressType_val
 *        A long containing the new value.
 */
int
ipAddressType_set(ipAddressTable_rowreq_ctx * rowreq_ctx,
                  u_long ipAddressType_val)
{

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

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:461:M: |-> Set ipAddressType value.
     * set ipAddressType value in rowreq_ctx->data
     */
    rowreq_ctx->data->ia_type = ipAddressType_val;

    return MFD_SUCCESS;
}                               /* ipAddressType_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
ipAddressType_undo(ipAddressTable_rowreq_ctx * rowreq_ctx)
{

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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up ipAddressType undo.
     */
    /*
     * copy ipAddressType data
     * set rowreq_ctx->data->ipAddressType from rowreq_ctx->undo->ipAddressType
     */
    rowreq_ctx->data->ia_type = rowreq_ctx->undo->ia_type;

    return MFD_SUCCESS;
}                               /* ipAddressType_undo */

/*---------------------------------------------------------------------
 * IP-MIB::ipAddressEntry.ipAddressStatus
 * ipAddressStatus is subid 7 of ipAddressEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.34.1.7
 * Description:
The status of the address, describing if the address can be
            used for communication.


            In the absence of other information, an IPv4 address is
            always preferred(1).
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: preferred
 *
 * Enum range: 5/8. Values:  preferred(1), invalid(3), inaccessible(4), unknown(5), tentative(6), duplicate(7)
 *
 * Its syntax is IpAddressStatusTC (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipAddressStatus_val
 *        A long containing the new value.
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * ipAddressTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_INTEGER
 *    The value is one of  preferred(1), invalid(3), inaccessible(4), unknown(5), tentative(6), duplicate(7)
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
ipAddressStatus_check_value(ipAddressTable_rowreq_ctx * rowreq_ctx,
                            u_long ipAddressStatus_val)
{
    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressStatus_check_value",
                "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:441:o: |-> Check for valid ipAddressStatus value.
     *
     * nothing but preferred supported yet
     */
    if (IPADDRESSSTATUSTC_PREFERRED != ipAddressStatus_val)
        return MFD_NOT_VALID_EVER;

    return MFD_SUCCESS;         /* ipAddressStatus value not illegal */
}                               /* ipAddressStatus_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (ipAddressTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * ipAddressTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
ipAddressStatus_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressStatus_undo_setup",
                "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:455:o: |-> Setup ipAddressStatus undo.
     */
    /*
     * handled in ipAddressTable_undo_setup
     */

    return MFD_SUCCESS;
}                               /* ipAddressStatus_undo_setup */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param ipAddressStatus_val
 *        A long containing the new value.
 */
int
ipAddressStatus_set(ipAddressTable_rowreq_ctx * rowreq_ctx,
                    u_long ipAddressStatus_val)
{

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

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:461:M: |-> Set ipAddressStatus value.
     * set ipAddressStatus value in rowreq_ctx->data
     */
    rowreq_ctx->data->ia_status = ipAddressStatus_val;

    return MFD_SUCCESS;
}                               /* ipAddressStatus_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
ipAddressStatus_undo(ipAddressTable_rowreq_ctx * rowreq_ctx)
{

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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up ipAddressStatus undo.
     */
    /*
     * copy ipAddressStatus data
     * set rowreq_ctx->data->ipAddressStatus from rowreq_ctx->undo->ipAddressStatus
     */
    rowreq_ctx->data->ia_status = rowreq_ctx->undo->ia_status;

    return MFD_SUCCESS;
}                               /* ipAddressStatus_undo */

/*---------------------------------------------------------------------
 * IP-MIB::ipAddressEntry.ipAddressRowStatus
 * ipAddressRowStatus is subid 10 of ipAddressEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.34.1.10
 * Description:
The status of this conceptual row.


            The RowStatus TC requires that this DESCRIPTION clause
            states under which circumstances other objects in this row
            can be modified.  The value of this object has no effect on
            whether other objects in this conceptual row can be
            modified.


            A conceptual row can not be made active until the
            ipAddressIfIndex has been set to a valid index.  
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 * Enum range: 3/8. Values:  active(1), notInService(2), notReady(3), createAndGo(4), createAndWait(5), destroy(6)
 *
 * Its syntax is RowStatus (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipAddressRowStatus_val
 *        A long containing the new value.
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * ipAddressTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_INTEGER
 *    The value is one of  active(1), notInService(2), notReady(3), createAndGo(4), createAndWait(5), destroy(6)
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
ipAddressRowStatus_check_value(ipAddressTable_rowreq_ctx * rowreq_ctx,
                               u_long ipAddressRowStatus_val)
{
    int             rc;

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

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:441:o: |-> Check for valid ipAddressRowStatus value.
     *
     * don't support createAndWait
     * check for valid RowStatus transition (old, new)
     */
    if (ROWSTATUS_CREATEANDWAIT == ipAddressRowStatus_val) {
        DEBUGMSGTL(("ipAddressTable", "createAndWait not supported\n"));
        return MFD_NOT_VALID_EVER;
    }

    rc = check_rowstatus_transition(rowreq_ctx->ipAddressRowStatus,
                                    ipAddressRowStatus_val);
    if (MFD_SUCCESS != rc) {
        DEBUGMSGTL(("ipAddressTable",
                    "row status transition from %d to %lu\n",
                    rowreq_ctx->ipAddressRowStatus,
                    ipAddressRowStatus_val));
        return rc;
    }

    return MFD_SUCCESS;         /* ipAddressRowStatus value not illegal */
}                               /* ipAddressRowStatus_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (ipAddressTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * ipAddressTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
ipAddressRowStatus_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressRowStatus_undo_setup",
                "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:455:o: |-> Setup ipAddressRowStatus undo.
     */
    /*
     * handled in ipAddressTable_undo_setup
     */

    return MFD_SUCCESS;
}                               /* ipAddressRowStatus_undo_setup */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param ipAddressRowStatus_val
 *        A long containing the new value.
 */
int
ipAddressRowStatus_set(ipAddressTable_rowreq_ctx * rowreq_ctx,
                       u_long ipAddressRowStatus_val)
{

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

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:461:M: |-> Set ipAddressRowStatus value.
     * set ipAddressRowStatus value in rowreq_ctx->data
     */
    rowreq_ctx->ipAddressRowStatus = ipAddressRowStatus_val;

    return MFD_SUCCESS;
}                               /* ipAddressRowStatus_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
ipAddressRowStatus_undo(ipAddressTable_rowreq_ctx * rowreq_ctx)
{

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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up ipAddressRowStatus undo.
     */
    /*
     * copy ipAddressRowStatus data
     * set rowreq_ctx->data->ipAddressRowStatus from rowreq_ctx->undo->ipAddressRowStatus
     */
    rowreq_ctx->ipAddressRowStatus = rowreq_ctx->ipAddressRowStatus_undo;

    return MFD_SUCCESS;
}                               /* ipAddressRowStatus_undo */

/*---------------------------------------------------------------------
 * IP-MIB::ipAddressEntry.ipAddressStorageType
 * ipAddressStorageType is subid 11 of ipAddressEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.34.1.11
 * Description:
The storage type for this conceptual row.  If this object
            has a value of 'permanent' then no other objects are
            required to be able to be modified.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: volatile
 *
 * Enum range: 4/8. Values:  other(1), volatile(2), nonVolatile(3), permanent(4), readOnly(5)
 *
 * Its syntax is StorageType (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipAddressStorageType_val
 *        A long containing the new value.
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * ipAddressTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_INTEGER
 *    The value is one of  other(1), volatile(2), nonVolatile(3), permanent(4), readOnly(5)
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
ipAddressStorageType_check_value(ipAddressTable_rowreq_ctx * rowreq_ctx,
                                 u_long ipAddressStorageType_val)
{
    int             rc;

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

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:441:o: |-> Check for valid ipAddressStorageType value.
     */
    /*
     * since I don't know how the various operating systems
     * deal with ip addresses, and whether or not changes will
     * be saved on reboot, so don't allow rows to be set to anything
     * but volatile. I'd prefer other, but since the default for
     * new rows, per the mib, is volatile...
     *
     * If some industrious soul would like
     * non-volaltile support, the first would need to 
     *   add it in  the data access code for their os
     *   define a flag bit for volatile/permanent/readonly
     *   set the bit in data access
     *   copy the bit to a new var in the rowreq_ctx (see _add_new_entry)
     *        with a default of volatile (for os' w/out nonvolatile support)
     *   update this code to use new flag
     */
    if (STORAGETYPE_VOLATILE != ipAddressStorageType_val)
        return MFD_NOT_VALID_EVER;

    /*
     * check for valid StorageType transition (old, new)
     */
    rc = check_storage_transition(rowreq_ctx->data->ia_storagetype,
                                  ipAddressStorageType_val);
    if (MFD_SUCCESS != rc)
        return rc;

    return MFD_SUCCESS;         /* ipAddressStorageType value not illegal */
}                               /* ipAddressStorageType_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (ipAddressTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * ipAddressTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
ipAddressStorageType_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressStorageType_undo_setup",
                "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:455:o: |-> Setup ipAddressStorageType undo.
     */
    /*
     * handled in ipAddressTable_undo_setup
     */

    return MFD_SUCCESS;
}                               /* ipAddressStorageType_undo_setup */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param ipAddressStorageType_val
 *        A long containing the new value.
 */
int
ipAddressStorageType_set(ipAddressTable_rowreq_ctx * rowreq_ctx,
                         u_long ipAddressStorageType_val)
{

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

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:461:M: |-> Set ipAddressStorageType value.
     * set ipAddressStorageType value in rowreq_ctx->data
     */
    rowreq_ctx->data->ia_storagetype = ipAddressStorageType_val;

    return MFD_SUCCESS;
}                               /* ipAddressStorageType_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
ipAddressStorageType_undo(ipAddressTable_rowreq_ctx * rowreq_ctx)
{

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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up ipAddressStorageType undo.
     */
    /*
     * copy ipAddressStorageType data
     * set rowreq_ctx->data->ipAddressStorageType from rowreq_ctx->undo->ipAddressStorageType
     */
    rowreq_ctx->data->ia_storagetype = rowreq_ctx->undo->ia_storagetype;

    return MFD_SUCCESS;
}                               /* ipAddressStorageType_undo */

/**
 * check dependencies
 *
 * This is useful for for tables which have dependencies between columns
 * (or rows, or tables). For example, two columns allocating a percentage
 * of something add up 100%.
 *
 * Should you need different behavior depending on which columns were
 * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
 * set. The definitions for the COLUMN_*_FLAG bits can be found in
 * ipAddressTable.h.
 * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
 *
 * @retval MFD_SUCCESS all the changes to the row are legal
 * @retval MFD_ERROR   one or more changes are not legal
 *
 * (see README-table-ipAddressTable if you don't have dependencies)
 */
int
ipAddressTable_check_dependencies(ipAddressTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:470:o: Check ipAddressTable row dependencies.
     * check that all new value are legal and consistent with each other
     */
    /*
     * check RowStatus dependencies
     */
    if (rowreq_ctx->column_set_flags & COLUMN_IPADDRESSROWSTATUS_FLAG) {
        /*
         * row creation requirements
         */
        if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED) {
            if (ROWSTATUS_DESTROY == rowreq_ctx->ipAddressRowStatus) {
                rowreq_ctx->rowreq_flags |= MFD_ROW_DELETED;
            } else if (ROWSTATUS_CREATEANDGO ==
                       rowreq_ctx->ipAddressRowStatus) {
                if ((rowreq_ctx->
                     column_set_flags & IPADDRESSTABLE_REQUIRED_COLS)
                    != IPADDRESSTABLE_REQUIRED_COLS) {
                    DEBUGMSGTL(("ipAddressTable",
                                "required columns missing (0x%0x != 0x%0x)\n",
                                rowreq_ctx->column_set_flags,
                                IPADDRESSTABLE_REQUIRED_COLS));
                    return MFD_CANNOT_CREATE_NOW;
                }
                rowreq_ctx->ipAddressRowStatus = ROWSTATUS_ACTIVE;
            }
        } /* row creation */
        else {
            /*
             * row change requirements
             */
            /*
             * don't allow a destroy if any other value was changed, since
             * that might call data access routines with bad info.
             *
             * you may or may not require the row be notInService before it
             * can be destroyed.
             */
            if (ROWSTATUS_DESTROY == rowreq_ctx->ipAddressRowStatus) {
                if (rowreq_ctx->
                    column_set_flags & ~COLUMN_IPADDRESSROWSTATUS_FLAG) {
                    DEBUGMSGTL(("ipAddressTable",
                                "destroy must be only varbind for row\n"));
                    return MFD_NOT_VALID_NOW;
                }
                rowreq_ctx->rowreq_flags |= MFD_ROW_DELETED;

            }                   /* row destroy */
        }                       /* row change */
    } else {
        /*
         * must have row status to create a row
         */
        if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED) {
            DEBUGMSGTL(("ipAddressTable",
                        "must use RowStatus to create rows\n"));
            return MFD_CANNOT_CREATE_NOW;
        }
    }                           /* row status not set */

    return rc;
}                               /* ipAddressTable_check_dependencies */

/** @} */
/** @{ */
