/*
 * Note: this file originally auto-generated by mib2c using
 *       version : 1.48 $ of : mfd-top.m2c,v $ 
 *
 * $Id$
 */
/** \page MFD helper for inetNetToMediaTable
 *
 * \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 our parent header 
 */
#include "inetNetToMediaTable.h"

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

#include "inetNetToMediaTable_interface.h"

oid             inetNetToMediaTable_oid[] = { INETNETTOMEDIATABLE_OID };
int             inetNetToMediaTable_oid_size =
OID_LENGTH(inetNetToMediaTable_oid);

inetNetToMediaTable_registration inetNetToMediaTable_user_context;
static inetNetToMediaTable_registration *inetNetToMediaTable_user_context_p;

void            initialize_table_inetNetToMediaTable(void);
void            shutdown_table_inetNetToMediaTable(void);


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

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

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

}                               /* init_inetNetToMediaTable */

/**
 * Shut-down the inetNetToMediaTable module (agent is exiting)
 */
void
shutdown_inetNetToMediaTable(void)
{
    if (should_init("inetNetToMediaTable"))
        shutdown_table_inetNetToMediaTable();

}

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

    DEBUGMSGTL(("verbose:inetNetToMediaTable:initialize_table_inetNetToMediaTable", "called\n"));

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

    /*
     * TODO:302:o: |->Initialize inetNetToMediaTable user context
     * if you'd like to pass in a pointer to some data for this
     * table, allocate or set it up here.
     */
    /*
     * a netsnmp_data_list is a simple way to store void pointers. A simple
     * string token is used to add, find or remove pointers.
     */
    inetNetToMediaTable_user_context_p =
        netsnmp_create_data_list("inetNetToMediaTable", NULL, NULL);

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

    /*
     * call interface initialization code
     */
    _inetNetToMediaTable_initialize_interface
	(inetNetToMediaTable_user_context_p, flags);
}                               /* initialize_table_inetNetToMediaTable */

/**
 * Shutdown the table inetNetToMediaTable 
 */
void
shutdown_table_inetNetToMediaTable(void)
{
    /*
     * call interface shutdown code
     */
    _inetNetToMediaTable_shutdown_interface
        (inetNetToMediaTable_user_context_p);
    netsnmp_free_all_list_data(inetNetToMediaTable_user_context_p);
    inetNetToMediaTable_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
inetNetToMediaTable_rowreq_ctx_init(inetNetToMediaTable_rowreq_ctx *
                                    rowreq_ctx, void *user_init_ctx)
{
    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaTable_rowreq_ctx_init", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* inetNetToMediaTable_rowreq_ctx_init */

/**
 * extra context cleanup
 *
 */
void
inetNetToMediaTable_rowreq_ctx_cleanup(inetNetToMediaTable_rowreq_ctx *
                                       rowreq_ctx)
{
    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaTable_rowreq_ctx_cleanup", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:211:o: |-> Perform extra inetNetToMediaTable rowreq cleanup.
     */
}                               /* inetNetToMediaTable_rowreq_ctx_cleanup */

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

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

    return MFD_SUCCESS;
}                               /* inetNetToMediaTable_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
inetNetToMediaTable_post_request(inetNetToMediaTable_registration *
                                 user_context, int rc)
{
    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaTable_post_request", "called\n"));

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

    /*
     * check to set if any rows were changed.
     */
    if (inetNetToMediaTable_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
             */
        }

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

    return MFD_SUCCESS;
}                               /* inetNetToMediaTable_post_request */


/**********************************************************************
 **********************************************************************
 ***
 *** Table inetNetToMediaTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * IP-MIB::inetNetToMediaTable is subid 35 of ip.
 * Its status is Current.
 * OID: .1.3.6.1.2.1.4.35, length: 8
 */

/*
 * ---------------------------------------------------------------------
 * * TODO:200:r: Implement inetNetToMediaTable data context functions.
 */
/*
 * inetNetToMediaTable_allocate_data
 *
 * Purpose: create new inetNetToMediaTable_data.
 */
