MFD:ifXTable:Get_Data - fenner/net-snmp-wiki-experiment GitHub Wiki
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
intifName_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;}
intifName_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
intifInMulticastPkts_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;}
intifInMulticastPkts_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
intifHCInOctets_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;}
intifHCInOctets_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