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

const oid       inetNetToMediaTable_oid[] = { INETNETTOMEDIATABLE_OID };
const 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.
     */
    SNMP_FREE(rowreq_ctx->data);
}                               /* 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
     */
    *inetNetToMediaLastUpdated_val_ptr = rowreq_ctx->data->arp_last_updated;
    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 */

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