inetNetToMediaTable_data *
inetNetToMediaTable_allocate_data(void)
{
    /*
     * TODO:201:r: |-> allocate memory for the inetNetToMediaTable data context.
     */
    /** this might not be right for netsnmp_inetmedia_entry */
    inetNetToMediaTable_data *rtn = netsnmp_access_arp_entry_create();

    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaTable_allocate_data", "called\n"));

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

    return rtn;
}                               /* inetNetToMediaTable_allocate_data */

/*
 * inetNetToMediaTable_release_data
 *
 * Purpose: release inetNetToMediaTable data.
 */
void
inetNetToMediaTable_release_data(inetNetToMediaTable_data * data)
{
    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaTable_release_data", "called\n"));

    /*
     * TODO:202:r: |-> release memory for the inetNetToMediaTable data context.
     */
    netsnmp_access_arp_entry_free(data);
}                               /* inetNetToMediaTable_release_data */



/**
 * set mib index(es)
 *
 * @param tbl_idx mib index structure
 * @param inetNetToMediaIfIndex_val
 * @param inetNetToMediaNetAddressType_val
 * @param inetNetToMediaNetAddress_val_ptr
 * @param inetNetToMediaNetAddress_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
inetNetToMediaTable_indexes_set_tbl_idx(inetNetToMediaTable_mib_index *
                                        tbl_idx,
                                        long inetNetToMediaIfIndex_val,
                                        u_long
                                        inetNetToMediaNetAddressType_val,
                                        char
                                        *inetNetToMediaNetAddress_val_ptr,
                                        size_t
                                        inetNetToMediaNetAddress_val_ptr_len)
{
    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaTable_indexes_set_tbl_idx", "called\n"));

    /*
     * inetNetToMediaIfIndex(1)/InterfaceIndex/ASN_INTEGER/long(long)//l/a/w/e/R/d/H 
     */
    /** WARNING: this code might not work for netsnmp_arp_entry */
    tbl_idx->inetNetToMediaIfIndex = inetNetToMediaIfIndex_val;

    /*
     * inetNetToMediaNetAddressType(2)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h 
     */
    /** WARNING: this code might not work for netsnmp_arp_entry */
    tbl_idx->inetNetToMediaNetAddressType =
        inetNetToMediaNetAddressType_val;

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


    return MFD_SUCCESS;
}                               /* inetNetToMediaTable_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
inetNetToMediaTable_indexes_set(inetNetToMediaTable_rowreq_ctx *
                                rowreq_ctx, long inetNetToMediaIfIndex_val,
                                u_long inetNetToMediaNetAddressType_val,
                                char *inetNetToMediaNetAddress_val_ptr,
                                size_t
                                inetNetToMediaNetAddress_val_ptr_len)
{
    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaTable_indexes_set", "called\n"));

    if (MFD_SUCCESS !=
        inetNetToMediaTable_indexes_set_tbl_idx(&rowreq_ctx->tbl_idx,
                                                inetNetToMediaIfIndex_val,
                                                inetNetToMediaNetAddressType_val,
                                                inetNetToMediaNetAddress_val_ptr,
                                                inetNetToMediaNetAddress_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 != inetNetToMediaTable_index_to_oid(&rowreq_ctx->oid_idx,
                                              &rowreq_ctx->tbl_idx)) {
        return MFD_ERROR;
    }

    return MFD_SUCCESS;
}                               /* inetNetToMediaTable_indexes_set */


/*---------------------------------------------------------------------
 * IP-MIB::inetNetToMediaEntry.inetNetToMediaPhysAddress
 * inetNetToMediaPhysAddress is subid 4 of inetNetToMediaEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.35.1.4
 * Description:
The media-dependent `physical' address.


            As the entries in this table are typically not persistent
            when this object is written the entity SHOULD NOT save the
            change to non-volatile storage.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 1      hashint   1
 *   settable   1
 *   hint: 1x:
 *
 * Ranges:  0 - 65535;
 *
 * Its syntax is PhysAddress (based on perltype OCTETSTR)
 * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
 * This data type requires a length.  (Max 65535)
 */
