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

/*
 * include our parent header 
 */
#include "ifXTable.h"
#include "if-mib/ifTable/ifTable_defs.h"

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

#include "ifXTable_interface.h"

/*
 * not sure if we want to support set for promiscuous mode, because
 * 1) careful thought should go into any settable object that performs
 *    an action that requires root access
 * 2) i don't want to write the code right now
 * 
 */
#undef NETSNMP_ENABLE_PROMISCUOUSMODE_SET

const oid       ifXTable_oid[] = { IFXTABLE_OID };
const int       ifXTable_oid_size = OID_LENGTH(ifXTable_oid);

ifXTable_registration ifXTable_user_context;
static ifXTable_registration *ifXTable_user_context_p;

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

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

    /*
     * here we initialize all the tables we're planning on supporting
     */
    init_ifTable();

}                               /* init_ifXTable */

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

    DEBUGMSGTL(("verbose:ifXTable:initialize_table_ifXTable", "called\n"));

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

    /*
     * TODO:302:o: |->Initialize ifXTable 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.
     */
    ifXTable_user_context_p = netsnmp_create_data_list("ifXTable", NULL, NULL);

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

    /*
     * call interface initialization code
     */
    _ifXTable_initialize_interface(ifXTable_user_context_p, flags);

    /*
     * if there is no container, bail. otherwise, register the callbacks
     * for persistent storage.
     */
    if (NULL == ifTable_container_get())
        return;                 /* msg already logged */

}                               /* initialize_table_ifXTable */

void
shutdown_ifXTable(void)
{
    netsnmp_free_all_list_data(ifXTable_user_context_p);
    ifXTable_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
ifXTable_rowreq_ctx_init(ifXTable_rowreq_ctx * rowreq_ctx,
                         void *user_init_ctx)
{
    DEBUGMSGTL(("verbose:ifXTable:ifXTable_rowreq_ctx_init", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:210:o: |-> Perform extra ifXTable rowreq initialization. (eg DEFVALS)
     * should never get here - ifTable should handle this
     */
    netsnmp_assert(0);

    return MFD_ERROR;
}                               /* ifXTable_rowreq_ctx_init */

/**
 * extra context cleanup
 *
 */
void
ifXTable_rowreq_ctx_cleanup(ifXTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ifXTable:ifXTable_rowreq_ctx_cleanup",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:211:o: |-> Perform extra ifXTable rowreq cleanup.
     */
    /*
     * should never get here - ifTable should handle this
     */
    netsnmp_assert(0);
}                               /* ifXTable_rowreq_ctx_cleanup */

/**
 * the *_should_save routine is called to determine if a row
 * should be stored persistently.
 *
 * Note that this is not a 'dirty' check (i.e. if a row has changed),
 * but a check for volatile rows that should not be saved between
 * restarts.
 *
 * @param rowreq_ctx
 * 
 * @return 1 if the row should be stored
 * @return 0 if the row should not be stored
 */
int
ifXTable_container_should_save(ifXTable_rowreq_ctx * rowreq_ctx)
{

    return 1;                   /* save the row */
}

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

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

    return MFD_SUCCESS;
}                               /* ifXTable_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
ifXTable_post_request(ifXTable_registration * user_context, int rc)
{
    DEBUGMSGTL(("verbose:ifXTable:ifXTable_post_request", "called\n"));

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

    /*
     * check to set if any rows were changed.
     */
    if (ifXTable_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
             */
            snmp_store(netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
                                             NETSNMP_DS_LIB_APPTYPE));
        }

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

    return MFD_SUCCESS;
}                               /* ifXTable_post_request */


/**********************************************************************
 **********************************************************************
 ***
 *** Table ifXTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * IF-MIB::ifXTable is subid 1 of ifMIBObjects.
 * Its status is Current.
 * OID: .1.3.6.1.2.1.31.1.1, length: 9
 */

/*
 * ---------------------------------------------------------------------
 * * TODO:200:r: Implement ifXTable data context functions.
 */


/**
 * set mib index(es)
 *
 * @param tbl_idx mib index structure
 * @param ifIndex_val
 *
 * @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
ifXTable_indexes_set_tbl_idx(ifXTable_mib_index * tbl_idx,
                             long ifIndex_val)
{
    DEBUGMSGTL(("verbose:ifXTable:ifXTable_indexes_set_tbl_idx",
                "called\n"));

    /*
     * ifIndex(1)/InterfaceIndex/ASN_INTEGER/long(long)//l/A/w/e/R/d/H 
     */
    tbl_idx->ifIndex = ifIndex_val;


    return MFD_SUCCESS;
}                               /* ifXTable_indexes_set_tbl_idx */

/**
 * @internal
 * set row context indexes
 *
 * @param reqreq_ctx the row context that needs updated indexes
 * @param ifIndex_val
 *
 * @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
ifXTable_indexes_set(ifXTable_rowreq_ctx * rowreq_ctx, long ifIndex_val)
{
    DEBUGMSGTL(("verbose:ifXTable:ifXTable_indexes_set", "called\n"));

    if (MFD_SUCCESS !=
        ifXTable_indexes_set_tbl_idx(&rowreq_ctx->tbl_idx, ifIndex_val))
        return MFD_ERROR;

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

    return MFD_SUCCESS;
}                               /* ifXTable_indexes_set */


/*---------------------------------------------------------------------
 * IF-MIB::ifXEntry.ifName
 * ifName is subid 1 of ifXEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.31.1.1.1.1
 * Description:
The textual name of the interface.  The value of this
            object should be the name of the interface as assigned by
            the local device and should be suitable for use in commands
            entered at the device's `console'.  This might be a text
            name, such as `le0' or a simple port number, such as `1',
            depending on the interface naming syntax of the device.  If
            several entries in the ifTable together represent a single
            interface as named by the device, then each will have the
            same value of ifName.  Note that for an agent which responds
            to SNMP queries concerning an interface on some other
            (proxied) device, then the value of ifName for such an
            interface is the proxied device's local name for it.

            If there is no local name, or this object is otherwise not
            applicable, then this object contains a zero-length string.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 1      hashint   1
 *   settable   0
 *   hint: 255a
 *
 * Ranges:  0 - 255;
 *
 * Its syntax is DisplayString (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 255)
 */
