/*
 * 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-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

/*
 * 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/ipv4InterfaceTable/ipv4InterfaceTable.h"
#endif
#ifdef USING_IF_MIB_IFXTABLE_IFXTABLE_MODULE
#   include "if-mib/ifXTable/ifXTable.h"
#endif

oid             ifTable_oid[] = { IFTABLE_OID };
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
     */
    {
        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) {
            /*
             * save changed rows, if you haven't already
             */
            snmp_store(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) =
            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) =
            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) > nullOidLen);
    (*ifSpecific_val_ptr_len_ptr) = nullOidLen;
    memcpy(*ifSpecific_val_ptr_ptr, &nullOid, nullOidLen);
#endif

    return MFD_SUCCESS;
}                               /* ifSpecific_get */



/** @} */
/**********************************************************************
 **********************************************************************
 ***
 *** 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 */


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;
}

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