/**
 * Extract the current value of the inetNetToMediaPhysAddress data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetNetToMediaPhysAddress_val_ptr_ptr
 *        Pointer to storage for a char variable
 * @param inetNetToMediaPhysAddress_val_ptr_len_ptr
 *        Pointer to a size_t. On entry, it will contain the size (in bytes)
 *        pointed to by inetNetToMediaPhysAddress.
 *        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 (*inetNetToMediaPhysAddress_val_ptr_len_ptr) bytes of memory,
 *       allocate it using malloc() and update inetNetToMediaPhysAddress_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
inetNetToMediaPhysAddress_get(inetNetToMediaTable_rowreq_ctx * rowreq_ctx,
                              char **inetNetToMediaPhysAddress_val_ptr_ptr,
                              size_t
                              * inetNetToMediaPhysAddress_val_ptr_len_ptr)
{
   /** we should have a non-NULL pointer and enough storage */
    netsnmp_assert((NULL != inetNetToMediaPhysAddress_val_ptr_ptr)
                   && (NULL != *inetNetToMediaPhysAddress_val_ptr_ptr));
    netsnmp_assert(NULL != inetNetToMediaPhysAddress_val_ptr_len_ptr);


    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaPhysAddress_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the inetNetToMediaPhysAddress data.
     * copy (* inetNetToMediaPhysAddress_val_ptr_ptr ) data and (* inetNetToMediaPhysAddress_val_ptr_len_ptr ) from rowreq_ctx->data
     */
    if ((*inetNetToMediaPhysAddress_val_ptr_len_ptr) <
        rowreq_ctx->data->arp_physaddress_len)
        return MFD_SKIP;

    memcpy((*inetNetToMediaPhysAddress_val_ptr_ptr),
           rowreq_ctx->data->arp_physaddress,
           rowreq_ctx->data->arp_physaddress_len);
    (*inetNetToMediaPhysAddress_val_ptr_len_ptr) =
        rowreq_ctx->data->arp_physaddress_len;

    return MFD_SUCCESS;
}                               /* inetNetToMediaPhysAddress_get */

/*---------------------------------------------------------------------
 * IP-MIB::inetNetToMediaEntry.inetNetToMediaLastUpdated
 * inetNetToMediaLastUpdated is subid 5 of inetNetToMediaEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.35.1.5
 * 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 inetNetToMediaLastUpdated data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetNetToMediaLastUpdated_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
inetNetToMediaLastUpdated_get(inetNetToMediaTable_rowreq_ctx * rowreq_ctx,
                              u_long * inetNetToMediaLastUpdated_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != inetNetToMediaLastUpdated_val_ptr);


    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaLastUpdated_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the inetNetToMediaLastUpdated data.
     * copy (* inetNetToMediaLastUpdated_val_ptr ) from rowreq_ctx->data
     */
    /*
     * xxx-rks: get this value?
     */
    return MFD_SKIP;

    return MFD_SUCCESS;
}                               /* inetNetToMediaLastUpdated_get */

/*---------------------------------------------------------------------
 * IP-MIB::inetNetToMediaEntry.inetNetToMediaType
 * inetNetToMediaType is subid 6 of inetNetToMediaEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.35.1.6
 * Description:
The type of mapping.


            Setting this object to the value invalid(2) has the effect
            of invalidating the corresponding entry in the
            inetNetToMediaTable.  That is, it effectively dis-
            associates the interface identified with said entry from the
            mapping identified with said entry.  It is an
            implementation- specific matter as to whether the agent
            removes an invalidated entry from the table.  Accordingly,
            management stations must be prepared to receive tabular
            information from agents that corresponds to entries not
            currently in use.  Proper interpretation of such entries
            requires examination of the relevant inetNetToMediaType
            object.


            The 'dynamic(3)' type indicates that the IP address to
            physical addresses mapping has been dynamically resolved
            using e.g. IPv4 ARP or the IPv6 Neighbor Discovery protocol.


            The 'static(4)' type indicates that the mapping has been
            statically configured.  Both of these refer to entries that
            provide mappings for other entities addresses.


            The 'local(5)' type indicates that the mapping is provided
            for an entity's own interface address.


            As the entries in this table are typically not persistent
            when this object is written the entity SHOULD NOT save the




            change to non-volatile storage.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: static
 *
 * Enum range: 5/8. Values:  other(1), invalid(2), dynamic(3), static(4), local(5)
 *
 * 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 inetNetToMediaType data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetNetToMediaType_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
inetNetToMediaType_get(inetNetToMediaTable_rowreq_ctx * rowreq_ctx,
                       u_long * inetNetToMediaType_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != inetNetToMediaType_val_ptr);


    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaType_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* inetNetToMediaType_get */