/**
 * Extract the current value of the ifName data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifName_val_ptr_ptr
 *        Pointer to storage for a char variable
 * @param ifName_val_ptr_len_ptr
 *        Pointer to a size_t. On entry, it will contain the size (in bytes)
 *        pointed to by ifName.
 *        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 (*ifName_val_ptr_len_ptr) bytes of memory,
 *       allocate it using malloc() and update ifName_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
ifName_get(ifXTable_rowreq_ctx * rowreq_ctx, char **ifName_val_ptr_ptr,
           size_t * ifName_val_ptr_len_ptr)
{
    int             tmp_len;

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


    DEBUGMSGTL(("verbose:ifXTable:ifName_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ifName data.
     * copy (* ifName_val_ptr_ptr ) data and (* ifName_val_ptr_len_ptr ) from rowreq_ctx->data
     */
    /*
     * make sure there is enough space for ifName data
     */
    tmp_len = strlen(rowreq_ctx->data.ifName);
    if ((NULL == (*ifName_val_ptr_ptr)) ||
        ((*ifName_val_ptr_len_ptr) < tmp_len)) {
        /*
         * allocate space for ifName data
         */
        (*ifName_val_ptr_ptr) = malloc(tmp_len);
        if (NULL == (*ifName_val_ptr_ptr)) {
            snmp_log(LOG_ERR, "could not allocate memory\n");
            return MFD_ERROR;
        }
    }
    (*ifName_val_ptr_len_ptr) = tmp_len;
    memcpy((*ifName_val_ptr_ptr), rowreq_ctx->data.ifName, tmp_len);

    return MFD_SUCCESS;
}                               /* ifName_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifXEntry.ifInMulticastPkts
 * ifInMulticastPkts is subid 2 of ifXEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.31.1.1.1.2
 * Description:
The number of packets, delivered by this sub-layer to a
            higher (sub-)layer, which were addressed to a multicast
            address at this sub-layer.  For a MAC layer protocol, this
            includes both Group and Functional addresses.

            Discontinuities in the value of this counter can occur at
            re-initialization of the management system, and at other

            times as indicated by the value of
            ifCounterDiscontinuityTime.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER (based on perltype COUNTER)
 * The net-snmp type is ASN_COUNTER. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the ifInMulticastPkts data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifInMulticastPkts_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
ifInMulticastPkts_get(ifXTable_rowreq_ctx * rowreq_ctx,
                      u_long * ifInMulticastPkts_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifInMulticastPkts_val_ptr);


    DEBUGMSGTL(("verbose:ifXTable:ifInMulticastPkts_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* ifInMulticastPkts_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifXEntry.ifInBroadcastPkts
 * ifInBroadcastPkts is subid 3 of ifXEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.31.1.1.1.3
 * Description:
The number of packets, delivered by this sub-layer to a
            higher (sub-)layer, which were addressed to a broadcast
            address at this sub-layer.

            Discontinuities in the value of this counter can occur at
            re-initialization of the management system, and at other
            times as indicated by the value of
            ifCounterDiscontinuityTime.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER (based on perltype COUNTER)
 * The net-snmp type is ASN_COUNTER. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the ifInBroadcastPkts data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifInBroadcastPkts_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
ifInBroadcastPkts_get(ifXTable_rowreq_ctx * rowreq_ctx,
                      u_long * ifInBroadcastPkts_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifInBroadcastPkts_val_ptr);


    DEBUGMSGTL(("verbose:ifXTable:ifInBroadcastPkts_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* ifInBroadcastPkts_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifXEntry.ifOutMulticastPkts
 * ifOutMulticastPkts is subid 4 of ifXEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.31.1.1.1.4
 * Description:
The total number of packets that higher-level protocols
            requested be transmitted, and which were addressed to a
            multicast address at this sub-layer, including those that
            were discarded or not sent.  For a MAC layer protocol, this
            includes both Group and Functional addresses.

            Discontinuities in the value of this counter can occur at
            re-initialization of the management system, and at other
            times as indicated by the value of
            ifCounterDiscontinuityTime.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER (based on perltype COUNTER)
 * The net-snmp type is ASN_COUNTER. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the ifOutMulticastPkts data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifOutMulticastPkts_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
ifOutMulticastPkts_get(ifXTable_rowreq_ctx * rowreq_ctx,
                       u_long * ifOutMulticastPkts_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifOutMulticastPkts_val_ptr);


    DEBUGMSGTL(("verbose:ifXTable:ifOutMulticastPkts_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* ifOutMulticastPkts_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifXEntry.ifOutBroadcastPkts
 * ifOutBroadcastPkts is subid 5 of ifXEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.31.1.1.1.5
 * Description:
The total number of packets that higher-level protocols
            requested be transmitted, and which were addressed to a
            broadcast address at this sub-layer, including those that
            were discarded or not sent.

            Discontinuities in the value of this counter can occur at
            re-initialization of the management system, and at other

            times as indicated by the value of
            ifCounterDiscontinuityTime.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER (based on perltype COUNTER)
 * The net-snmp type is ASN_COUNTER. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the ifOutBroadcastPkts data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifOutBroadcastPkts_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
ifOutBroadcastPkts_get(ifXTable_rowreq_ctx * rowreq_ctx,
                       u_long * ifOutBroadcastPkts_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifOutBroadcastPkts_val_ptr);


    DEBUGMSGTL(("verbose:ifXTable:ifOutBroadcastPkts_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* ifOutBroadcastPkts_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifXEntry.ifHCInOctets
 * ifHCInOctets is subid 6 of ifXEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.31.1.1.1.6
 * Description:
The total number of octets received on the interface,
            including framing characters.  This object is a 64-bit
            version of ifInOctets.

            Discontinuities in the value of this counter can occur at
            re-initialization of the management system, and at other
            times as indicated by the value of
            ifCounterDiscontinuityTime.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER64 (based on perltype COUNTER64)
 * The net-snmp type is ASN_COUNTER64. The C type decl is U64 (U64)
 */
