/*
 * Note: this file originally auto-generated by mib2c using
 *       version : 1.48 $ of : mfd-top.m2c,v $ 
 *
 * $Id$
 */
/** \page MFD helper for ifTable
 *
 * \section intro Introduction
 * Introductory text.
 *
 */
/*
 * standard Net-SNMP includes 
 */
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-features.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

#ifndef NETSNMP_NO_WRITE_SUPPORT
netsnmp_feature_require(interface_access_entry_set_admin_status)
#endif /* NETSNMP_NO_WRITE_SUPPORT */

/*
 * include our parent header 
 */
#include "ifTable.h"
#include "ifTable_defs.h"

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

#include "ifTable_interface.h"

#ifdef USING_IP_MIB_IPV4INTERFACETABLE_IPV4INTERFACETABLE_MODULE
#   include "ip-mib/ipv4InterfaceTable/ipv4InterfaceTable.h"
#endif
#ifdef USING_IP_MIB_IPV6INTERFACETABLE_IPV6INTERFACETABLE_MODULE
#   include "ip-mib/ipv6InterfaceTable/ipv6InterfaceTable.h"
#endif
#ifdef USING_IF_MIB_IFXTABLE_IFXTABLE_MODULE
#   include "if-mib/ifXTable/ifXTable.h"
#endif

const oid       ifTable_oid[] = { IFTABLE_OID };
const int       ifTable_oid_size = OID_LENGTH(ifTable_oid);

ifTable_registration ifTable_user_context;
static ifTable_registration *ifTable_user_context_p;

void            initialize_table_ifTable(void);
void            shutdown_table_ifTable(void);

static int
_if_number_handler(netsnmp_mib_handler *handler,
                   netsnmp_handler_registration *reginfo,
                   netsnmp_agent_request_info *reqinfo,
                   netsnmp_request_info *requests);


/**
 * Initializes the ifTable module
 */
void
init_ifTable(void)
{
    static int      ifTable_did_init = 0;

    DEBUGMSGTL(("verbose:ifTable:init_ifTable", "called\n"));

    /*
     * TODO:300:o: Perform ifTable one-time module initialization.
     */
    if (++ifTable_did_init != 1) {
        DEBUGMSGTL(("ifTable:init_ifTable", "ignoring duplicate call\n"));
        return;
    }

    /*
     * here we initialize all the tables we're planning on supporting
     */
    if (should_init("ifTable")) {

#ifdef USING_IP_MIB_IPV4INTERFACETABLE_IPV4INTERFACETABLE_MODULE
        if (should_init("ipv4InterfaceTable"))
            initialize_table_ipv4InterfaceTable();
#endif

#ifdef USING_IP_MIB_IPV6INTERFACETABLE_IPV6INTERFACETABLE_MODULE
        if (should_init("ipv6InterfaceTable"))
            initialize_table_ipv6InterfaceTable();
#endif

        initialize_table_ifTable();

#ifdef USING_IF_MIB_IFXTABLE_IFXTABLE_MODULE
        if (should_init("ifXTable"))
            initialize_table_ifXTable();
#endif
    }
}                               /* init_ifTable */

/**
 * Shut-down the ifTable module (agent is exiting)
 */
void
shutdown_ifTable(void)
{
    if (should_init("ifTable"))
        shutdown_table_ifTable();

}

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

    DEBUGMSGTL(("verbose:ifTable:initialize_table_ifTable", "called\n"));

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

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

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

    /*
     * call interface initialization code
     */
    _ifTable_initialize_interface(ifTable_user_context_p, flags);

    /*
     * register scalar for ifNumber
     */
    {
        const oid       reg_oid[] = { IFTABLE_NUMBER };
        netsnmp_handler_registration *myreg;

        myreg =
            netsnmp_create_handler_registration("if number",
                                                _if_number_handler,
                                                reg_oid,
                                                OID_LENGTH(reg_oid),
                                                HANDLER_CAN_RONLY);
        netsnmp_register_scalar(myreg);
    }

}                               /* initialize_table_ifTable */

/**
 * Shutdown the table ifTable
 */