/*---------------------------------------------------------------------
 * IP-MIB::inetNetToMediaEntry.inetNetToMediaState
 * inetNetToMediaState is subid 7 of inetNetToMediaEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.35.1.7
 * Description:
The Neighbor Unreachability Detection [4] state for the
            interface when the address mapping in this entry is used.
            If Neighbor Unreachability Detection is not in use (e.g. for
            IPv4), this object is always unknown(6).
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 * Enum range: 6/8. Values:  reachable(1), stale(2), delay(3), probe(4), invalid(5), unknown(6), incomplete(7)
 *
 * 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 inetNetToMediaState data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetNetToMediaState_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
inetNetToMediaState_get(inetNetToMediaTable_rowreq_ctx * rowreq_ctx,
                        u_long * inetNetToMediaState_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != inetNetToMediaState_val_ptr);


    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaState_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* inetNetToMediaState_get */

/*---------------------------------------------------------------------
 * IP-MIB::inetNetToMediaEntry.inetNetToMediaRowStatus
 * inetNetToMediaRowStatus is subid 8 of inetNetToMediaEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.35.1.8
 * 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
            inetNetToMediaPhysAddress object has been set.




            Note that if the inetNetToMediaType is set to 'invalid' the
            managed node may delete the entry independent of the state
            of this object.
 *
 * 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 inetNetToMediaRowStatus data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetNetToMediaRowStatus_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
inetNetToMediaRowStatus_get(inetNetToMediaTable_rowreq_ctx * rowreq_ctx,
                            u_long * inetNetToMediaRowStatus_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != inetNetToMediaRowStatus_val_ptr);

    (*inetNetToMediaRowStatus_val_ptr) =
        rowreq_ctx->inetNetToMediaRowStatus;

    return MFD_SUCCESS;
}                               /* inetNetToMediaRowStatus_get */



/** @} */
/**********************************************************************
 **********************************************************************
 ***
 *** Table inetNetToMediaTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * IP-MIB::inetNetToMediaTable is subid 35 of ip.
 * Its status is Current.
 * OID: .1.3.6.1.2.1.4.35, 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
 * inetNetToMediaTable_allocate_data(), but may need extra
 * initialization similar to what you may have done in
 * inetNetToMediaTable_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 (inetNetToMediaTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 */
int
inetNetToMediaTable_undo_setup(inetNetToMediaTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaTable_undo_setup", "called\n"));

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

    /*
     * TODO:451:M: |-> Setup inetNetToMediaTable undo.
     * set up inetNetToMediaTable undo information, in preparation for a set.
     * Undo storage is in (* inetNetToMediaRowStatus_val_ptr )*
     */

    return rc;
}                               /* inetNetToMediaTable_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 (inetNetToMediaTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 */
int
inetNetToMediaTable_undo(inetNetToMediaTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaTable_undo",
                "called\n"));

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

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

    return rc;
}                               /* inetNetToMediaTable_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 (inetNetToMediaTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error
 */
int
inetNetToMediaTable_undo_cleanup(inetNetToMediaTable_rowreq_ctx *
                                 rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaTable_undo_cleanup", "called\n"));

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

    /*
     * TODO:452:M: |-> Cleanup inetNetToMediaTable undo.
     * Undo storage is in (* inetNetToMediaRowStatus_val_ptr )*
     */

    return rc;
}                               /* inetNetToMediaTable_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
 * inetNetToMediaTable.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
inetNetToMediaTable_commit(inetNetToMediaTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;
    int             save_flags;

    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaTable_commit",
                "called\n"));

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

    /*
     * save flags, then clear until we actually do something
     */
    save_flags = rowreq_ctx->column_set_flags;
    rowreq_ctx->column_set_flags = 0;

    /*
     * commit inetNetToMediaTable data
     * 1) check the column's flag in save_flags 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.
     */