/**
 * Extract the current value of the ifHCInOctets data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifHCInOctets_val_ptr
 *        Pointer to storage for a U64 variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ifHCInOctets_get(ifXTable_rowreq_ctx * rowreq_ctx,
                 U64 * ifHCInOctets_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifHCInOctets_val_ptr);

    /*
     * TODO:231:o: |-> copy ifHCInOctets data.
     * get (* ifHCInOctets_val_ptr ).low and (* ifHCInOctets_val_ptr ).high from rowreq_ctx->data
     */
    (*ifHCInOctets_val_ptr).high = rowreq_ctx->data.ifHCInOctets.high;
    (*ifHCInOctets_val_ptr).low = rowreq_ctx->data.ifHCInOctets.low;


    return MFD_SUCCESS;
}                               /* ifHCInOctets_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifXEntry.ifHCInUcastPkts
 * ifHCInUcastPkts is subid 7 of ifXEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.31.1.1.1.7
 * Description:
The number of packets, delivered by this sub-layer to a
            higher (sub-)layer, which were not addressed to a multicast
            or broadcast address at this sub-layer.  This object is a
            64-bit version of ifInUcastPkts.

            Discontinuities in the value of this counter can occur at
            re-initialization of the management system, and at other
            times as indicated by the value of
            ifCounterDiscontinuityTime.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER64 (based on perltype COUNTER64)
 * The net-snmp type is ASN_COUNTER64. The C type decl is U64 (U64)
 */
/**
 * Extract the current value of the ifHCInUcastPkts data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifHCInUcastPkts_val_ptr
 *        Pointer to storage for a U64 variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ifHCInUcastPkts_get(ifXTable_rowreq_ctx * rowreq_ctx,
                    U64 * ifHCInUcastPkts_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifHCInUcastPkts_val_ptr);

    /*
     * TODO:231:o: |-> copy ifHCInUcastPkts data.
     * get (* ifHCInUcastPkts_val_ptr ).low and (* ifHCInUcastPkts_val_ptr ).high from rowreq_ctx->data
     */
    (*ifHCInUcastPkts_val_ptr).high =
        rowreq_ctx->data.ifHCInUcastPkts.high;
    (*ifHCInUcastPkts_val_ptr).low = rowreq_ctx->data.ifHCInUcastPkts.low;


    return MFD_SUCCESS;
}                               /* ifHCInUcastPkts_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifXEntry.ifHCInMulticastPkts
 * ifHCInMulticastPkts is subid 8 of ifXEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.31.1.1.1.8
 * Description:
The number of packets, delivered by this sub-layer to a
            higher (sub-)layer, which were addressed to a multicast
            address at this sub-layer.  For a MAC layer protocol, this
            includes both Group and Functional addresses.  This object
            is a 64-bit version of ifInMulticastPkts.

            Discontinuities in the value of this counter can occur at
            re-initialization of the management system, and at other
            times as indicated by the value of
            ifCounterDiscontinuityTime.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER64 (based on perltype COUNTER64)
 * The net-snmp type is ASN_COUNTER64. The C type decl is U64 (U64)
 */
/**
 * Extract the current value of the ifHCInMulticastPkts data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifHCInMulticastPkts_val_ptr
 *        Pointer to storage for a U64 variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ifHCInMulticastPkts_get(ifXTable_rowreq_ctx * rowreq_ctx,
                        U64 * ifHCInMulticastPkts_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifHCInMulticastPkts_val_ptr);

    /*
     * TODO:231:o: |-> copy ifHCInMulticastPkts data.
     * get (* ifHCInMulticastPkts_val_ptr ).low and (* ifHCInMulticastPkts_val_ptr ).high from rowreq_ctx->data
     */
    (*ifHCInMulticastPkts_val_ptr).high =
        rowreq_ctx->data.ifHCInMulticastPkts.high;
    (*ifHCInMulticastPkts_val_ptr).low =
        rowreq_ctx->data.ifHCInMulticastPkts.low;


    return MFD_SUCCESS;
}                               /* ifHCInMulticastPkts_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifXEntry.ifHCInBroadcastPkts
 * ifHCInBroadcastPkts is subid 9 of ifXEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.31.1.1.1.9
 * Description:
The number of packets, delivered by this sub-layer to a
            higher (sub-)layer, which were addressed to a broadcast
            address at this sub-layer.  This object is a 64-bit version
            of ifInBroadcastPkts.

            Discontinuities in the value of this counter can occur at
            re-initialization of the management system, and at other
            times as indicated by the value of
            ifCounterDiscontinuityTime.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER64 (based on perltype COUNTER64)
 * The net-snmp type is ASN_COUNTER64. The C type decl is U64 (U64)
 */
/**
 * Extract the current value of the ifHCInBroadcastPkts data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifHCInBroadcastPkts_val_ptr
 *        Pointer to storage for a U64 variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ifHCInBroadcastPkts_get(ifXTable_rowreq_ctx * rowreq_ctx,
                        U64 * ifHCInBroadcastPkts_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifHCInBroadcastPkts_val_ptr);

    /*
     * TODO:231:o: |-> copy ifHCInBroadcastPkts data.
     * get (* ifHCInBroadcastPkts_val_ptr ).low and (* ifHCInBroadcastPkts_val_ptr ).high from rowreq_ctx->data
     */
    (*ifHCInBroadcastPkts_val_ptr).high =
        rowreq_ctx->data.ifHCInBroadcastPkts.high;
    (*ifHCInBroadcastPkts_val_ptr).low =
        rowreq_ctx->data.ifHCInBroadcastPkts.low;


    return MFD_SUCCESS;
}                               /* ifHCInBroadcastPkts_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifXEntry.ifHCOutOctets
 * ifHCOutOctets is subid 10 of ifXEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.31.1.1.1.10
 * Description:
The total number of octets transmitted out of the
            interface, including framing characters.  This object is a
            64-bit version of ifOutOctets.

            Discontinuities in the value of this counter can occur at
            re-initialization of the management system, and at other
            times as indicated by the value of
            ifCounterDiscontinuityTime.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER64 (based on perltype COUNTER64)
 * The net-snmp type is ASN_COUNTER64. The C type decl is U64 (U64)
 */