void
shutdown_table_ifTable(void)
{
    /*
     * call interface shutdown code
     */
    _ifTable_shutdown_interface(ifTable_user_context_p);
    netsnmp_free_all_list_data(ifTable_user_context_p);
    ifTable_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
ifTable_rowreq_ctx_init(ifTable_rowreq_ctx * rowreq_ctx,
                        void *user_init_ctx)
{
    DEBUGMSGTL(("verbose:ifTable:ifTable_rowreq_ctx_init", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:210:o: |-> Perform extra ifTable rowreq initialization. (eg DEFVALS)
     */
    if (NULL == user_init_ctx)
        rowreq_ctx->data.ifentry =
            netsnmp_access_interface_entry_create(NULL, 0);
    else
        rowreq_ctx->data.ifentry =
            (netsnmp_interface_entry *) user_init_ctx;

    return MFD_SUCCESS;
}                               /* ifTable_rowreq_ctx_init */

/**
 * extra context cleanup
 * @param rowreq_ctx
 */
void
ifTable_rowreq_ctx_cleanup(ifTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ifTable:ifTable_rowreq_ctx_cleanup", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:211:o: |-> Perform extra ifTable rowreq cleanup.
     */
    if (NULL != rowreq_ctx->data.ifentry) {
        netsnmp_access_interface_entry_free(rowreq_ctx->data.ifentry);
        rowreq_ctx->data.ifentry = NULL;
    }
}                               /* ifTable_rowreq_ctx_cleanup */

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

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

    return MFD_SUCCESS;
}                               /* ifTable_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
ifTable_post_request(ifTable_registration * user_context, int rc)
{
    DEBUGMSGTL(("verbose:ifTable:ifTable_post_request", "called\n"));

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

    /*
     * check to set if any rows were changed.
     */
    if (ifTable_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) {
            /*
             * notify library to save changed rows
             */
            snmp_store_needed(netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
                                             NETSNMP_DS_LIB_APPTYPE));
        }

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

    return MFD_SUCCESS;
}                               /* ifTable_post_request */


/**********************************************************************
 **********************************************************************
 ***
 *** Table ifTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * IF-MIB::ifTable is subid 2 of interfaces.
 * Its status is Current.
 * OID: .1.3.6.1.2.1.2.2, length: 8
 */

/*
 * ---------------------------------------------------------------------
 * * TODO:200:r: Implement ifTable 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
ifTable_indexes_set_tbl_idx(ifTable_mib_index * tbl_idx, long ifIndex_val)
{
    DEBUGMSGTL(("verbose:ifTable:ifTable_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;
}                               /* ifTable_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
ifTable_indexes_set(ifTable_rowreq_ctx * rowreq_ctx, long ifIndex_val)
{
    DEBUGMSGTL(("verbose:ifTable:ifTable_indexes_set", "called\n"));

    if (MFD_SUCCESS !=
        ifTable_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 != ifTable_index_to_oid(&rowreq_ctx->oid_idx,
                                  &rowreq_ctx->tbl_idx)) {
        return MFD_ERROR;
    }

    return MFD_SUCCESS;
}                               /* ifTable_indexes_set */