#if 1
    /** xxx-rks:9 nettomedia commit */
#else
    if (save_flags & COLUMN_INETNETTOMEDIAPHYSADDRESS_FLAG) {
        save_flags &= ~COLUMN_INETNETTOMEDIAPHYSADDRESS_FLAG;   /* clear inetNetToMediaPhysAddress */
        /*
         * TODO:482:o: |-> commit column inetNetToMediaPhysAddress.
         */
        rc = -1;
        if (-1 == rc) {
            snmp_log(LOG_ERR,
                     "inetNetToMediaTable column inetNetToMediaPhysAddress commit failed\n");
        } else {
            /*
             * set flag, in case we need to undo inetNetToMediaPhysAddress
             */
            rowreq_ctx->column_set_flags |=
                COLUMN_INETNETTOMEDIAPHYSADDRESS_FLAG;
        }
    }

    if (save_flags & COLUMN_INETNETTOMEDIATYPE_FLAG) {
        save_flags &= ~COLUMN_INETNETTOMEDIATYPE_FLAG;  /* clear inetNetToMediaType */
        /*
         * TODO:482:o: |-> commit column inetNetToMediaType.
         */
        rc = -1;
        if (-1 == rc) {
            snmp_log(LOG_ERR,
                     "inetNetToMediaTable column inetNetToMediaType commit failed\n");
        } else {
            /*
             * set flag, in case we need to undo inetNetToMediaType
             */
            rowreq_ctx->column_set_flags |= COLUMN_INETNETTOMEDIATYPE_FLAG;
        }
    }

    if (save_flags & COLUMN_INETNETTOMEDIAROWSTATUS_FLAG) {
        save_flags &= ~COLUMN_INETNETTOMEDIAROWSTATUS_FLAG;     /* clear inetNetToMediaRowStatus */
        /*
         * TODO:482:o: |-> commit column inetNetToMediaRowStatus.
         */
        rc = -1;
        if (-1 == rc) {
            snmp_log(LOG_ERR,
                     "inetNetToMediaTable column inetNetToMediaRowStatus commit failed\n");
        } else {
            /*
             * set flag, in case we need to undo inetNetToMediaRowStatus
             */
            rowreq_ctx->column_set_flags |=
                COLUMN_INETNETTOMEDIAROWSTATUS_FLAG;
        }
    }

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

    if (save_flags) {
        snmp_log(LOG_ERR, "unhandled columns (0x%x) in commit\n",
                 save_flags);
        return MFD_ERROR;
    }

    return rc;
}                               /* inetNetToMediaTable_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
 * inetNetToMediaTable.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
inetNetToMediaTable_undo_commit(inetNetToMediaTable_rowreq_ctx *
                                rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaTable_undo_commit", "called\n"));

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

    /*
     * TODO:485:M: |-> Undo inetNetToMediaTable 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 we successfully un-commited this row, clear the dirty flag.
     */
    if (MFD_SUCCESS == rc) {
        rowreq_ctx->rowreq_flags &= ~MFD_ROW_DIRTY;
    }

    return rc;
}                               /* inetNetToMediaTable_undo_commit */

/*
 * TODO:440:M: Implement inetNetToMediaTable node value checks.
 * TODO:450:M: Implement inetNetToMediaTable undo functions.
 * TODO:460:M: Implement inetNetToMediaTable set functions.
 * TODO:480:M: Implement inetNetToMediaTable commit functions.
 */