/**
 * Extract the current value of the ifHCOutOctets data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifHCOutOctets_val_ptr
 *        Pointer to storage for a U64 variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ifHCOutOctets_get(ifXTable_rowreq_ctx * rowreq_ctx,
                  U64 * ifHCOutOctets_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifHCOutOctets_val_ptr);

    /*
     * TODO:231:o: |-> copy ifHCOutOctets data.
     * get (* ifHCOutOctets_val_ptr ).low and (* ifHCOutOctets_val_ptr ).high from rowreq_ctx->data
     */
    (*ifHCOutOctets_val_ptr).high = rowreq_ctx->data.ifHCOutOctets.high;
    (*ifHCOutOctets_val_ptr).low = rowreq_ctx->data.ifHCOutOctets.low;


    return MFD_SUCCESS;
}                               /* ifHCOutOctets_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifXEntry.ifHCOutUcastPkts
 * ifHCOutUcastPkts is subid 11 of ifXEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.31.1.1.1.11
 * Description:
The total number of packets that higher-level protocols
            requested be transmitted, and which were not addressed to a
            multicast or broadcast address at this sub-layer, including
            those that were discarded or not sent.  This object is a
            64-bit version of ifOutUcastPkts.

            Discontinuities in the value of this counter can occur at
            re-initialization of the management system, and at other
            times as indicated by the value of
            ifCounterDiscontinuityTime.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER64 (based on perltype COUNTER64)
 * The net-snmp type is ASN_COUNTER64. The C type decl is U64 (U64)
 */
/**
 * Extract the current value of the ifHCOutUcastPkts data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifHCOutUcastPkts_val_ptr
 *        Pointer to storage for a U64 variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ifHCOutUcastPkts_get(ifXTable_rowreq_ctx * rowreq_ctx,
                     U64 * ifHCOutUcastPkts_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifHCOutUcastPkts_val_ptr);

    /*
     * TODO:231:o: |-> copy ifHCOutUcastPkts data.
     * get (* ifHCOutUcastPkts_val_ptr ).low and (* ifHCOutUcastPkts_val_ptr ).high from rowreq_ctx->data
     */
    (*ifHCOutUcastPkts_val_ptr).high =
        rowreq_ctx->data.ifHCOutUcastPkts.high;
    (*ifHCOutUcastPkts_val_ptr).low =
        rowreq_ctx->data.ifHCOutUcastPkts.low;


    return MFD_SUCCESS;
}                               /* ifHCOutUcastPkts_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifXEntry.ifHCOutMulticastPkts
 * ifHCOutMulticastPkts is subid 12 of ifXEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.31.1.1.1.12
 * Description:
The total number of packets that higher-level protocols
            requested be transmitted, and which were addressed to a
            multicast address at this sub-layer, including those that
            were discarded or not sent.  For a MAC layer protocol, this
            includes both Group and Functional addresses.  This object
            is a 64-bit version of ifOutMulticastPkts.

            Discontinuities in the value of this counter can occur at
            re-initialization of the management system, and at other
            times as indicated by the value of
            ifCounterDiscontinuityTime.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER64 (based on perltype COUNTER64)
 * The net-snmp type is ASN_COUNTER64. The C type decl is U64 (U64)
 */
/**
 * Extract the current value of the ifHCOutMulticastPkts data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifHCOutMulticastPkts_val_ptr
 *        Pointer to storage for a U64 variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ifHCOutMulticastPkts_get(ifXTable_rowreq_ctx * rowreq_ctx,
                         U64 * ifHCOutMulticastPkts_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifHCOutMulticastPkts_val_ptr);

    /*
     * TODO:231:o: |-> copy ifHCOutMulticastPkts data.
     * get (* ifHCOutMulticastPkts_val_ptr ).low and (* ifHCOutMulticastPkts_val_ptr ).high from rowreq_ctx->data
     */
    (*ifHCOutMulticastPkts_val_ptr).high =
        rowreq_ctx->data.ifHCOutMulticastPkts.high;
    (*ifHCOutMulticastPkts_val_ptr).low =
        rowreq_ctx->data.ifHCOutMulticastPkts.low;


    return MFD_SUCCESS;
}                               /* ifHCOutMulticastPkts_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifXEntry.ifHCOutBroadcastPkts
 * ifHCOutBroadcastPkts is subid 13 of ifXEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.31.1.1.1.13
 * Description:
The total number of packets that higher-level protocols
            requested be transmitted, and which were addressed to a
            broadcast address at this sub-layer, including those that
            were discarded or not sent.  This object is a 64-bit version
            of ifOutBroadcastPkts.

            Discontinuities in the value of this counter can occur at
            re-initialization of the management system, and at other
            times as indicated by the value of
            ifCounterDiscontinuityTime.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is COUNTER64 (based on perltype COUNTER64)
 * The net-snmp type is ASN_COUNTER64. The C type decl is U64 (U64)
 */