/*---------------------------------------------------------------------
 * IF-MIB::ifEntry.ifDescr
 * ifDescr is subid 2 of ifEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.2.2.1.2
 * Description:
A textual string containing information about the
            interface.  This string should include the name of the
            manufacturer, the product name and the version of the
            interface hardware/software.
 *
 * 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 ifDescr data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifDescr_val_ptr_ptr
 *        Pointer to storage for a char variable
 * @param ifDescr_val_ptr_len_ptr
 *        Pointer to a size_t. On entry, it will contain the size (in bytes)
 *        pointed to by ifDescr.
 *        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 (*ifDescr_val_ptr_len_ptr) bytes of memory,
 *       allocate it using malloc() and update ifDescr_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
ifDescr_get(ifTable_rowreq_ctx * rowreq_ctx, char **ifDescr_val_ptr_ptr,
            size_t * ifDescr_val_ptr_len_ptr)
{
    char           *tmp_descr = NULL;
    u_char          tmp_len = 0;

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


    DEBUGMSGTL(("verbose:ifTable:ifDescr_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * if ifDescr is NULL, use the ifName
     */
    if (NULL == rowreq_ctx->data.ifDescr) {
#ifdef USING_IF_MIB_IFXTABLE_IFXTABLE_MODULE
        tmp_descr = rowreq_ctx->data.ifName;
#else
        tmp_descr = NULL;
#endif
    } else
        tmp_descr = rowreq_ctx->data.ifDescr;

    if (NULL != tmp_descr)
        tmp_len = strlen(tmp_descr);
    else
        tmp_len = 0;

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

    return MFD_SUCCESS;
}                               /* ifDescr_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifEntry.ifType
 * ifType is subid 3 of ifEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.2.2.1.3
 * Description:
The type of interface.  Additional values for ifType are
            assigned by the Internet Assigned Numbers Authority (IANA),
            through updating the syntax of the IANAifType textual
            convention.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 * Enum range: 149/256. Values:  other(1), regular1822(2), hdh1822(3), ddnX25(4), rfc877x25(5), ethernetCsmacd(6), iso88023Csmacd(7), iso88024TokenBus(8), iso88025TokenRing(9), iso88026Man(10), starLan(11), proteon10Mbit(12), proteon80Mbit(13), hyperchannel(14), fddi(15), lapb(16), sdlc(17), ds1(18), e1(19), basicISDN(20), primaryISDN(21), propPointToPointSerial(22), ppp(23), softwareLoopback(24), eon(25), ethernet3Mbit(26), nsip(27), slip(28), ultra(29), ds3(30), sip(31), frameRelay(32), rs232(33), para(34), arcnet(35), arcnetPlus(36), atm(37), miox25(38), sonet(39), x25ple(40), iso88022llc(41), localTalk(42), smdsDxi(43), frameRelayService(44), v35(45), hssi(46), hippi(47), modem(48), aal5(49), sonetPath(50), sonetVT(51), smdsIcip(52), propVirtual(53), propMultiplexor(54), ieee80212(55), fibreChannel(56), hippiInterface(57), frameRelayInterconnect(58), aflane8023(59), aflane8025(60), cctEmul(61), fastEther(62), isdn(63), v11(64), v36(65), g703at64k(66), g703at2mb(67), qllc(68), fastEtherFX(69), channel(70), ieee80211(71), ibm370parChan(72), escon(73), dlsw(74), isdns(75), isdnu(76), lapd(77), ipSwitch(78), rsrb(79), atmLogical(80), ds0(81), ds0Bundle(82), bsc(83), async(84), cnr(85), iso88025Dtr(86), eplrs(87), arap(88), propCnls(89), hostPad(90), termPad(91), frameRelayMPI(92), x213(93), adsl(94), radsl(95), sdsl(96), vdsl(97), iso88025CRFPInt(98), myrinet(99), voiceEM(100), voiceFXO(101), voiceFXS(102), voiceEncap(103), voiceOverIp(104), atmDxi(105), atmFuni(106), atmIma(107), pppMultilinkBundle(108), ipOverCdlc(109), ipOverClaw(110), stackToStack(111), virtualIpAddress(112), mpc(113), ipOverAtm(114), iso88025Fiber(115), tdlc(116), gigabitEthernet(117), hdlc(118), lapf(119), v37(120), x25mlp(121), x25huntGroup(122), trasnpHdlc(123), interleave(124), fast(125), ip(126), docsCableMaclayer(127), docsCableDownstream(128), docsCableUpstream(129), a12MppSwitch(130), tunnel(131), coffee(132), ces(133), atmSubInterface(134), l2vlan(135), l3ipvlan(136), l3ipxvlan(137), digitalPowerline(138), mediaMailOverIp(139), dtm(140), dcn(141), ipForward(142), msdsl(143), ieee1394(144), if_gsn(145), dvbRccMacLayer(146), dvbRccDownstream(147), dvbRccUpstream(148), atmVirtual(149), mplsTunnel(150), srp(151), voiceOverAtm(152), voiceOverFrameRelay(153), idsl(154), compositeLink(155), ss7SigLink(156), propWirelessP2P(157), frForward(158), rfc1483(159), usb(160), ieee8023adLag(161), bgppolicyaccounting(162), frf16MfrBundle(163), h323Gatekeeper(164), h323Proxy(165), mpls(166), mfSigLink(167), hdsl2(168), shdsl(169), ds1FDL(170), pos(171), dvbAsiIn(172), dvbAsiOut(173), plc(174), nfas(175), tr008(176), gr303RDT(177), gr303IDT(178), isup(179), propDocsWirelessMaclayer(180), propDocsWirelessDownstream(181), propDocsWirelessUpstream(182), hiperlan2(183), propBWAp2Mp(184), sonetOverheadChannel(185), digitalWrapperOverheadChannel(186), aal2(187), radioMAC(188), atmRadio(189), imt(190), mvl(191), reachDSL(192), frDlciEndPt(193), atmVciEndPt(194), opticalChannel(195), opticalTransport(196), propAtm(197), voiceOverCable(198), infiniband(199), teLink(200), q2931(201), virtualTg(202), sipTg(203), sipSig(204), docsCableUpstreamChannel(205), econet(206), pon155(207), pon622(208), bridge(209), linegroup(210), voiceEMFGD(211), voiceFGDEANA(212), voiceDID(213), mpegTransport(214), sixToFour(215), gtp(216), pdnEtherLoop1(217), pdnEtherLoop2(218), opticalChannelGroup(219), homepna(220), gfp(221), ciscoISLvlan(222), actelisMetaLOOP(223), fcipLink(224)
 *
 * Its syntax is IANAifType (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 ifType data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifType_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
ifType_get(ifTable_rowreq_ctx * rowreq_ctx, u_long * ifType_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifType_val_ptr);


    DEBUGMSGTL(("verbose:ifTable:ifType_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* ifType_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifEntry.ifMtu
 * ifMtu is subid 4 of ifEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.2.2.1.4
 * Description:
The size of the largest packet which can be sent/received
            on the interface, specified in octets.  For interfaces that
            are used for transmitting network datagrams, this is the
            size of the largest network datagram that can be sent on the
            interface.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is INTEGER32 (based on perltype INTEGER32)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (long)
 */