/*---------------------------------------------------------------------
 * IP-MIB::inetNetToMediaEntry.inetNetToMediaPhysAddress
 * inetNetToMediaPhysAddress is subid 4 of inetNetToMediaEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.35.1.4
 * Description:
The media-dependent `physical' address.


            As the entries in this table are typically not persistent
            when this object is written the entity SHOULD NOT save the
            change to non-volatile storage.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 1      hashint   1
 *   settable   1
 *   hint: 1x:
 *
 * Ranges:  0 - 65535;
 *
 * Its syntax is PhysAddress (based on perltype OCTETSTR)
 * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
 * This data type requires a length.  (Max 65535)
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetNetToMediaPhysAddress_val_ptr
 *        A char containing the new value.
 * @param inetNetToMediaPhysAddress_val_ptr_len
 *        The size (in bytes) of the data pointed to by inetNetToMediaPhysAddress_val_ptr
 *
 * @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).
 *
 * Since you aren't using a generated data context, you also need to
 * check the length, to make sure you don't overflow your storage space.
 *
 * 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
 * inetNetToMediaTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_OCTET_STR
 *    The length is in (one of) the range set(s):  0 - 65535
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
inetNetToMediaPhysAddress_check_value(inetNetToMediaTable_rowreq_ctx *
                                      rowreq_ctx, char
                                      *inetNetToMediaPhysAddress_val_ptr,
                                      size_t
                                      inetNetToMediaPhysAddress_val_ptr_len)
{
    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaPhysAddress_check_value", "called\n"));

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

    /*
     * TODO:441:o: |-> Check for valid inetNetToMediaPhysAddress value.
     */

    return MFD_SUCCESS;         /* inetNetToMediaPhysAddress value not illegal */
}                               /* inetNetToMediaPhysAddress_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (inetNetToMediaTable_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
 * inetNetToMediaTable_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
inetNetToMediaPhysAddress_undo_setup(inetNetToMediaTable_rowreq_ctx *
                                     rowreq_ctx)
{
    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaPhysAddress_undo_setup", "called\n"));

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

    /*
     * TODO:455:o: |-> Setup inetNetToMediaPhysAddress undo.
     */
    /*
     * copy inetNetToMediaPhysAddress and inetNetToMediaPhysAddress_len data
     * set rowreq_ctx->undo->inetNetToMediaPhysAddress from rowreq_ctx->data->inetNetToMediaPhysAddress
     */


    return MFD_SUCCESS;
}                               /* inetNetToMediaPhysAddress_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 inetNetToMediaPhysAddress_val_ptr
 *        A char containing the new value.
 * @param inetNetToMediaPhysAddress_val_ptr_len
 *        The size (in bytes) of the data pointed to by inetNetToMediaPhysAddress_val_ptr
 */
int
inetNetToMediaPhysAddress_set(inetNetToMediaTable_rowreq_ctx * rowreq_ctx,
                              char *inetNetToMediaPhysAddress_val_ptr,
                              size_t inetNetToMediaPhysAddress_val_ptr_len)
{

    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaPhysAddress_set", "called\n"));

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

    /*
     * TODO:461:M: |-> Set inetNetToMediaPhysAddress value.
     * set inetNetToMediaPhysAddress value in rowreq_ctx->data
     */

    return MFD_SUCCESS;
}                               /* inetNetToMediaPhysAddress_set */

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

    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaPhysAddress_undo", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up inetNetToMediaPhysAddress undo.
     */
    /*
     * copy inetNetToMediaPhysAddress and inetNetToMediaPhysAddress_len data
     * set rowreq_ctx->data->inetNetToMediaPhysAddress from rowreq_ctx->undo->inetNetToMediaPhysAddress
     */


    return MFD_SUCCESS;
}                               /* inetNetToMediaPhysAddress_undo */