/**
 * Extract the current value of the ifHCOutBroadcastPkts data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifHCOutBroadcastPkts_val_ptr
 *        Pointer to storage for a U64 variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ifHCOutBroadcastPkts_get(ifXTable_rowreq_ctx * rowreq_ctx,
                         U64 * ifHCOutBroadcastPkts_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifHCOutBroadcastPkts_val_ptr);

    /*
     * TODO:231:o: |-> copy ifHCOutBroadcastPkts data.
     * get (* ifHCOutBroadcastPkts_val_ptr ).low and (* ifHCOutBroadcastPkts_val_ptr ).high from rowreq_ctx->data
     */
    (*ifHCOutBroadcastPkts_val_ptr).high =
        rowreq_ctx->data.ifHCOutBroadcastPkts.high;
    (*ifHCOutBroadcastPkts_val_ptr).low =
        rowreq_ctx->data.ifHCOutBroadcastPkts.low;


    return MFD_SUCCESS;
}                               /* ifHCOutBroadcastPkts_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifXEntry.ifLinkUpDownTrapEnable
 * ifLinkUpDownTrapEnable is subid 14 of ifXEntry.
 * Its status is Current, and its access level is ReadWrite.
 * OID: .1.3.6.1.2.1.31.1.1.1.14
 * Description:
Indicates whether linkUp/linkDown traps should be generated
            for this interface.

            By default, this object should have the value enabled(1) for
            interfaces which do not operate on 'top' of any other
            interface (as defined in the ifStackTable), and disabled(2)
            otherwise.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 * Enum range: 2/8. Values:  enabled(1), disabled(2)
 *
 * 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 ifLinkUpDownTrapEnable data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifLinkUpDownTrapEnable_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
ifLinkUpDownTrapEnable_get(ifXTable_rowreq_ctx * rowreq_ctx,
                           u_long * ifLinkUpDownTrapEnable_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifLinkUpDownTrapEnable_val_ptr);


    DEBUGMSGTL(("verbose:ifXTable:ifLinkUpDownTrapEnable_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    if (0 == rowreq_ctx->data.ifLinkUpDownTrapEnable)
        return MFD_SKIP;

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

    return MFD_SUCCESS;
}                               /* ifLinkUpDownTrapEnable_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifXEntry.ifHighSpeed
 * ifHighSpeed is subid 15 of ifXEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.31.1.1.1.15
 * Description:
An estimate of the interface's current bandwidth in units
            of 1,000,000 bits per second.  If this object reports a
            value of `n' then the speed of the interface is somewhere in
            the range of `n-500,000' to `n+499,999'.  For interfaces
            which do not vary in bandwidth or for those where no
            accurate estimation can be made, this object should contain
            the nominal bandwidth.  For a sub-layer which has no concept
            of bandwidth, this object should be zero.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is GAUGE (based on perltype GAUGE)
 * The net-snmp type is ASN_GAUGE. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the ifHighSpeed data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifHighSpeed_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
ifHighSpeed_get(ifXTable_rowreq_ctx * rowreq_ctx,
                u_long * ifHighSpeed_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifHighSpeed_val_ptr);


    DEBUGMSGTL(("verbose:ifXTable:ifHighSpeed_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ifHighSpeed data.
     * copy (* ifHighSpeed_val_ptr ) from rowreq_ctx->data
     */
    if (0 == rowreq_ctx->data.ifHighSpeed)
        (*ifHighSpeed_val_ptr) = rowreq_ctx->data.ifSpeed / 1000000;
    else
        (*ifHighSpeed_val_ptr) = rowreq_ctx->data.ifHighSpeed;

    return MFD_SUCCESS;
}                               /* ifHighSpeed_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifXEntry.ifPromiscuousMode
 * ifPromiscuousMode is subid 16 of ifXEntry.
 * Its status is Current, and its access level is ReadWrite.
 * OID: .1.3.6.1.2.1.31.1.1.1.16
 * Description:
This object has a value of false(2) if this interface only
            accepts packets/frames that are addressed to this station.
            This object has a value of true(1) when the station accepts
            all packets/frames transmitted on the media.  The value
            true(1) is only legal on certain types of media.  If legal,
            setting this object to a value of true(1) may require the
            interface to be reset before becoming effective.

            The value of ifPromiscuousMode does not affect the reception
            of broadcast and multicast packets/frames by the interface.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 * Enum range: 2/8. Values:  true(1), false(2)
 *
 * Its syntax is TruthValue (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 ifPromiscuousMode data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifPromiscuousMode_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
ifPromiscuousMode_get(ifXTable_rowreq_ctx * rowreq_ctx,
                      u_long * ifPromiscuousMode_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifPromiscuousMode_val_ptr);


    DEBUGMSGTL(("verbose:ifXTable:ifPromiscuousMode_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ifPromiscuousMode data.
     * copy (* ifPromiscuousMode_val_ptr ) from rowreq_ctx->data
     */
    /** this is coming from the interface entry, which is a boolean */
    if (rowreq_ctx->data.ifPromiscuousMode)
        (*ifPromiscuousMode_val_ptr) = 1;
    else
        (*ifPromiscuousMode_val_ptr) = 2;

    return MFD_SUCCESS;
}                               /* ifPromiscuousMode_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifXEntry.ifConnectorPresent
 * ifConnectorPresent is subid 17 of ifXEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.31.1.1.1.17
 * Description:
This object has the value 'true(1)' if the interface
            sublayer has a physical connector and the value 'false(2)'
            otherwise.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 * Enum range: 2/8. Values:  true(1), false(2)
 *
 * Its syntax is TruthValue (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 ifConnectorPresent data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifConnectorPresent_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
ifConnectorPresent_get(ifXTable_rowreq_ctx * rowreq_ctx,
                       u_long * ifConnectorPresent_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifConnectorPresent_val_ptr);


    DEBUGMSGTL(("verbose:ifXTable:ifConnectorPresent_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    (*ifConnectorPresent_val_ptr) = rowreq_ctx->data.ifConnectorPresent ?
        TV_TRUE : TV_FALSE;

    return MFD_SUCCESS;
}                               /* ifConnectorPresent_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifXEntry.ifAlias
 * ifAlias is subid 18 of ifXEntry.
 * Its status is Current, and its access level is ReadWrite.
 * OID: .1.3.6.1.2.1.31.1.1.1.18
 * Description:
This object is an 'alias' name for the interface as
            specified by a network manager, and provides a non-volatile
            'handle' for the interface.

            On the first instantiation of an interface, the value of
            ifAlias associated with that interface is the zero-length
            string.  As and when a value is written into an instance of
            ifAlias through a network management set operation, then the
            agent must retain the supplied value in the ifAlias instance
            associated with the same interface for as long as that
            interface remains instantiated, including across all re-
            initializations/reboots of the network management system,
            including those which result in a change of the interface's
            ifIndex value.

            An example of the value which a network manager might store
            in this object for a WAN interface is the (Telco's) circuit
            number/identifier of the interface.

            Some agents may support write-access only for interfaces
            having particular values of ifType.  An agent which supports
            write access to this object is required to keep the value in
            non-volatile storage, but it may limit the length of new
            values depending on how much storage is already occupied by
            the current values for other interfaces.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 1      hashint   1
 *   settable   1
 *   hint: 255a
 *
 * Ranges:  0 - 64;
 *
 * Its syntax is DisplayString (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 64)
 */