/**
 * Extract the current value of the ifMtu data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifMtu_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
ifMtu_get(ifTable_rowreq_ctx * rowreq_ctx, long *ifMtu_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifMtu_val_ptr);


    DEBUGMSGTL(("verbose:ifTable:ifMtu_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* ifMtu_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifEntry.ifSpeed
 * ifSpeed is subid 5 of ifEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.2.2.1.5
 * Description:
An estimate of the interface's current bandwidth in bits
            per second.  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.  If the
            bandwidth of the interface is greater than the maximum value
            reportable by this object then this object should report its
            maximum value (4,294,967,295) and ifHighSpeed must be used
            to report the interace's speed.  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 ifSpeed data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifSpeed_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
ifSpeed_get(ifTable_rowreq_ctx * rowreq_ctx, u_long * ifSpeed_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifSpeed_val_ptr);


    DEBUGMSGTL(("verbose:ifTable:ifSpeed_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* ifSpeed_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifEntry.ifPhysAddress
 * ifPhysAddress is subid 6 of ifEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.2.2.1.6
 * Description:
The interface's address at its protocol sub-layer.  For
            example, for an 802.x interface, this object normally
            contains a MAC address.  The interface's media-specific MIB
            must define the bit and byte ordering and the format of the
            value of this object.  For interfaces which do not have such
            an address (e.g., a serial line), this object should contain
            an octet string of zero length.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   1
 *   settable   0
 *   hint: 1x:
 *
 *
 * 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 255)
 */
