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

netsnmp_feature_require(check_storage_transition)
netsnmp_feature_require(ipaddress_entry_copy)
netsnmp_feature_require(ipaddress_prefix_copy)

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

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