/**
 * Extract the current value of the ifAlias data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifAlias_val_ptr_ptr
 *        Pointer to storage for a char variable
 * @param ifAlias_val_ptr_len_ptr
 *        Pointer to a size_t. On entry, it will contain the size (in bytes)
 *        pointed to by ifAlias.
 *        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 (*ifAlias_val_ptr_len_ptr) bytes of memory,
 *       allocate it using malloc() and update ifAlias_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
ifAlias_get(ifXTable_rowreq_ctx * rowreq_ctx, char **ifAlias_val_ptr_ptr,
            size_t * ifAlias_val_ptr_len_ptr)
{
   /** we should have a non-NULL pointer and enough storage */
    netsnmp_assert((NULL != ifAlias_val_ptr_ptr)
                   && (NULL != *ifAlias_val_ptr_ptr));
    netsnmp_assert(NULL != ifAlias_val_ptr_len_ptr);


    DEBUGMSGTL(("verbose:ifXTable:ifAlias_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ifAlias data.
     * copy (* ifAlias_val_ptr_ptr ) data and (* ifAlias_val_ptr_len_ptr ) from rowreq_ctx->data
     */
    /*
     * make sure there is enough space for ifAlias data
     */
    if ((NULL == (*ifAlias_val_ptr_ptr)) ||
        ((*ifAlias_val_ptr_len_ptr) <
         (rowreq_ctx->data.ifAlias_len *
          sizeof(rowreq_ctx->data.ifAlias[0])))) {
        /*
         * allocate space for ifAlias data
         */
        (*ifAlias_val_ptr_ptr) =
            malloc(rowreq_ctx->data.ifAlias_len *
                   sizeof(rowreq_ctx->data.ifAlias[0]));
        if (NULL == (*ifAlias_val_ptr_ptr)) {
            snmp_log(LOG_ERR, "could not allocate memory\n");
            return MFD_ERROR;
        }
    }
    (*ifAlias_val_ptr_len_ptr) =
        rowreq_ctx->data.ifAlias_len * sizeof(rowreq_ctx->data.ifAlias[0]);
    memcpy((*ifAlias_val_ptr_ptr), rowreq_ctx->data.ifAlias,
           rowreq_ctx->data.ifAlias_len *
           sizeof(rowreq_ctx->data.ifAlias[0]));

    return MFD_SUCCESS;
}                               /* ifAlias_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifXEntry.ifCounterDiscontinuityTime
 * ifCounterDiscontinuityTime is subid 19 of ifXEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.31.1.1.1.19
 * Description:
The value of sysUpTime on the most recent occasion at which
            any one or more of this interface's counters suffered a
            discontinuity.  The relevant counters are the specific
            instances associated with this interface of any Counter32 or

            Counter64 object contained in the ifTable or ifXTable.  If
            no such discontinuities have occurred since the last re-
            initialization of the local 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 ifCounterDiscontinuityTime data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifCounterDiscontinuityTime_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
ifCounterDiscontinuityTime_get(ifXTable_rowreq_ctx * rowreq_ctx,
                               u_long * ifCounterDiscontinuityTime_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifCounterDiscontinuityTime_val_ptr);


    DEBUGMSGTL(("verbose:ifXTable:ifCounterDiscontinuityTime_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* ifCounterDiscontinuityTime_get */



/** @} */
/**********************************************************************
 **********************************************************************
 ***
 *** Table ifXTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * IF-MIB::ifXTable is subid 1 of ifMIBObjects.
 * Its status is Current.
 * OID: .1.3.6.1.2.1.31.1.1, length: 9
 */
    /*
     * 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
     *                        +==============+
     *       +----------------||  object    ||
     *       |              E ||  lookup    ||
     *       |                +==============+
     *       |                       | 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
     *                        +--------------+
     *                        |    post      |
     *                        |   request    |
     *                        +--------------+
     *
     */

/**
 * 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
 * ifXTable_allocate_data(), but may need extra
 * initialization similar to what you may have done in
 * ifXTable_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 (ifXTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 */
int
ifXTable_undo_setup(ifXTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("verbose:ifXTable:ifXTable_undo_setup", "called\n"));

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

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

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

    DEBUGMSGTL(("verbose:ifXTable:ifXTable_undo", "called\n"));

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

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

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

    DEBUGMSGTL(("verbose:ifXTable:ifXTable_undo_cleanup", "called\n"));

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

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

    return rc;
}                               /* ifXTable_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
 * ifXTable.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
ifXTable_commit(ifXTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;
    int             save_flags;

    DEBUGMSGTL(("verbose:ifXTable:ifXTable_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 ifXTable 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.
     *
     * this is where one would usually commit data. In this case,
     * ifLinkUpDownTrapEnable and ifAlias are purely internal, so
     * nothing needs to be done. That leaves ifPromiscuosMode,
     * which I'm leery about implementing. Thus, at this point,
     * there is nothing to do except twiddle flag bits.
     */
    if (save_flags & COLUMN_IFLINKUPDOWNTRAPENABLE_FLAG) {
        save_flags &= ~COLUMN_IFLINKUPDOWNTRAPENABLE_FLAG;      /* clear ifLinkUpDownTrapEnable */
        /*
         * TODO:482:o: |-> commit column ifLinkUpDownTrapEnable.
         */
        /*
         * set flag, in case we need to undo ifLinkUpDownTrapEnable
         */
        rowreq_ctx->column_set_flags |= COLUMN_IFLINKUPDOWNTRAPENABLE_FLAG;
    }