/**
 * Extract the current value of the ifPhysAddress data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifPhysAddress_val_ptr_ptr
 *        Pointer to storage for a char variable
 * @param ifPhysAddress_val_ptr_len_ptr
 *        Pointer to a size_t. On entry, it will contain the size (in bytes)
 *        pointed to by ifPhysAddress.
 *        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 (*ifPhysAddress_val_ptr_len_ptr) bytes of memory,
 *       allocate it using malloc() and update ifPhysAddress_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
ifPhysAddress_get(ifTable_rowreq_ctx * rowreq_ctx,
                  char **ifPhysAddress_val_ptr_ptr,
                  size_t * ifPhysAddress_val_ptr_len_ptr)
{
   /** we should have a non-NULL pointer and enough storage */
    netsnmp_assert((NULL != ifPhysAddress_val_ptr_ptr)
                   && (NULL != *ifPhysAddress_val_ptr_ptr));
    netsnmp_assert(NULL != ifPhysAddress_val_ptr_len_ptr);


    DEBUGMSGTL(("verbose:ifTable:ifPhysAddress_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    if ((rowreq_ctx->data.ifPhysAddress[0] == 0) &&
        (rowreq_ctx->data.ifPhysAddress[1] == 0) &&
        (rowreq_ctx->data.ifPhysAddress[2] == 0) &&
        (rowreq_ctx->data.ifPhysAddress[3] == 0) &&
        (rowreq_ctx->data.ifPhysAddress[4] == 0) &&
        (rowreq_ctx->data.ifPhysAddress[5] == 0)) {
        /*
         * all 0s = empty string
         */
        (*ifPhysAddress_val_ptr_len_ptr) = 0;
        return MFD_SUCCESS;
    }

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

    return MFD_SUCCESS;
}                               /* ifPhysAddress_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifEntry.ifAdminStatus
 * ifAdminStatus is subid 7 of ifEntry.
 * Its status is Current, and its access level is ReadWrite.
 * OID: .1.3.6.1.2.1.2.2.1.7
 * Description:
The desired state of the interface.  The testing(3) state
            indicates that no operational packets can be passed.  When a
            managed system initializes, all interfaces start with
            ifAdminStatus in the down(2) state.  As a result of either
            explicit management action or per configuration information
            retained by the managed system, ifAdminStatus is then
            changed to either the up(1) or testing(3) states (or remains
            in the down(2) state).
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 * Enum range: 2/8. Values:  up(1), down(2), testing(3)
 *
 * Its syntax is INTEGER (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Extract the current value of the ifAdminStatus data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifAdminStatus_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
ifAdminStatus_get(ifTable_rowreq_ctx * rowreq_ctx,
                  u_long * ifAdminStatus_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifAdminStatus_val_ptr);


    DEBUGMSGTL(("verbose:ifTable:ifAdminStatus_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* ifAdminStatus_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifEntry.ifOperStatus
 * ifOperStatus is subid 8 of ifEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.2.2.1.8
 * Description:
The current operational state of the interface.  The
            testing(3) state indicates that no operational packets can
            be passed.  If ifAdminStatus is down(2) then ifOperStatus
            should be down(2).  If ifAdminStatus is changed to up(1)
            then ifOperStatus should change to up(1) if the interface is
            ready to transmit and receive network traffic; it should
            change to dormant(5) if the interface is waiting for
            external actions (such as a serial line waiting for an
            incoming connection); it should remain in the down(2) state
            if and only if there is a fault that prevents it from going
            to the up(1) state; it should remain in the notPresent(6)
            state if the interface has missing (typically, hardware)
            components.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 * Enum range: 5/8. Values:  up(1), down(2), testing(3), unknown(4), dormant(5), notPresent(6), lowerLayerDown(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 ifOperStatus data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifOperStatus_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
ifOperStatus_get(ifTable_rowreq_ctx * rowreq_ctx,
                 u_long * ifOperStatus_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifOperStatus_val_ptr);


    DEBUGMSGTL(("verbose:ifTable:ifOperStatus_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* ifOperStatus_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifEntry.ifLastChange
 * ifLastChange is subid 9 of ifEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.2.2.1.9
 * Description:
The value of sysUpTime at the time the interface entered
            its current operational state.  If the current state was
            entered 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 TICKS (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 ifLastChange data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifLastChange_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
ifLastChange_get(ifTable_rowreq_ctx * rowreq_ctx,
                 u_long * ifLastChange_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifLastChange_val_ptr);


    DEBUGMSGTL(("verbose:ifTable:ifLastChange_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* ifLastChange_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifEntry.ifInOctets
 * ifInOctets is subid 10 of ifEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.2.2.1.10
 * Description:
The total number of octets received on the interface,
            including framing characters.

            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 ifInOctets data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifInOctets_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
ifInOctets_get(ifTable_rowreq_ctx * rowreq_ctx,
               u_long * ifInOctets_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifInOctets_val_ptr);


    DEBUGMSGTL(("verbose:ifTable:ifInOctets_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* ifInOctets_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifEntry.ifInUcastPkts
 * ifInUcastPkts is subid 11 of ifEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.2.2.1.11
 * 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.

            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 ifInUcastPkts data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifInUcastPkts_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
ifInUcastPkts_get(ifTable_rowreq_ctx * rowreq_ctx,
                  u_long * ifInUcastPkts_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifInUcastPkts_val_ptr);


    DEBUGMSGTL(("verbose:ifTable:ifInUcastPkts_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* ifInUcastPkts_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifEntry.ifInNUcastPkts
 * ifInNUcastPkts is subid 12 of ifEntry.
 * Its status is Deprecated, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.2.2.1.12
 * Description:
The number of packets, delivered by this sub-layer to a
            higher (sub-)layer, which were addressed to a multicast or
            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.

            This object is deprecated in favour of ifInMulticastPkts and
            ifInBroadcastPkts.
 *
 * 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 ifInNUcastPkts data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifInNUcastPkts_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
ifInNUcastPkts_get(ifTable_rowreq_ctx * rowreq_ctx,
                   u_long * ifInNUcastPkts_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifInNUcastPkts_val_ptr);


    DEBUGMSGTL(("verbose:ifTable:ifInNUcastPkts_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* ifInNUcastPkts_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifEntry.ifInDiscards
 * ifInDiscards is subid 13 of ifEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.2.2.1.13
 * Description:
The number of inbound packets which were chosen to be
            discarded even though no errors had been detected to prevent

            their being deliverable to a higher-layer protocol.  One
            possible reason for discarding such a packet could be to
            free up buffer space.

            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 ifInDiscards data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifInDiscards_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
ifInDiscards_get(ifTable_rowreq_ctx * rowreq_ctx,
                 u_long * ifInDiscards_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifInDiscards_val_ptr);


    DEBUGMSGTL(("verbose:ifTable:ifInDiscards_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* ifInDiscards_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifEntry.ifInErrors
 * ifInErrors is subid 14 of ifEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.2.2.1.14
 * Description:
For packet-oriented interfaces, the number of inbound
            packets that contained errors preventing them from being
            deliverable to a higher-layer protocol.  For character-
            oriented or fixed-length interfaces, the number of inbound
            transmission units that contained errors preventing them
            from being deliverable to a higher-layer protocol.

            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 ifInErrors data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifInErrors_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
ifInErrors_get(ifTable_rowreq_ctx * rowreq_ctx,
               u_long * ifInErrors_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifInErrors_val_ptr);


    DEBUGMSGTL(("verbose:ifTable:ifInErrors_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* ifInErrors_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifEntry.ifInUnknownProtos
 * ifInUnknownProtos is subid 15 of ifEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.2.2.1.15
 * Description:
For packet-oriented interfaces, the number of packets
            received via the interface which were discarded because of
            an unknown or unsupported protocol.  For character-oriented
            or fixed-length interfaces that support protocol
            multiplexing the number of transmission units received via
            the interface which were discarded because of an unknown or
            unsupported protocol.  For any interface that does not
            support protocol multiplexing, this counter will always be
            0.

            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 ifInUnknownProtos data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifInUnknownProtos_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
ifInUnknownProtos_get(ifTable_rowreq_ctx * rowreq_ctx,
                      u_long * ifInUnknownProtos_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifInUnknownProtos_val_ptr);


    DEBUGMSGTL(("verbose:ifTable:ifInUnknownProtos_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* ifInUnknownProtos_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifEntry.ifOutOctets
 * ifOutOctets is subid 16 of ifEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.2.2.1.16
 * Description:
The total number of octets transmitted out of the
            interface, including framing characters.

            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 ifOutOctets data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifOutOctets_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
ifOutOctets_get(ifTable_rowreq_ctx * rowreq_ctx,
                u_long * ifOutOctets_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifOutOctets_val_ptr);


    DEBUGMSGTL(("verbose:ifTable:ifOutOctets_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* ifOutOctets_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifEntry.ifOutUcastPkts
 * ifOutUcastPkts is subid 17 of ifEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.2.2.1.17
 * 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.

            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 ifOutUcastPkts data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifOutUcastPkts_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
ifOutUcastPkts_get(ifTable_rowreq_ctx * rowreq_ctx,
                   u_long * ifOutUcastPkts_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifOutUcastPkts_val_ptr);


    DEBUGMSGTL(("verbose:ifTable:ifOutUcastPkts_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* ifOutUcastPkts_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifEntry.ifOutNUcastPkts
 * ifOutNUcastPkts is subid 18 of ifEntry.
 * Its status is Deprecated, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.2.2.1.18
 * Description:
The total number of packets that higher-level protocols
            requested be transmitted, and which were addressed to a
            multicast or 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.

            This object is deprecated in favour of ifOutMulticastPkts
            and ifOutBroadcastPkts.
 *
 * 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 ifOutNUcastPkts data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifOutNUcastPkts_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
ifOutNUcastPkts_get(ifTable_rowreq_ctx * rowreq_ctx,
                    u_long * ifOutNUcastPkts_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifOutNUcastPkts_val_ptr);


    DEBUGMSGTL(("verbose:ifTable:ifOutNUcastPkts_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* ifOutNUcastPkts_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifEntry.ifOutDiscards
 * ifOutDiscards is subid 19 of ifEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.2.2.1.19
 * Description:
The number of outbound packets which were chosen to be
            discarded even though no errors had been detected to prevent
            their being transmitted.  One possible reason for discarding
            such a packet could be to free up buffer space.

            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 ifOutDiscards data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifOutDiscards_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
ifOutDiscards_get(ifTable_rowreq_ctx * rowreq_ctx,
                  u_long * ifOutDiscards_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifOutDiscards_val_ptr);


    DEBUGMSGTL(("verbose:ifTable:ifOutDiscards_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* ifOutDiscards_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifEntry.ifOutErrors
 * ifOutErrors is subid 20 of ifEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.2.2.1.20
 * Description:
For packet-oriented interfaces, the number of outbound
            packets that could not be transmitted because of errors.
            For character-oriented or fixed-length interfaces, the
            number of outbound transmission units that could not be
            transmitted because of errors.

            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 ifOutErrors data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifOutErrors_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
ifOutErrors_get(ifTable_rowreq_ctx * rowreq_ctx,
                u_long * ifOutErrors_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifOutErrors_val_ptr);


    DEBUGMSGTL(("verbose:ifTable:ifOutErrors_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* ifOutErrors_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifEntry.ifOutQLen
 * ifOutQLen is subid 21 of ifEntry.
 * Its status is Deprecated, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.2.2.1.21
 * Description:
The length of the output packet queue (in packets).
 *
 * 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 ifOutQLen data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifOutQLen_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
ifOutQLen_get(ifTable_rowreq_ctx * rowreq_ctx, u_long * ifOutQLen_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifOutQLen_val_ptr);


    DEBUGMSGTL(("verbose:ifTable:ifOutQLen_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return MFD_SUCCESS;
}                               /* ifOutQLen_get */

