/*
 * 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(u_long * mib_ipAddressAddrType_val_ptr,
                      u_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,
                                   u_long ipAddressAddrType_val,
                                   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,
                           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];
    int             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) = 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 == 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 != ipAddressIfIndex_val)
        rowreq_ctx->data->if_index = 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 */

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