Skip to content

MFD:ifXTable:Get_Data

Bill Fenner edited this page Aug 30, 2018 · 1 revision

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

Clone this wiki locally