/*---------------------------------------------------------------------
 * IF-MIB::ifEntry.ifSpecific
 * ifSpecific is subid 22 of ifEntry.
 * Its status is Deprecated, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.2.2.1.22
 * Description:
A reference to MIB definitions specific to the particular
            media being used to realize the interface.  It is

            recommended that this value point to an instance of a MIB
            object in the media-specific MIB, i.e., that this object
            have the semantics associated with the InstancePointer
            textual convention defined in RFC 2579.  In fact, it is
            recommended that the media-specific MIB specify what value
            ifSpecific should/can take for values of ifType.  If no MIB
            definitions specific to the particular media are available,
            the value should be set to the OBJECT IDENTIFIER { 0 0 }.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is OBJECTID (based on perltype OBJECTID)
 * The net-snmp type is ASN_OBJECT_ID. The C type decl is oid (oid)
 * This data type requires a length.  (Max 255)
 */
/**
 * Extract the current value of the ifSpecific data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifSpecific_val_ptr_ptr
 *        Pointer to storage for a oid variable
 * @param ifSpecific_val_ptr_len_ptr
 *        Pointer to a size_t. On entry, it will contain the size (in bytes)
 *        pointed to by ifSpecific.
 *        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 (*ifSpecific_val_ptr_len_ptr) bytes of memory,
 *       allocate it using malloc() and update ifSpecific_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
ifSpecific_get(ifTable_rowreq_ctx * rowreq_ctx,
               oid ** ifSpecific_val_ptr_ptr,
               size_t * ifSpecific_val_ptr_len_ptr)
{
   /** we should have a non-NULL pointer and enough storage */
    netsnmp_assert((NULL != ifSpecific_val_ptr_ptr)
                   && (NULL != *ifSpecific_val_ptr_ptr));
    netsnmp_assert(NULL != ifSpecific_val_ptr_len_ptr);


    DEBUGMSGTL(("verbose:ifTable:ifSpecific_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ifSpecific data.
     * copy (* ifSpecific_val_ptr_ptr ) data and (* ifSpecific_val_ptr_len_ptr ) from rowreq_ctx->data
     */
#ifdef IFTABLE_HAS_IFSPECIFIC
    /*
     * make sure there is enough space for ifSpecific data
     */
    if ((NULL == (*ifSpecific_val_ptr_ptr)) ||
        ((*ifSpecific_val_ptr_len_ptr) <
         (rowreq_ctx->data.ifSpecific_len *
          sizeof(rowreq_ctx->data.ifSpecific[0])))) {
        /*
         * allocate space for ifSpecific data
         */
        (*ifSpecific_val_ptr_ptr) =
            malloc(rowreq_ctx->data.ifSpecific_len *
                   sizeof(rowreq_ctx->data.ifSpecific[0]));
        if (NULL == (*ifSpecific_val_ptr_ptr)) {
            snmp_log(LOG_ERR, "could not allocate memory\n");
            return MFD_ERROR;
        }
    }
    (*ifSpecific_val_ptr_len_ptr) =
        rowreq_ctx->data.ifSpecific_len *
        sizeof(rowreq_ctx->data.ifSpecific[0]);
    memcpy((*ifSpecific_val_ptr_ptr), rowreq_ctx->data.ifSpecific,
           (*ifSpecific_val_ptr_len_ptr));
#else
    /*
     * hard coded
     */
    netsnmp_assert((*ifSpecific_val_ptr_len_ptr) > (size_t)nullOidLen);
    (*ifSpecific_val_ptr_len_ptr) = (size_t)nullOidLen;
    memcpy(*ifSpecific_val_ptr_ptr, &nullOid, (size_t)nullOidLen);
#endif

    return MFD_SUCCESS;
}                               /* ifSpecific_get */



/** @} */

#ifndef NETSNMP_NO_WRITE_SUPPORT

/**********************************************************************
 **********************************************************************
 ***
 *** Table ifTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * IF-MIB::ifTable is subid 2 of interfaces.
 * Its status is Current.
 * OID: .1.3.6.1.2.1.2.2, 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
     *                        +==============+
     *       +----------------||  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.
 *
     * Undo storage is in (* ifSpecific_val_ptr_ptr )*
 * 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
 * ifTable_allocate_data(), but may need extra
 * initialization similar to what you may have done in
 * ifTable_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 (ifTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * Undo storage is in (* ifSpecific_val_ptr_ptr )*
 * @retval MFD_ERROR   : error. set will fail.
 */
int
ifTable_undo_setup(ifTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("verbose:ifTable:ifTable_undo_setup", "called\n"));

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

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

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

    DEBUGMSGTL(("verbose:ifTable:ifTable_undo", "called\n"));

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

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

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

    DEBUGMSGTL(("verbose:ifTable:ifTable_undo_cleanup", "called\n"));

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

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

    return rc;
}                               /* ifTable_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
 * ifTable.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
ifTable_commit(ifTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;
    int             save_flags;

    DEBUGMSGTL(("verbose:ifTable:ifTable_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 ifTable 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 (save_flags & COLUMN_IFADMINSTATUS_FLAG) {
        save_flags &= ~COLUMN_IFADMINSTATUS_FLAG;       /* clear ifAdminStatus */
        /*
         * TODO:482:o: |-> commit column ifAdminStatus.
         */
        rc = netsnmp_access_interface_entry_set_admin_status(rowreq_ctx->
                                                             data.ifentry,
                                                             rowreq_ctx->
                                                             data.
                                                             ifAdminStatus);
        if (0 != rc) {
            snmp_log(LOG_ERR,
                     "ifTable column ifAdminStatus commit failed\n");
        } else {
            /*
             * set flag, in case we need to undo ifAdminStatus
             */
            rowreq_ctx->column_set_flags |= COLUMN_IFADMINSTATUS_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;
}                               /* ifTable_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
 * ifTable.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
ifTable_undo_commit(ifTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("verbose:ifTable:ifTable_undo_commit", "called\n"));

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

    /*
     * TODO:485:M: |-> Undo ifTable 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) {}
     */
    /*
     * no undo cleanup, undo entry simply freed
     */


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

    return rc;
}                               /* ifTable_undo_commit */