/*---------------------------------------------------------------------
 * IP-MIB::inetNetToMediaEntry.inetNetToMediaType
 * inetNetToMediaType is subid 6 of inetNetToMediaEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.35.1.6
 * Description:
The type of mapping.


            Setting this object to the value invalid(2) has the effect
            of invalidating the corresponding entry in the
            inetNetToMediaTable.  That is, it effectively dis-
            associates the interface identified with said entry from the
            mapping identified with said entry.  It is an
            implementation- specific matter as to whether the agent
            removes an invalidated entry from the table.  Accordingly,
            management stations must be prepared to receive tabular
            information from agents that corresponds to entries not
            currently in use.  Proper interpretation of such entries
            requires examination of the relevant inetNetToMediaType
            object.


            The 'dynamic(3)' type indicates that the IP address to
            physical addresses mapping has been dynamically resolved
            using e.g. IPv4 ARP or the IPv6 Neighbor Discovery protocol.


            The 'static(4)' type indicates that the mapping has been
            statically configured.  Both of these refer to entries that
            provide mappings for other entities addresses.


            The 'local(5)' type indicates that the mapping is provided
            for an entity's own interface address.


            As the entries in this table are typically not persistent
            when this object is written the entity SHOULD NOT save the




            change to non-volatile storage.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: static
 *
 * Enum range: 5/8. Values:  other(1), invalid(2), dynamic(3), static(4), local(5)
 *
 * 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 inetNetToMediaType_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
 * inetNetToMediaTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_INTEGER
 *    The value is one of  other(1), invalid(2), dynamic(3), static(4), local(5)
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
inetNetToMediaType_check_value(inetNetToMediaTable_rowreq_ctx * rowreq_ctx,
                               u_long inetNetToMediaType_val)
{
    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaType_check_value", "called\n"));

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

    /*
     * TODO:441:o: |-> Check for valid inetNetToMediaType value.
     */

    return MFD_SUCCESS;         /* inetNetToMediaType value not illegal */
}                               /* inetNetToMediaType_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (inetNetToMediaTable_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
 * inetNetToMediaTable_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
inetNetToMediaType_undo_setup(inetNetToMediaTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaType_undo_setup", "called\n"));

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

    /*
     * TODO:455:o: |-> Setup inetNetToMediaType undo.
     */
    /*
     * copy inetNetToMediaType data
     * set rowreq_ctx->undo->inetNetToMediaType from rowreq_ctx->data->inetNetToMediaType
     */


    return MFD_SUCCESS;
}                               /* inetNetToMediaType_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 inetNetToMediaType_val
 *        A long containing the new value.
 */
int
inetNetToMediaType_set(inetNetToMediaTable_rowreq_ctx * rowreq_ctx,
                       u_long inetNetToMediaType_val)
{

    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaType_set",
                "called\n"));

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

    /*
     * TODO:461:M: |-> Set inetNetToMediaType value.
     * set inetNetToMediaType value in rowreq_ctx->data
     */

    return MFD_SUCCESS;
}                               /* inetNetToMediaType_set */

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

    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaType_undo",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up inetNetToMediaType undo.
     */
    /*
     * copy inetNetToMediaType data
     * set rowreq_ctx->data->inetNetToMediaType from rowreq_ctx->undo->inetNetToMediaType
     */


    return MFD_SUCCESS;
}                               /* inetNetToMediaType_undo */

/*---------------------------------------------------------------------
 * IP-MIB::inetNetToMediaEntry.inetNetToMediaRowStatus
 * inetNetToMediaRowStatus is subid 8 of inetNetToMediaEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.35.1.8
 * 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
            inetNetToMediaPhysAddress object has been set.




            Note that if the inetNetToMediaType is set to 'invalid' the
            managed node may delete the entry independent of the state
            of this object.
 *
 * 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 inetNetToMediaRowStatus_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
 * inetNetToMediaTable_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
inetNetToMediaRowStatus_check_value(inetNetToMediaTable_rowreq_ctx *
                                    rowreq_ctx,
                                    u_long inetNetToMediaRowStatus_val)
{
    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaRowStatus_check_value", "called\n"));

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

    /*
     * TODO:441:o: |-> Check for valid inetNetToMediaRowStatus value.
     */

    return MFD_SUCCESS;         /* inetNetToMediaRowStatus value not illegal */
}                               /* inetNetToMediaRowStatus_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (inetNetToMediaTable_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
 * inetNetToMediaTable_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
inetNetToMediaRowStatus_undo_setup(inetNetToMediaTable_rowreq_ctx *
                                   rowreq_ctx)
{
    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaRowStatus_undo_setup", "called\n"));

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

    /*
     * TODO:455:o: |-> Setup inetNetToMediaRowStatus undo.
     */
    /*
     * copy inetNetToMediaRowStatus data
     * set rowreq_ctx->undo->inetNetToMediaRowStatus from rowreq_ctx->data->inetNetToMediaRowStatus
     */
    rowreq_ctx->inetNetToMediaRowStatus_undo =
        rowreq_ctx->inetNetToMediaRowStatus;

    return MFD_SUCCESS;
}                               /* inetNetToMediaRowStatus_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 inetNetToMediaRowStatus_val
 *        A long containing the new value.
 */
