MFD:ifXTable:Get Data

From Net-SNMP Wiki
Jump to: navigation, search

MIBs For Dummies : ifXTable data GET

Once the correct table context has been found, the individual node get routines will be called. These are generated in the file ifXTable_data_get.c. The code generated for each node defaults to returning MFD_SKIP, which will cause Net-SNMP to skip the column for the given table context. If you compile and run the code before implementing any code in the get routines, and try to walk the ifXTable, each node's get routine will be called once for each interface. Since every function will return MFD_SKIP, snmpwalk will eventually return END OF MIB.

Implementing the get routines

We are using the same data structures that the ifTable implementation uses for the Linux kernel. I won't cover every node, as they are all very similar.

ifName_get

The ifName node is a string. First we check that the string is large enough to hold the name in our data context, allocating memory if it is not. Then the name is copied and the length variable is set.

Generated code Modified code
int
ifName_get(ifXTable_ctx * ctx, char **ifName_ptr_ptr,
           size_t * ifName_len_ptr)
{
    /** syntax-DisplayString-get.m2i not found, using generic */
   /** we should have a non-NULL pointer and enough storage */
    netsnmp_assert((NULL != ifName_ptr_ptr) && (NULL != *ifName_ptr_ptr));
    netsnmp_assert(NULL != ifName_len_ptr);

    netsnmp_assert(NULL != ctx);

    /*
     * TODO:
     * set (* ifName_ptr_ptr) and (* ifName_len_ptr) from ctx->data.
     */
    return MFD_SKIP;            /* TODO: remove this once you've set data */

    return SNMP_ERR_NOERROR;
}
int
ifName_get(ifXTable_ctx * ctx, char **ifName_ptr_ptr,
           size_t * ifName_len_ptr)
{
    /** syntax-DisplayString-get.m2i not found, using generic */
   /** we should have a non-NULL pointer and enough storage */
    netsnmp_assert((NULL != ifName_ptr_ptr) && (NULL != *ifName_ptr_ptr));
    netsnmp_assert(NULL != ifName_len_ptr);

    netsnmp_assert(NULL != ctx);

    /*
     * TODO:
     * set (* ifName_ptr_ptr) and (* ifName_len_ptr) from ctx->data.
     */
    if (*ifName_len_ptr < strnlen(ctx->data.Name,sizeof(ctx->data.Name))) {
       *ifName_ptr_ptr = malloc(strnlen(ctx->data.Name,sizeof(ctx->data.Name)));
    }
    *ifName_len_ptr = strnlen(ctx->data.Name,sizeof(ctx->data.Name));
    memcpy(*ifName_ptr_ptr, ctx->data.Name, *ifName_len_ptr);

    return SNMP_ERR_NOERROR;
}

ifInMulticastPkts_get

The ifInMulticastPkts node is a integer. However, we don't always have the data for this node. At compile time we test a macro that will be set during configure to determine if the data is available. variable is set.

Generated code Modified code
int
ifInMulticastPkts_get(ifXTable_ctx * ctx, u_long * ifInMulticastPkts_ptr)
{
    /** syntax-COUNTER-get.m2i not found, using generic */
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifInMulticastPkts_ptr);

    netsnmp_assert(NULL != ctx);

    /*
     * TODO:
     * set (* ifInMulticastPkts_ptr) from ctx->data.
     */
    return MFD_SKIP;            /* TODO: remove this once you've set data */

    /*
     * TODO:
     * value mapping
     *
     * If the values for your data type don't exactly match the
     * possible values defined by the mib, you should map them here.
     */


    return SNMP_ERR_NOERROR;
}
int
ifInMulticastPkts_get(ifXTable_ctx * ctx, u_long * ifInMulticastPkts_ptr)
{
    /** syntax-COUNTER-get.m2i not found, using generic */
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifInMulticastPkts_ptr);

    netsnmp_assert(NULL != ctx);

    /*
     * TODO:
     * set (* ifInMulticastPkts_ptr) from ctx->data.
     */
#if STRUCT_IFNET_HAS_IF_IMCASTS
    temp_ifInMulticastPkts = (u_long) ctx->data.ifnet.if_imcasts;
#else
    return MFD_SKIP;            /* TODO: remove this once you've set data */
#endif

    /*
     * TODO:
     * value mapping
     *
     * If the values for your data type don't exactly match the
     * possible values defined by the mib, you should map them here.
     */


    return SNMP_ERR_NOERROR;
}

ifHCInOctets_get

The ifHCInOctets node is a 64 bit counter. Net-SNMP uses a structure containing the high and low 32 bits for 64 bit counters. We use if_ibytes if it is available, or if_ipackets otherwise. This logic is straight from the current ifTable implementation.

Generated code Modified code
int
ifHCInOctets_get(ifXTable_ctx * ctx, U64 * ifHCInOctets_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifHCInOctets_ptr);

    /*
     * TODO:
     * get (* ifHCInOctets_ptr).low and (* ifHCInOctets_ptr).high from ctx->data.
     */


    return SNMP_ERR_NOERROR;
}
int
ifHCInOctets_get(ifXTable_ctx * ctx, U64 * ifHCInOctets_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ifHCInOctets_ptr);

    /*
     * TODO:
     * get (* ifHCInOctets_ptr).low and (* ifHCInOctets_ptr).high from ctx->data.
     */
    (*ifHCInOctets_ptr).high = 0;
#ifdef STRUCT_IFNET_HAS_IF_IBYTES
    (*ifHCInOctets_ptr).low = (u_long) ctx->data.ifnet.if_ibytes;
#else
     (*ifHCInOctets_ptr).low = (u_long) ctx->data.ifnet.if_ipackets * 308; /* XXX */
#endif


    return SNMP_ERR_NOERROR;
}