/*
 * TODO:440:M: Implement ifTable node value checks.
 * TODO:450:M: Implement ifTable undo functions.
 * TODO:460:M: Implement ifTable set functions.
 * TODO:480:M: Implement ifTable commit functions.
 */
/*---------------------------------------------------------------------
 * IF-MIB::ifEntry.ifAdminStatus
 * ifAdminStatus is subid 7 of ifEntry.
 * Its status is Current, and its access level is ReadWrite.
 * OID: .1.3.6.1.2.1.2.2.1.7
 * Description:
The desired state of the interface.  The testing(3) state
            indicates that no operational packets can be passed.  When a
            managed system initializes, all interfaces start with
            ifAdminStatus in the down(2) state.  As a result of either
            explicit management action or per configuration information
            retained by the managed system, ifAdminStatus is then
            changed to either the up(1) or testing(3) states (or remains
            in the down(2) state).
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 * Enum range: 2/8. Values:  up(1), down(2), testing(3)
 *
 * Its syntax is INTEGER (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ifAdminStatus_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
 * ifTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_INTEGER
 *    The value is one of  up(1), down(2), testing(3)
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
ifAdminStatus_check_value(ifTable_rowreq_ctx * rowreq_ctx,
                          u_long ifAdminStatus_val)
{
    DEBUGMSGTL(("verbose:ifTable:ifAdminStatus_check_value", "called\n"));

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

    /*
     * TODO:441:o: |-> Check for valid ifAdminStatus value.
     */
    /*
     * we don't support test
     */
    if (ifAdminStatus_val == IFADMINSTATUS_TESTING)
        return MFD_ERROR;

    return MFD_SUCCESS;         /* ifAdminStatus value not illegal */
}                               /* ifAdminStatus_check_value */

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

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

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

    return MFD_SUCCESS;
}                               /* ifAdminStatus_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 ifAdminStatus_val
 *        A long containing the new value.
 */