#ifdef NETSNMP_ENABLE_PROMISCUOUSMODE_SET
    if (save_flags & COLUMN_IFPROMISCUOUSMODE_FLAG) {
        save_flags &= ~COLUMN_IFPROMISCUOUSMODE_FLAG;   /* clear ifPromiscuousMode */
        /*
         * TODO:482:o: |-> commit column ifPromiscuousMode.
         */
        rc = -1;
        if (-1 == rc) {
            snmp_log(LOG_ERR,
                     "ifXTable column ifPromiscuousMode commit failed\n");
        } else {
            /*
             * set flag, in case we need to undo ifPromiscuousMode
             */
            rowreq_ctx->column_set_flags |= COLUMN_IFPROMISCUOUSMODE_FLAG;
        }
    }
#endif                          /* NETSNMP_ENABLE_PROMISCUOUSMODE_SET */

    if (save_flags & COLUMN_IFALIAS_FLAG) {
        save_flags &= ~COLUMN_IFALIAS_FLAG;     /* clear ifAlias */
        /*
         * set flag, in case we need to undo ifAlias
         */
        rowreq_ctx->column_set_flags |= COLUMN_IFALIAS_FLAG;
    }

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

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

    return rc;
}                               /* ifXTable_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
 * ifXTable.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
ifXTable_undo_commit(ifXTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("verbose:ifXTable:ifXTable_undo_commit", "called\n"));

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

    /*
     * TODO:485:M: |-> Undo ifXTable 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;
}                               /* ifXTable_undo_commit */

/*
 * TODO:440:M: Implement ifXTable node value checks.
 * TODO:450:M: Implement ifXTable undo functions.
 * TODO:460:M: Implement ifXTable set functions.
 * TODO:480:M: Implement ifXTable commit functions.
 */
/*---------------------------------------------------------------------
 * IF-MIB::ifXEntry.ifLinkUpDownTrapEnable
 * ifLinkUpDownTrapEnable is subid 14 of ifXEntry.
 * Its status is Current, and its access level is ReadWrite.
 * OID: .1.3.6.1.2.1.31.1.1.1.14
 * Description:
Indicates whether linkUp/linkDown traps should be generated
            for this interface.

            By default, this object should have the value enabled(1) for
            interfaces which do not operate on 'top' of any other
            interface (as defined in the ifStackTable), and disabled(2)
            otherwise.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 * Enum range: 2/8. Values:  enabled(1), disabled(2)
 *
 * 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 ifLinkUpDownTrapEnable_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
 * ifXTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_INTEGER
 *    The value is one of  enabled(1), disabled(2)
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
ifLinkUpDownTrapEnable_check_value(ifXTable_rowreq_ctx * rowreq_ctx,
                                   u_long ifLinkUpDownTrapEnable_val)
{
    DEBUGMSGTL(("verbose:ifXTable:ifLinkUpDownTrapEnable_check_value",
                "called\n"));

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

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

    return MFD_SUCCESS;         /* ifLinkUpDownTrapEnable value not illegal */
}                               /* ifLinkUpDownTrapEnable_check_value */

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

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

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


    return MFD_SUCCESS;
}                               /* ifLinkUpDownTrapEnable_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 ifLinkUpDownTrapEnable_val
 *        A long containing the new value.
 */
int
ifLinkUpDownTrapEnable_set(ifXTable_rowreq_ctx * rowreq_ctx,
                           u_long ifLinkUpDownTrapEnable_val)
{

    DEBUGMSGTL(("verbose:ifXTable:ifLinkUpDownTrapEnable_set",
                "called\n"));

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

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

    return MFD_SUCCESS;
}                               /* ifLinkUpDownTrapEnable_set */

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

    DEBUGMSGTL(("verbose:ifXTable:ifLinkUpDownTrapEnable_undo",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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


    return MFD_SUCCESS;
}                               /* ifLinkUpDownTrapEnable_undo */

/*---------------------------------------------------------------------
 * IF-MIB::ifXEntry.ifPromiscuousMode
 * ifPromiscuousMode is subid 16 of ifXEntry.
 * Its status is Current, and its access level is ReadWrite.
 * OID: .1.3.6.1.2.1.31.1.1.1.16
 * Description:
This object has a value of false(2) if this interface only
            accepts packets/frames that are addressed to this station.
            This object has a value of true(1) when the station accepts
            all packets/frames transmitted on the media.  The value
            true(1) is only legal on certain types of media.  If legal,
            setting this object to a value of true(1) may require the
            interface to be reset before becoming effective.

            The value of ifPromiscuousMode does not affect the reception
            of broadcast and multicast packets/frames by the interface.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 * Enum range: 2/8. Values:  true(1), false(2)
 *
 * Its syntax is TruthValue (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 ifPromiscuousMode_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
 * ifXTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_INTEGER
 *    The value is one of  true(1), false(2)
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
ifPromiscuousMode_check_value(ifXTable_rowreq_ctx * rowreq_ctx,
                              u_long ifPromiscuousMode_val)
{
    DEBUGMSGTL(("verbose:ifXTable:ifPromiscuousMode_check_value",
                "called\n"));

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

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

    return MFD_SUCCESS;         /* ifPromiscuousMode value not illegal */
}                               /* ifPromiscuousMode_check_value */

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

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

    /*
     * TODO:455:o: |-> Setup ifPromiscuousMode undo.
     */