int
inetNetToMediaRowStatus_set(inetNetToMediaTable_rowreq_ctx * rowreq_ctx,
                            u_long inetNetToMediaRowStatus_val)
{

    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaRowStatus_set",
                "called\n"));

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

    /*
     * TODO:461:M: |-> Set inetNetToMediaRowStatus value.
     * set inetNetToMediaRowStatus value in rowreq_ctx->data
     */

    return MFD_SUCCESS;
}                               /* inetNetToMediaRowStatus_set */

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

    DEBUGMSGTL(("verbose:inetNetToMediaTable:inetNetToMediaRowStatus_undo",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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


    return MFD_SUCCESS;
}                               /* inetNetToMediaRowStatus_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
 * inetNetToMediaTable.h.
 * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
 *
 * @param rowreq_ctx
 *
 * @retval MFD_SUCCESS all the changes to the row are legal
 * @retval MFD_ERROR   one or more changes are not legal
 *
 * (see README-table-inetNetToMediaTable if you don't have dependencies)
 */
int
inetNetToMediaTable_check_dependencies(inetNetToMediaTable_rowreq_ctx *
                                       rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("internal:inetNetToMediaTable:inetNetToMediaTable_check_dependencies", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:470:o: Check inetNetToMediaTable row dependencies.
     * check that all new value are legal and consistent with each other
     */
    /*
     * check RowStatus dependencies
     */
    if (rowreq_ctx->column_set_flags & COLUMN_INETNETTOMEDIAROWSTATUS_FLAG) {
        /*
         * check for valid RowStatus transition (old, new)
         * (Note: move transition check to 
         *  to catch errors earlier)
         */
        rc = check_rowstatus_transition(rowreq_ctx->
                                        inetNetToMediaRowStatus_undo,
                                        rowreq_ctx->
                                        inetNetToMediaRowStatus);
        if (MFD_SUCCESS != rc)
            return rc;

        /*
         * row creation requirements
         */
        if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED) {
            if (ROWSTATUS_DESTROY == rowreq_ctx->inetNetToMediaRowStatus) {
                rowreq_ctx->rowreq_flags |= MFD_ROW_DELETED;
            } else if (ROWSTATUS_CREATEANDGO ==
                       rowreq_ctx->inetNetToMediaRowStatus) {
                if ((rowreq_ctx->
                     column_set_flags & INETNETTOMEDIATABLE_REQUIRED_COLS)
                    != INETNETTOMEDIATABLE_REQUIRED_COLS) {
                    DEBUGMSGTL(("inetNetToMediaTable",
                                "required columns missing (0x%0x != 0x%0x)\n",
                                rowreq_ctx->column_set_flags,
                                INETNETTOMEDIATABLE_REQUIRED_COLS));
                    return MFD_CANNOT_CREATE_NOW;
                }
                rowreq_ctx->inetNetToMediaRowStatus = 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->inetNetToMediaRowStatus) {
                if (rowreq_ctx->
                    column_set_flags &
                    ~COLUMN_INETNETTOMEDIAROWSTATUS_FLAG) {
                    DEBUGMSGTL(("inetNetToMediaTable",
                                "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(("inetNetToMediaTable",
                        "must use RowStatus to create rows\n"));
            return MFD_CANNOT_CREATE_NOW;
        }
    }                           /* row status not set */

    if (MFD_SUCCESS != rc)
        return rc;

    return rc;
}                               /* inetNetToMediaTable_check_dependencies */

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