int
ifAdminStatus_set(ifTable_rowreq_ctx * rowreq_ctx,
                  u_long ifAdminStatus_val)
{

    DEBUGMSGTL(("verbose:ifTable:ifAdminStatus_set", "called\n"));

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

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

    return MFD_SUCCESS;
}                               /* ifAdminStatus_set */

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

    DEBUGMSGTL(("verbose:ifTable:ifAdminStatus_undo", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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


    return MFD_SUCCESS;
}                               /* ifAdminStatus_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
 * ifTable.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-ifTable if you don't have dependencies)
 */
int
ifTable_check_dependencies(ifTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("internal:ifTable:ifTable_check_dependencies",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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


#endif /* !NETSNMP_NO_WRITE_SUPPORT */

static int
_if_number_handler(netsnmp_mib_handler *handler,
                      netsnmp_handler_registration *reginfo,
                      netsnmp_agent_request_info *reqinfo,
                      netsnmp_request_info *requests)
{
    if (MODE_GET == reqinfo->mode) {
        int val = ifTable_container_size();
        snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
                                 (u_char *) &val, sizeof(val));
    } else
        netsnmp_assert("bad mode in RO handler");
    
    if (handler->next && handler->next->access_method)
        return netsnmp_call_next_handler(handler, reginfo, reqinfo,
                                         requests);
    
    return SNMP_ERR_NOERROR;
}

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