#ifdef NETSNMP_ENABLE_PROMISCUOUSMODE_SET
    /*
     * copy ifPromiscuousMode data
     * set rowreq_ctx->undo->ifPromiscuousMode from rowreq_ctx->data.ifPromiscuousMode
     */
    rowreq_ctx->undo->ifPromiscuousMode =
        rowreq_ctx->data.ifPromiscuousMode;


    return MFD_SUCCESS;
#else
    return MFD_NOT_VALID_EVER;
#endif
}                               /* ifPromiscuousMode_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 ifPromiscuousMode_val
 *        A long containing the new value.
 */
int
ifPromiscuousMode_set(ifXTable_rowreq_ctx * rowreq_ctx,
                      u_long ifPromiscuousMode_val)
{

    DEBUGMSGTL(("verbose:ifXTable:ifPromiscuousMode_set", "called\n"));

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

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

    return MFD_SUCCESS;
}                               /* ifPromiscuousMode_set */

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

    DEBUGMSGTL(("verbose:ifXTable:ifPromiscuousMode_undo", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up ifPromiscuousMode undo.
     */
#ifdef NETSNMP_ENABLE_PROMISCUOUSMODE_SET
    /*
     * copy ifPromiscuousMode data
     * set rowreq_ctx->data.ifPromiscuousMode from rowreq_ctx->undo->ifPromiscuousMode
     */
    rowreq_ctx->data.ifPromiscuousMode =
        rowreq_ctx->undo->ifPromiscuousMode;
#endif

    return MFD_SUCCESS;
}                               /* ifPromiscuousMode_undo */

/*---------------------------------------------------------------------
 * IF-MIB::ifXEntry.ifAlias
 * ifAlias is subid 18 of ifXEntry.
 * Its status is Current, and its access level is ReadWrite.
 * OID: .1.3.6.1.2.1.31.1.1.1.18
 * Description:
This object is an 'alias' name for the interface as
            specified by a network manager, and provides a non-volatile
            'handle' for the interface.

            On the first instantiation of an interface, the value of
            ifAlias associated with that interface is the zero-length
            string.  As and when a value is written into an instance of
            ifAlias through a network management set operation, then the
            agent must retain the supplied value in the ifAlias instance
            associated with the same interface for as long as that
            interface remains instantiated, including across all re-
            initializations/reboots of the network management system,
            including those which result in a change of the interface's
            ifIndex value.

            An example of the value which a network manager might store
            in this object for a WAN interface is the (Telco's) circuit
            number/identifier of the interface.

            Some agents may support write-access only for interfaces
            having particular values of ifType.  An agent which supports
            write access to this object is required to keep the value in
            non-volatile storage, but it may limit the length of new
            values depending on how much storage is already occupied by
            the current values for other interfaces.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 1      hashint   1
 *   settable   1
 *   hint: 255a
 *
 * Ranges:  0 - 64;
 *
 * Its syntax is DisplayString (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 64)
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifAlias_val_ptr
 *        A char containing the new value.
 * @param ifAlias_val_ptr_len
 *        The size (in bytes) of the data pointed to by ifAlias_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).
 *
 * 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
 * ifXTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_OCTET_STR
 *    The length is < sizeof(rowreq_ctx->data.ifAlias).
 *    The length is in (one of) the range set(s):  0 - 64
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
ifAlias_check_value(ifXTable_rowreq_ctx * rowreq_ctx,
                    char *ifAlias_val_ptr, size_t ifAlias_val_ptr_len)
{
    DEBUGMSGTL(("verbose:ifXTable:ifAlias_check_value", "called\n"));

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

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

    return MFD_SUCCESS;         /* ifAlias value not illegal */
}                               /* ifAlias_check_value */

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

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

    /*
     * TODO:455:o: |-> Setup ifAlias undo.
     */
    /*
     * copy ifAlias and ifAlias_len data
     * set rowreq_ctx->undo->ifAlias from rowreq_ctx->data.ifAlias
     */
    memcpy(rowreq_ctx->undo->ifAlias, rowreq_ctx->data.ifAlias,
           (rowreq_ctx->data.ifAlias_len *
            sizeof(rowreq_ctx->undo->ifAlias[0])));
    rowreq_ctx->undo->ifAlias_len = rowreq_ctx->data.ifAlias_len;


    return MFD_SUCCESS;
}                               /* ifAlias_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 ifAlias_val_ptr
 *        A char containing the new value.
 * @param ifAlias_val_ptr_len
 *        The size (in bytes) of the data pointed to by ifAlias_val_ptr
 */
int
ifAlias_set(ifXTable_rowreq_ctx * rowreq_ctx, char *ifAlias_val_ptr,
            size_t ifAlias_val_ptr_len)
{

    DEBUGMSGTL(("verbose:ifXTable:ifAlias_set", "called\n"));

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

    /*
     * TODO:461:M: |-> Set ifAlias value.
     * set ifAlias value in rowreq_ctx->data
     */
    memcpy(rowreq_ctx->data.ifAlias, ifAlias_val_ptr, ifAlias_val_ptr_len);
    /** convert bytes to number of char */
    rowreq_ctx->data.ifAlias_len =
        ifAlias_val_ptr_len / sizeof(ifAlias_val_ptr[0]);

    return MFD_SUCCESS;
}                               /* ifAlias_set */

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

    DEBUGMSGTL(("verbose:ifXTable:ifAlias_undo", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up ifAlias undo.
     */
    /*
     * copy ifAlias and ifAlias_len data
     * set rowreq_ctx->data.ifAlias from rowreq_ctx->undo->ifAlias
     */
    memcpy(rowreq_ctx->data.ifAlias, rowreq_ctx->undo->ifAlias,
           (rowreq_ctx->undo->ifAlias_len *
            sizeof(rowreq_ctx->data.ifAlias[0])));
    rowreq_ctx->data.ifAlias_len = rowreq_ctx->undo->ifAlias_len;


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

    DEBUGMSGTL(("internal:ifXTable:ifXTable_check_dependencies",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:470:o: Check ifXTable row dependencies.
     * check that all new value are legal and consistent with each other
     */
    return rc;
}                               /* ifXTable_check_dependencies */

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