Search
j0ke.net Open Build Service
>
Projects
>
GFS
>
net-snmp
> Add-ICMP-Statistics-Tables-support.patch
Sign Up
|
Log In
Username
Password
Cancel
Overview
Repositories
Revisions
Requests
Users
Advanced
Attributes
Meta
File Add-ICMP-Statistics-Tables-support.patch of Package net-snmp (Revision 3)
Currently displaying revision
3
,
show latest
From f691d90915f55027107270245494e1d25e340e20 Mon Sep 17 00:00:00 2001 From: Mitsuru Chinen <mitch@linux.vnet.ibm.com> Date: Mon, 20 Oct 2008 16:43:13 +0900 Subject: [PATCH] Add ICMP Statistics Tables support From net-snmp patch tracker: [ 1702361 ] Add ability to retrieve /proc/net/snmp6 under linux http://sourceforge.net/tracker/index.php?func=detail&aid=1702361&group_id=12694&atid=312694 [ 1702366 ] add support for icmpStatsTable oid under linux http://sourceforge.net/tracker/index.php?func=detail&aid=1702366&group_id=12694&atid=312694 [ 1703004 ] consolidate snmp6 caching in mibII read for linux http://sourceforge.net/tracker/index.php?func=detail&aid=1703004&group_id=12694&atid=312694 [ 1715395 ] Fix the output form of icmpStatsTable on Linux http://sourceforge.net/tracker/index.php?func=detail&aid=1715395&group_id=12694&atid=312694 [ 1721096 ] [Linux] Reply icmpStatsTable with old kernel http://sourceforge.net/tracker/index.php?func=detail&aid=1721096&group_id=12694&atid=312694 [ 1823465 ] fix icmp registration and caches http://sourceforge.net/tracker/index.php?func=detail&aid=1823465&group_id=12694&atid=312694 [ 1927751 ] Update icmpMsgStatsTable, Take IV http://sourceforge.net/tracker/index.php?func=detail&aid=1927751&group_id=12694&atid=312694 Signed-off-by: Mitsuru Chinen <mitch@linux.vnet.ibm.com> --- agent/mibgroup/mibII/icmp.c | 578 +++++++++++++++++++++++++++++++++ agent/mibgroup/mibII/icmp.h | 15 + agent/mibgroup/mibII/ipv6.c | 2 +- agent/mibgroup/mibII/kernel_linux.c | 483 +++++++++++++++++++++++++--- agent/mibgroup/mibII/kernel_linux.h | 86 +++++ configure | 5 +- configure.in | 5 +- include/net-snmp/net-snmp-config.h.in | 3 + win32/net-snmp/net-snmp-config.h.in | 3 + 9 files changed, 1138 insertions(+), 42 deletions(-) diff --git a/agent/mibgroup/mibII/icmp.c b/agent/mibgroup/mibII/icmp.c index f3fbb82..50daac1 100644 --- a/agent/mibgroup/mibII/icmp.c +++ b/agent/mibgroup/mibII/icmp.c @@ -9,6 +9,13 @@ #if HAVE_NETINET_IP_ICMP_H #include <netinet/ip_icmp.h> #endif + +#ifdef NETSNMP_ENABLE_IPV6 +#if HAVE_NETINET_ICMP6_H +#include <netinet/icmp6.h> +#endif +#endif /* NETSNMP_ENABLE_IPV6 */ + #if HAVE_NETINET_ICMP_VAR_H #include <netinet/icmp_var.h> #endif @@ -60,16 +67,388 @@ perfstat_id_t ps_name; * registering underneath */ oid icmp_oid[] = { SNMP_OID_MIB2, 5 }; +oid icmp_stats_tbl_oid[] = { SNMP_OID_MIB2, 5, 29 }; +oid icmp_msg_stats_tbl_oid[] = { SNMP_OID_MIB2, 5, 30 }; #ifdef USING_MIBII_IP_MODULE extern oid ip_module_oid[]; extern int ip_module_oid_len; extern int ip_module_count; #endif +#ifdef linux +struct icmp_stats_table_entry { + __uint32_t ipVer; + __uint32_t icmpStatsInMsgs; + __uint32_t icmpStatsInErrors; + __uint32_t icmpStatsOutMsgs; + __uint32_t icmpStatsOutErrors; +}; + +struct icmp_stats_table_entry icmp_stats_table[2]; + +#define ICMP_MSG_STATS_HAS_IN 1 +#define ICMP_MSG_STATS_HAS_OUT 2 + +struct icmp_msg_stats_table_entry { + uint32_t ipVer; + uint32_t icmpMsgStatsType; + uint32_t icmpMsgStatsInPkts; + uint32_t icmpMsgStatsOutPkts; + int flags; +}; + +#define ICMP_MSG_STATS_IPV4_COUNT 11 + +#ifdef NETSNMP_ENABLE_IPV6 +#define ICMP_MSG_STATS_IPV6_COUNT 14 +#else +#define ICMP_MSG_STATS_IPV6_COUNT 0 +#endif /* NETSNMP_ENABLE_IPV6 */ + +struct icmp_msg_stats_table_entry icmp_msg_stats_table[ICMP_MSG_STATS_IPV4_COUNT + ICMP_MSG_STATS_IPV6_COUNT]; + +int +icmp_stats_load(netsnmp_cache *cache, void *vmagic) +{ + + /* + * note don't bother using the passed in cache + * and vmagic pointers. They are useless as they + * currently point to the icmp system stats cache + * since I see little point in registering another + * cache for this table. Its not really needed + */ + + int i; + struct icmp_mib v4icmp; + struct icmp6_mib v6icmp; + for(i=0;i<2;i++) { + switch(i) { + case 0: + linux_read_icmp_stat(&v4icmp); + icmp_stats_table[i].icmpStatsInMsgs = v4icmp.icmpInMsgs; + icmp_stats_table[i].icmpStatsInErrors = v4icmp.icmpInErrors; + icmp_stats_table[i].icmpStatsOutMsgs = v4icmp.icmpOutMsgs; + icmp_stats_table[i].icmpStatsOutErrors = v4icmp.icmpOutErrors; + break; + default: + memset(&icmp_stats_table[i],0, + sizeof(struct icmp_stats_table_entry)); + linux_read_icmp6_stat(&v6icmp); + icmp_stats_table[i].icmpStatsInMsgs = v6icmp.icmp6InMsgs; + icmp_stats_table[i].icmpStatsInErrors = v6icmp.icmp6InErrors; + icmp_stats_table[i].icmpStatsOutMsgs = v6icmp.icmp6OutMsgs; + icmp_stats_table[i].icmpStatsOutErrors = v6icmp.icmp6OutDestUnreachs + + v6icmp.icmp6OutPktTooBigs + v6icmp.icmp6OutTimeExcds + + v6icmp.icmp6OutParmProblems; + break; + } + icmp_stats_table[i].ipVer=i+1; + } + + return 0; +} + +int +icmp_msg_stats_load(netsnmp_cache *cache, void *vmagic) +{ + struct icmp_mib v4icmp; + struct icmp4_msg_mib v4icmpmsg; + struct icmp6_mib v6icmp; + struct icmp6_msg_mib v6icmpmsg; + int i, j, k, flag, inc; + + memset(&icmp_msg_stats_table, 0, sizeof(icmp_msg_stats_table)); + + i = 0; + flag = 0; + k = 0; + inc = 0; + linux_read_icmp_msg_stat(&v4icmp, &v4icmpmsg, &flag); + if (flag) { + while (254 != k) { + if (v4icmpmsg.vals[k].InType) { + icmp_msg_stats_table[i].ipVer = 1; + icmp_msg_stats_table[i].icmpMsgStatsType = k; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmpmsg.vals[k].InType; + icmp_msg_stats_table[i].flags = icmp_msg_stats_table[i].flags | ICMP_MSG_STATS_HAS_IN; + inc = 1; /* Set this if we found a valid entry */ + } + if (v4icmpmsg.vals[k].OutType) { + icmp_msg_stats_table[i].ipVer = 1; + icmp_msg_stats_table[i].icmpMsgStatsType = k; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmpmsg.vals[k].OutType; + icmp_msg_stats_table[i].flags = icmp_msg_stats_table[i].flags | ICMP_MSG_STATS_HAS_OUT; + inc = 1; /* Set this if we found a valid entry */ + } + if (inc) { + i++; + inc = 0; + } + k++; + } + } else { + icmp_msg_stats_table[i].icmpMsgStatsType = ICMP_ECHOREPLY; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmp.icmpInEchoReps; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmp.icmpOutEchoReps; + i++; + + icmp_msg_stats_table[i].icmpMsgStatsType = ICMP_DEST_UNREACH; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmp.icmpInDestUnreachs; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmp.icmpOutDestUnreachs; + i++; + + icmp_msg_stats_table[i].icmpMsgStatsType = ICMP_SOURCE_QUENCH; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmp.icmpInSrcQuenchs; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmp.icmpOutSrcQuenchs; + i++; + + icmp_msg_stats_table[i].icmpMsgStatsType = ICMP_REDIRECT; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmp.icmpInRedirects; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmp.icmpOutRedirects; + i++; + + icmp_msg_stats_table[i].icmpMsgStatsType = ICMP_ECHO; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmp.icmpInEchos; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmp.icmpOutEchos; + i++; + + icmp_msg_stats_table[i].icmpMsgStatsType = ICMP_TIME_EXCEEDED; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmp.icmpInTimeExcds; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmp.icmpOutTimeExcds; + i++; + + icmp_msg_stats_table[i].icmpMsgStatsType = ICMP_PARAMETERPROB; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmp.icmpInParmProbs; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmp.icmpOutParmProbs; + i++; + + icmp_msg_stats_table[i].icmpMsgStatsType = ICMP_TIMESTAMP; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmp.icmpInTimestamps; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmp.icmpOutTimestamps; + i++; + + icmp_msg_stats_table[i].icmpMsgStatsType = ICMP_TIMESTAMPREPLY; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmp.icmpInTimestampReps; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmp.icmpOutTimestampReps; + i++; + + icmp_msg_stats_table[i].icmpMsgStatsType = ICMP_ADDRESS; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmp.icmpInAddrMasks; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmp.icmpOutAddrMasks; + i++; + + icmp_msg_stats_table[i].icmpMsgStatsType = ICMP_ADDRESSREPLY; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v4icmp.icmpInAddrMaskReps; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v4icmp.icmpOutAddrMaskReps; + i++; + + /* set the IP version and default flags */ + for (j = 0; j < ICMP_MSG_STATS_IPV4_COUNT; j++) { + icmp_msg_stats_table[j].ipVer = 1; + icmp_msg_stats_table[j].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT; + } + } + +#ifdef NETSNMP_ENABLE_IPV6 + flag = 0; + k = 0; + inc = 0; + linux_read_icmp6_msg_stat(&v6icmp, &v6icmpmsg, &flag); + if (flag) { + while (254 != k) { + if (v6icmpmsg.vals[k].InType) { + icmp_msg_stats_table[i].ipVer = 2; + icmp_msg_stats_table[i].icmpMsgStatsType = k; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmpmsg.vals[k].InType; + icmp_msg_stats_table[i].flags = icmp_msg_stats_table[i].flags | ICMP_MSG_STATS_HAS_IN; + inc = 1; /* Set this if we found a valid entry */ + } + if (v6icmpmsg.vals[k].OutType) { + icmp_msg_stats_table[i].ipVer = 2; + icmp_msg_stats_table[i].icmpMsgStatsType = k; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmpmsg.vals[k].OutType; + icmp_msg_stats_table[i].flags = icmp_msg_stats_table[i].flags | ICMP_MSG_STATS_HAS_OUT; + inc = 1; /* Set this if we found a valid entry */ + } + if (inc) { + i++; + inc = 0; + } + k++; + } + } else { + icmp_msg_stats_table[i].icmpMsgStatsType = ICMP6_DST_UNREACH; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InDestUnreachs; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmp.icmp6OutDestUnreachs; + i++; + + icmp_msg_stats_table[i].icmpMsgStatsType = ICMP6_PACKET_TOO_BIG; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InPktTooBigs; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmp.icmp6OutPktTooBigs; + i++; + + icmp_msg_stats_table[i].icmpMsgStatsType = ICMP6_TIME_EXCEEDED; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InTimeExcds; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmp.icmp6OutTimeExcds; + i++; + + icmp_msg_stats_table[i].icmpMsgStatsType = ICMP6_PARAM_PROB; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InParmProblems; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmp.icmp6OutParmProblems; + i++; + + icmp_msg_stats_table[i].icmpMsgStatsType = ICMP6_ECHO_REQUEST; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InEchos; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = 0; + icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN; + i++; + + icmp_msg_stats_table[i].icmpMsgStatsType = ICMP6_ECHO_REPLY; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InEchoReplies; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmp.icmp6OutEchoReplies; + i++; + + icmp_msg_stats_table[i].icmpMsgStatsType = MLD_LISTENER_QUERY; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InGroupMembQueries; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = 0; + icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN; + i++; + icmp_msg_stats_table[i].icmpMsgStatsType = MLD_LISTENER_REPORT; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InGroupMembResponses; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmp.icmp6OutGroupMembResponses; + i++; + + icmp_msg_stats_table[i].icmpMsgStatsType = MLD_LISTENER_REDUCTION; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InGroupMembReductions; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmp.icmp6OutGroupMembReductions; + i++; + + icmp_msg_stats_table[i].icmpMsgStatsType = ND_ROUTER_SOLICIT; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InRouterSolicits; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmp.icmp6OutRouterSolicits; + i++; + + icmp_msg_stats_table[i].icmpMsgStatsType = ND_ROUTER_ADVERT; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InRouterAdvertisements; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = 0; + icmp_msg_stats_table[i].flags = ICMP_MSG_STATS_HAS_IN; + i++; + + icmp_msg_stats_table[i].icmpMsgStatsType = ND_NEIGHBOR_SOLICIT; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InNeighborSolicits; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmp.icmp6OutNeighborSolicits; + i++; + + icmp_msg_stats_table[i].icmpMsgStatsType = ND_NEIGHBOR_ADVERT; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InNeighborAdvertisements; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmp.icmp6OutNeighborAdvertisements; + i++; + + icmp_msg_stats_table[i].icmpMsgStatsType = ND_REDIRECT; + icmp_msg_stats_table[i].icmpMsgStatsInPkts = v6icmp.icmp6InRedirects; + icmp_msg_stats_table[i].icmpMsgStatsOutPkts = v6icmp.icmp6OutRedirects; + + for (j = 0; j < ICMP_MSG_STATS_IPV6_COUNT; j++) { + icmp_msg_stats_table[ICMP_MSG_STATS_IPV4_COUNT + j].ipVer = 2; + icmp_msg_stats_table[ICMP_MSG_STATS_IPV4_COUNT + j].flags = ICMP_MSG_STATS_HAS_IN | ICMP_MSG_STATS_HAS_OUT; + } +#endif /* NETSNMP_ENABLE_IPV6 */ + } + return 0; +} + +netsnmp_variable_list * +icmp_stats_next_entry( void **loop_context, + void **data_context, + netsnmp_variable_list *index, + netsnmp_iterator_info *data) +{ + int i = (int)(*loop_context); + netsnmp_variable_list *idx = index; + + if(i > 1) + return NULL; + + + /* + *set IP version + */ + snmp_set_var_typed_value(idx, ASN_INTEGER, (u_char *)&icmp_stats_table[i].ipVer, + sizeof(__uint32_t)); + idx = idx->next_variable; + + *data_context = &icmp_stats_table[i]; + + *loop_context = (void *)(++i); + + return index; +} + + +netsnmp_variable_list * +icmp_stats_first_entry( void **loop_context, + void **data_context, + netsnmp_variable_list *index, + netsnmp_iterator_info *data) +{ + + *loop_context = 0; + *data_context = NULL; + return icmp_stats_next_entry(loop_context, data_context, index, data); +} + +netsnmp_variable_list * +icmp_msg_stats_next_entry(void **loop_context, + void **data_context, + netsnmp_variable_list *index, + netsnmp_iterator_info *data) +{ + int i = (int)(*loop_context); + netsnmp_variable_list *idx = index; + + if(i >= ICMP_MSG_STATS_IPV4_COUNT + ICMP_MSG_STATS_IPV6_COUNT) + return NULL; + + /* set IP version */ + snmp_set_var_typed_value(idx, ASN_INTEGER, + (u_char *)&icmp_msg_stats_table[i].ipVer, + sizeof(uint32_t)); + + /* set packet type */ + idx = idx->next_variable; + snmp_set_var_typed_value(idx, ASN_INTEGER, + (u_char *)&icmp_msg_stats_table[i].icmpMsgStatsType, + sizeof(uint32_t)); + + *data_context = &icmp_msg_stats_table[i]; + *loop_context = (void *)(++i); + + return index; +} + + +netsnmp_variable_list * +icmp_msg_stats_first_entry(void **loop_context, + void **data_context, + netsnmp_variable_list *index, + netsnmp_iterator_info *data) +{ + *loop_context = 0; + *data_context = NULL; + return icmp_msg_stats_next_entry(loop_context, data_context, index, data); +} +#endif + void init_icmp(void) { netsnmp_handler_registration *reginfo; + netsnmp_handler_registration *msg_stats_reginfo; + netsnmp_iterator_info *iinfo; + netsnmp_iterator_info *msg_stats_iinfo; + netsnmp_table_registration_info *table_info; + netsnmp_table_registration_info *msg_stats_table_info; /* * register ourselves with the agent as a group of scalars... @@ -89,6 +468,68 @@ init_icmp(void) icmp_oid, OID_LENGTH(icmp_oid))); #endif +#ifdef linux + + /* register icmpStatsTable */ + reginfo = netsnmp_create_handler_registration("icmpStatsTable", + icmp_stats_table_handler, icmp_stats_tbl_oid, + OID_LENGTH(icmp_stats_tbl_oid), HANDLER_CAN_RONLY); + + table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); + if (!table_info) { + return; + } + + netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, 0); + table_info->min_column = ICMP_STAT_INMSG; + table_info->max_column = ICMP_STAT_OUTERR; + + + iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); + if (!iinfo) { + return; + } + iinfo->get_first_data_point = icmp_stats_first_entry; + iinfo->get_next_data_point = icmp_stats_next_entry; + iinfo->table_reginfo = table_info; + + netsnmp_register_table_iterator(reginfo, iinfo); + + /* register icmpMsgStatsTable */ + msg_stats_reginfo = netsnmp_create_handler_registration("icmpMsgStatsTable", + icmp_msg_stats_table_handler, icmp_msg_stats_tbl_oid, + OID_LENGTH(icmp_msg_stats_tbl_oid), HANDLER_CAN_RONLY); + + msg_stats_table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); + if (!msg_stats_table_info) { + return; + } + + netsnmp_table_helper_add_indexes(msg_stats_table_info, ASN_INTEGER, ASN_INTEGER, 0); + msg_stats_table_info->min_column = ICMP_MSG_STAT_IN_PKTS; + msg_stats_table_info->max_column = ICMP_MSG_STAT_OUT_PKTS; + + msg_stats_iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info); + if (!msg_stats_iinfo) { + return; + } + msg_stats_iinfo->get_first_data_point = icmp_msg_stats_first_entry; + msg_stats_iinfo->get_next_data_point = icmp_msg_stats_next_entry; + msg_stats_iinfo->table_reginfo = msg_stats_table_info; + + netsnmp_register_table_iterator(msg_stats_reginfo, msg_stats_iinfo); + netsnmp_inject_handler( msg_stats_reginfo, + netsnmp_get_cache_handler(ICMP_STATS_CACHE_TIMEOUT, + icmp_load, icmp_free, + icmp_msg_stats_tbl_oid, OID_LENGTH(icmp_msg_stats_tbl_oid))); +#ifndef hpux11 + netsnmp_inject_handler( reginfo, + netsnmp_get_cache_handler(ICMP_STATS_CACHE_TIMEOUT, + icmp_load, icmp_free, + icmp_stats_tbl_oid, OID_LENGTH(icmp_stats_tbl_oid))); +#endif /* ! hpux11 */ +#endif /* linux */ + #ifdef USING_MIBII_IP_MODULE if (++ip_module_count == 2) REGISTER_SYSOR_TABLE(ip_module_oid, ip_module_oid_len, @@ -550,6 +991,141 @@ icmp_handler(netsnmp_mib_handler *handler, return SNMP_ERR_NOERROR; } +int +icmp_msg_stats_table_handler(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests) +{ + netsnmp_request_info *request; + netsnmp_variable_list *requestvb; + netsnmp_table_request_info *table_info; + struct icmp_msg_stats_table_entry *entry; + oid subid; + + switch (reqinfo->mode) { + case MODE_GET: + for (request = requests; request; request = request->next) { + requestvb = request->requestvb; + entry = (struct icmp_msg_stats_table_entry *)netsnmp_extract_iterator_context(request); + if (!entry) + continue; + table_info = netsnmp_extract_table_info(request); + subid = table_info->colnum; + + switch (subid) { + case ICMP_MSG_STAT_IN_PKTS: + if (entry->flags & ICMP_MSG_STATS_HAS_IN) { + snmp_set_var_typed_value(requestvb, ASN_COUNTER, + (u_char *)&entry->icmpMsgStatsInPkts, sizeof(uint32_t)); + } else { + requestvb->type = SNMP_NOSUCHINSTANCE; + } + break; + case ICMP_MSG_STAT_OUT_PKTS: + if (entry->flags & ICMP_MSG_STATS_HAS_OUT) { + snmp_set_var_typed_value(requestvb, ASN_COUNTER, + (u_char *)&entry->icmpMsgStatsOutPkts, sizeof(uint32_t)); + } else { + requestvb->type = SNMP_NOSUCHINSTANCE; + } + break; + default: + snmp_log(LOG_WARNING, "mibII/icmpMsgStatsTable: Unrecognised column (%d)\n",(int)subid); + } + } + break; + case MODE_GETNEXT: + case MODE_GETBULK: + case MODE_SET_RESERVE1: + case MODE_SET_RESERVE2: + case MODE_SET_ACTION: + case MODE_SET_COMMIT: + case MODE_SET_FREE: + case MODE_SET_UNDO: + snmp_log(LOG_WARNING, "mibII/icmpStatsTable: Unsupported mode (%d)\n", + reqinfo->mode); + break; + default: + snmp_log(LOG_WARNING, "mibII/icmpStatsTable: Unrecognised mode (%d)\n", + reqinfo->mode); + break; + + } + + return SNMP_ERR_NOERROR; +} + +int +icmp_stats_table_handler(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests) +{ + netsnmp_request_info *request; + netsnmp_variable_list *requestvb; + netsnmp_table_request_info *table_info; + struct icmp_stats_table_entry *entry; + oid subid; +#ifndef hpux11 + if (!netsnmp_cache_is_valid(reqinfo, reginfo->handlerName)) { + netsnmp_assert(!"cache == valid"); /* always false */ + icmp_load( NULL, NULL ); /* XXX - check for failure */ + } +#endif + + switch (reqinfo->mode) { + case MODE_GET: + for (request=requests; request; request=request->next) { + requestvb = request->requestvb; + entry = (struct icmp_stats_table_entry *)netsnmp_extract_iterator_context(request); + if (!entry) + continue; + table_info = netsnmp_extract_table_info(request); + subid = table_info->colnum; + + switch (subid) { + case ICMP_STAT_INMSG: + snmp_set_var_typed_value(requestvb, ASN_COUNTER, + (u_char *)&entry->icmpStatsInMsgs, sizeof(__uint32_t)); + break; + case ICMP_STAT_INERR: + snmp_set_var_typed_value(requestvb, ASN_COUNTER, + (u_char *)&entry->icmpStatsInErrors, sizeof(__uint32_t)); + break; + case ICMP_STAT_OUTMSG: + snmp_set_var_typed_value(requestvb, ASN_COUNTER, + (u_char *)&entry->icmpStatsOutMsgs, sizeof(__uint32_t)); + break; + case ICMP_STAT_OUTERR: + snmp_set_var_typed_value(requestvb, ASN_COUNTER, + (u_char *)&entry->icmpStatsOutErrors, sizeof(__uint32_t)); + break; + default: + snmp_log(LOG_WARNING, "mibII/icmpStatsTable: Unrecognised column (%d)\n",(int)subid); + } + } + break; + case MODE_GETNEXT: + case MODE_GETBULK: + case MODE_SET_RESERVE1: + case MODE_SET_RESERVE2: + case MODE_SET_ACTION: + case MODE_SET_COMMIT: + case MODE_SET_FREE: + case MODE_SET_UNDO: + snmp_log(LOG_WARNING, "mibII/icmpStatsTable: Unsupported mode (%d)\n", + reqinfo->mode); + break; + default: + snmp_log(LOG_WARNING, "mibII/icmpStatsTable: Unrecognised mode (%d)\n", + reqinfo->mode); + break; + + } + + return SNMP_ERR_NOERROR; +} /********************* * @@ -680,6 +1256,8 @@ icmp_load(netsnmp_cache *cache, void *vmagic) } else { DEBUGMSGTL(("mibII/icmp", "Loaded ICMP Group (linux)\n")); } + icmp_stats_load(cache, vmagic); + icmp_msg_stats_load(cache, vmagic); return ret_value; } #elif defined(solaris2) diff --git a/agent/mibgroup/mibII/icmp.h b/agent/mibgroup/mibII/icmp.h index 7417639..4a780ac 100644 --- a/agent/mibgroup/mibII/icmp.h +++ b/agent/mibgroup/mibII/icmp.h @@ -12,6 +12,8 @@ config_arch_require(linux, mibII/kernel_linux) extern void init_icmp(void); extern Netsnmp_Node_Handler icmp_handler; +extern Netsnmp_Node_Handler icmp_stats_table_handler; +extern Netsnmp_Node_Handler icmp_msg_stats_table_handler; extern NetsnmpCacheLoad icmp_load; extern NetsnmpCacheFree icmp_free; @@ -42,4 +44,17 @@ extern NetsnmpCacheFree icmp_free; #define ICMPOUTADDRMASKS 25 #define ICMPOUTADDRMASKREPS 26 +#define ICMPSTATSTABLE 29 +#define ICMP_STAT_IPVER 1 +#define ICMP_STAT_INMSG 2 +#define ICMP_STAT_INERR 3 +#define ICMP_STAT_OUTMSG 4 +#define ICMP_STAT_OUTERR 5 + +#define ICMPMSGSTATSTABLE 30 +#define ICMP_MSG_STAT_IPVER 1 +#define ICMP_MSG_STAT_TYPE 2 +#define ICMP_MSG_STAT_IN_PKTS 3 +#define ICMP_MSG_STAT_OUT_PKTS 4 + #endif /* _MIBGROUP_ICMP_H */ diff --git a/agent/mibgroup/mibII/ipv6.c b/agent/mibgroup/mibII/ipv6.c index 1e24989..ac64ad5 100644 --- a/agent/mibgroup/mibII/ipv6.c +++ b/agent/mibgroup/mibII/ipv6.c @@ -1851,7 +1851,7 @@ linux_read_ip6_stat_ulong(const char *file) return value; } -void +static void linux_read_ip6_stat(struct ip6_mib *ip6stat) { if (!ip6stat) diff --git a/agent/mibgroup/mibII/kernel_linux.c b/agent/mibgroup/mibII/kernel_linux.c index bb6f867..7b47d9c 100644 --- a/agent/mibgroup/mibII/kernel_linux.c +++ b/agent/mibgroup/mibII/kernel_linux.c @@ -16,43 +16,109 @@ #if HAVE_SYS_PARAM_H #include <sys/param.h> #endif +#include <errno.h> #include "kernel_linux.h" struct ip_mib cached_ip_mib; +struct ip6_mib cached_ip6_mib; struct icmp_mib cached_icmp_mib; +struct icmp6_mib cached_icmp6_mib; +struct icmp4_msg_mib cached_icmp4_msg_mib; +struct tcp_mib cached_tcp_mib; struct tcp_mib cached_tcp_mib; struct udp_mib cached_udp_mib; +struct udp6_mib cached_udp6_mib; #define IP_STATS_LINE "Ip: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu" #define ICMP_STATS_LINE "Icmp: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu" +#define ICMP_MSG_STATS_LINE "IcmpMsg: " #define TCP_STATS_LINE "Tcp: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu" #define UDP_STATS_LINE "Udp: %lu %lu %lu %lu" +#define IP6_STATS_LINE "Ip6" +#define ICMP6_STATS_LINE "Icmp6" #define UDP6_STATS_LINE "Udp6" #define IP_STATS_PREFIX_LEN 4 #define ICMP_STATS_PREFIX_LEN 6 +#define ICMP_MSG_STATS_PREFIX_LEN 9 #define TCP_STATS_PREFIX_LEN 5 #define UDP_STATS_PREFIX_LEN 5 +#define IP6_STATS_PREFIX_LEN 3 +#define ICMP6_STATS_PREFIX_LEN 5 #define UDP6_STATS_PREFIX_LEN 4 +int +decode_icmp_msg(char *line, char *data, struct icmp4_msg_mib *msg) +{ + char *token, *saveptr, *lineptr, *saveptr1, *dataptr, *delim = NULL; + char line_cpy[1024]; + char data_cpy[1024]; + long index; + + if(data == NULL) + return -1; + + /* + * Since we are using strtok, there is a possiblity of the orginal data + * getting modified. So we take a local copy for this purpose even though + * its expensive. + */ + strncpy(line_cpy, line, sizeof(line_cpy)); + strncpy(data_cpy, data, sizeof(data_cpy)); + + lineptr = line_cpy; + dataptr = data_cpy; + saveptr1 = NULL; + while (1) { + if(NULL == (token = strtok_r(lineptr, " ", &saveptr))) + break; + lineptr = NULL; + errno = 0; + if (0 == strncmp(strsep(&token, "e"), "OutTyp", 6)) { + index = strtol(token, &delim, 0); + if (ERANGE == errno) { + continue; + } else if (index > LONG_MAX) { + continue; + } else if (index < LONG_MIN) { + continue; + } + if (NULL == (token = strtok_r(dataptr, " ", &saveptr1))) + break; + dataptr = NULL; + msg->vals[index].OutType = atoi(token); + } else { + index = strtol(token, &delim, 0); + if (ERANGE == errno) { + continue; + } else if (index > LONG_MAX) { + continue; + } else if (index < LONG_MIN) { + continue; + } + if(NULL == (token = strtok_r(dataptr, " ", &saveptr1))) + break; + dataptr = NULL; + msg->vals[index].InType = atoi(token); + } + } + return 0; +} int linux_read_mibII_stats(void) { FILE *in = fopen("/proc/net/snmp", "r"); -#ifdef NETSNMP_ENABLE_IPV6 - FILE *in6; - unsigned long value; -#endif - char line[1024]; - + char line[1024], data[1024]; + int ret = 0; if (!in) { DEBUGMSGTL(("mibII/kernel_linux","Unable to open /proc/net/snmp")); return -1; } - + memset(line, '\0', sizeof(line)); + memset(data, '\0', sizeof(data)); while (line == fgets(line, sizeof(line), in)) { if (!strncmp(line, IP_STATS_LINE, IP_STATS_PREFIX_LEN)) { sscanf(line, IP_STATS_LINE, @@ -104,6 +170,19 @@ linux_read_mibII_stats(void) &cached_icmp_mib.icmpOutTimestampReps, &cached_icmp_mib.icmpOutAddrMasks, &cached_icmp_mib.icmpOutAddrMaskReps); + } else if (!strncmp(line, ICMP_MSG_STATS_LINE, ICMP_MSG_STATS_PREFIX_LEN)) { + /* + * Note: We have to do this differently from other stats as the + * counters to this stats are dynamic. So we will not know the + * number of counters at a given time. + */ + fgets(data, sizeof(data), in); + if(decode_icmp_msg(line + ICMP_MSG_STATS_PREFIX_LEN, + data + ICMP_MSG_STATS_PREFIX_LEN, + &cached_icmp4_msg_mib) < 0) { + continue; + } + ret = 1; } else if (!strncmp(line, TCP_STATS_LINE, TCP_STATS_PREFIX_LEN)) { int ret = sscanf(line, TCP_STATS_LINE, &cached_tcp_mib.tcpRtoAlgorithm, @@ -132,35 +211,6 @@ linux_read_mibII_stats(void) } fclose(in); -#ifdef NETSNMP_ENABLE_IPV6 - in6 = fopen("/proc/net/snmp6", "r"); - if (in6) { - - while (line == fgets(line, sizeof(line), in6)) { - - if (('U' != line[0]) || - (0 != strncmp(line, UDP6_STATS_LINE, UDP6_STATS_PREFIX_LEN))) - continue; - - sscanf(line, "%*s %lu" , &value); - - if ('O' == line[4]) /* Udp6OutDatagrams */ - cached_udp_mib.udpOutDatagrams += value; - else if ('N' == line[4]) /* Udp6NoPorts */ - cached_udp_mib.udpNoPorts += value; - else if ('D' == line[6]) /* Udp6InDatagrams */ - cached_udp_mib.udpInDatagrams += value; - else if ('E' == line[6]) /* Udp6InErrors */ - cached_udp_mib.udpInErrors += value; - - } - fclose(in6); - } else { - DEBUGMSGTL(("mibII/kernel_linux","Unable to open /proc/net/snmp6")); - } - -#endif - /* * Tweak illegal values: * @@ -176,7 +226,8 @@ linux_read_mibII_stats(void) */ if (!cached_tcp_mib.tcpRtoAlgorithm) cached_tcp_mib.tcpRtoAlgorithm = 1; - return 0; + + return ret; } int @@ -189,18 +240,305 @@ linux_read_ip_stat(struct ip_mib *ipstat) return 0; } +int linux_read_ip6_stat( struct ip6_mib *ip6stat) +{ +#ifdef NETSNMP_ENABLE_IPV6 + FILE *in; + char line[1024]; + unsigned long stats; + char *endp; + int match; +#endif + + memset((char *) ip6stat, (0), sizeof(*ip6stat)); + +#ifdef NETSNMP_ENABLE_IPV6 + DEBUGMSGTL(("mibII/kernel_linux/ip6stats", + "Reading /proc/net/snmp6 stats\n")); + if (NULL == (in = fopen("/proc/net/snmp6", "r"))) { + DEBUGMSGTL(("mibII/kernel_linux/ip6stats", + "Failed to open /proc/net/snmp6\n")); + return -1; + } + + while (NULL != fgets(line, sizeof(line), in)) { + if (0 != strncmp(line, IP6_STATS_LINE, IP6_STATS_PREFIX_LEN)) + continue; + + if (1 != sscanf(line, "%*s %lu", &stats)) + continue; + + endp = strchr(line, ' '); + *endp = '\0'; + DEBUGMSGTL(("mibII/kernel_linux/ip6stats", "Find tag: %s\n", line)); + + match = 1; + if (0 == strncmp(line + 3, "In", 2)) { /* In */ + if (0 == strcmp(line + 5, "AddrErrors")) { + cached_ip6_mib.ip6InAddrErrors = stats; + } else if (0 == strcmp(line + 5, "Delivers")) { + cached_ip6_mib.ip6InDelivers = stats; + } else if (0 == strcmp(line + 5, "Discards")) { + cached_ip6_mib.ip6InDiscards = stats; + } else if (0 == strcmp(line + 5, "HdrErrors")) { + cached_ip6_mib.ip6InHdrErrors = stats; + } else if (0 == strcmp(line + 5, "McastPkts")) { + cached_ip6_mib.ip6InMcastPkts = stats; + } else if (0 == strcmp(line + 5, "NoRoutes")) { + cached_ip6_mib.ip6InNoRoutes = stats; + } else if (0 == strcmp(line + 5, "Receives")) { + cached_ip6_mib.ip6InReceives = stats; + } else if (0 == strcmp(line + 5, "TruncatedPkts")) { + cached_ip6_mib.ip6InTruncatedPkts = stats; + } else if (0 == strcmp(line + 5, "TooBigErrors")) { + cached_ip6_mib.ip6InTooBigErrors = stats; + } else if (0 == strcmp(line + 5, "UnknownProtos")) { + cached_ip6_mib.ip6InUnknownProtos = stats; + } else { + match = 0; + } + } else if (0 == strncmp(line + 3, "Out", 3)) { /* Out */ + if (0 == strcmp(line + 6, "Discards")) { + cached_ip6_mib.ip6OutDiscards = stats; + } else if (0 == strcmp(line + 6, "ForwDatagrams")) { + cached_ip6_mib.ip6OutForwDatagrams = stats; + } else if (0 == strcmp(line + 6, "McastPkts")) { + cached_ip6_mib.ip6OutMcastPkts = stats; + } else if (0 == strcmp(line + 6, "NoRoutes")) { + cached_ip6_mib.ip6OutNoRoutes = stats; + } else if (0 == strcmp(line + 6, "Requests")) { + cached_ip6_mib.ip6OutRequests = stats; + } else { + match = 0; + } + } else if (0 == strncmp(line + 3, "Reasm", 5)) { /* Reasm */ + if (0 == strcmp(line + 8, "Fails")) { + cached_ip6_mib.ip6ReasmFails = stats; + } else if (0 == strcmp(line + 8, "OKs")) { + cached_ip6_mib.ip6ReasmOKs = stats; + } else if (0 == strcmp(line + 8, "Reqds")) { + cached_ip6_mib.ip6ReasmReqds = stats; + } else if (0 == strcmp(line + 8, "Timeout")) { + cached_ip6_mib.ip6ReasmTimeout = stats; + } else { + match = 0; + } + } else if (0 == strncmp(line + 3, "Frag", 4)) { /* Frag */ + if (0 == strcmp(line + 7, "Creates")) { + cached_ip6_mib.ip6FragCreates = stats; + } else if (0 == strcmp(line + 7, "Fails")) { + cached_ip6_mib.ip6FragFails = stats; + } else if (0 == strcmp(line + 7, "OKs")) { + cached_ip6_mib.ip6FragOKs = stats; + } else { + match = 0; + } + } else { + match = 0; + } + + if(!match) + DEBUGMSGTL(("mibII/kernel_linux/ip6stats", + "%s is an unknown tag\n", line)); + } + + fclose(in); +#endif + + memcpy((char *) ip6stat, (char *) &cached_ip6_mib, sizeof(*ip6stat)); + return 0; +} + +int +linux_read_icmp_msg_stat(struct icmp_mib *icmpstat, + struct icmp4_msg_mib *icmpmsgstat, + int *flag) +{ + int ret; + + memset(icmpstat, 0, sizeof(*icmpstat)); + memset(icmpmsgstat, 0, sizeof(*icmpmsgstat)); + + if ((ret = linux_read_mibII_stats()) == -1) { + return -1; + } else if (ret) { + memcpy(icmpmsgstat, &cached_icmp4_msg_mib, sizeof(*icmpmsgstat)); + *flag = 1; /* We have a valid icmpmsg */ + } + + memcpy(icmpstat, &cached_icmp_mib, sizeof(*icmpstat)); + return 0; +} + + + +int +linux_read_icmp6_parse(struct icmp6_mib *icmp6stat, + struct icmp6_msg_mib *icmp6msgstat, + int *support) +{ +#ifdef NETSNMP_ENABLE_IPV6 + FILE *in; + char line[1024]; + char name[255]; + unsigned long stats; + char *endp ,*token, *vals; + int match; +#endif + + memset(icmp6stat, 0, sizeof(*icmp6stat)); + if (NULL != icmp6msgstat) + memset(icmp6msgstat, 0, sizeof(*icmp6msgstat)); + +#ifdef NETSNMP_ENABLE_IPV6 + DEBUGMSGTL(("mibII/kernel_linux/icmp6stats", + "Reading /proc/net/snmp6 stats\n")); + if (NULL == (in = fopen("/proc/net/snmp6", "r"))) { + DEBUGMSGTL(("mibII/kernel_linux/icmp6stats", + "Failed to open /proc/net/snmp6\n")); + return -1; + } + + while (NULL != fgets(line, sizeof(line), in)) { + if (0 != strncmp(line, ICMP6_STATS_LINE, ICMP6_STATS_PREFIX_LEN)) + continue; + + if (2 != sscanf(line, "%s %lu", name, &stats)) + continue; + + endp = strchr(line, ' '); + *endp = '\0'; + DEBUGMSGTL(("mibII/kernel_linux/icmp6stats", "Find tag: %s\n", line)); + + vals = name; + if (NULL != icmp6msgstat) { + if (0 == strncmp(name, "Icmp6OutType", 12)) { + token = strsep(&vals, "e"); + icmp6msgstat->vals[atoi(vals)].OutType = stats; + *support = 1; + continue; + } else if (0 == strncmp(name, "Icmp6InType", 11)) { + token = strsep(&vals, "e"); + icmp6msgstat->vals[atoi(vals)].InType = stats; + *support = 1; + continue; + } + } + + match = 1; + if (0 == strncmp(line + 5, "In", 2)) { /* In */ + if (0 == strcmp(line + 7, "DestUnreachs")) { + cached_icmp6_mib.icmp6InDestUnreachs = stats; + } else if (0 == strcmp(line + 7, "Echos")) { + cached_icmp6_mib.icmp6InEchos = stats; + } else if (0 == strcmp(line + 7, "EchoReplies")) { + cached_icmp6_mib.icmp6InEchoReplies = stats; + } else if (0 == strcmp(line + 7, "Errors")) { + cached_icmp6_mib.icmp6InErrors = stats; + } else if (0 == strcmp(line + 7, "GroupMembQueries")) { + cached_icmp6_mib.icmp6InGroupMembQueries = stats; + } else if (0 == strcmp(line + 7, "GroupMembReductions")) { + cached_icmp6_mib.icmp6InGroupMembReductions = stats; + } else if (0 == strcmp(line + 7, "GroupMembResponses")) { + cached_icmp6_mib.icmp6InGroupMembResponses = stats; + } else if (0 == strcmp(line + 7, "Msgs")) { + cached_icmp6_mib.icmp6InMsgs = stats; + } else if (0 == strcmp(line + 7, "NeighborAdvertisements")) { + cached_icmp6_mib.icmp6InNeighborAdvertisements = stats; + } else if (0 == strcmp(line + 7, "NeighborSolicits")) { + cached_icmp6_mib.icmp6InNeighborSolicits = stats; + } else if (0 == strcmp(line + 7, "PktTooBigs")) { + cached_icmp6_mib.icmp6InPktTooBigs = stats; + } else if (0 == strcmp(line + 7, "ParmProblems")) { + cached_icmp6_mib.icmp6InParmProblems = stats; + } else if (0 == strcmp(line + 7, "Redirects")) { + cached_icmp6_mib.icmp6InRedirects = stats; + } else if (0 == strcmp(line + 7, "RouterAdvertisements")) { + cached_icmp6_mib.icmp6InRouterAdvertisements = stats; + } else if (0 == strcmp(line + 7, "RouterSolicits")) { + cached_icmp6_mib.icmp6InRouterSolicits = stats; + } else if (0 == strcmp(line + 7, "TimeExcds")) { + cached_icmp6_mib.icmp6InTimeExcds = stats; + } else { + match = 0; + } + } else if (0 == strncmp(line + 5, "Out", 3)) { /* Out */ + if (0 == strcmp(line + 8, "DestUnreachs")) { + cached_icmp6_mib.icmp6OutDestUnreachs = stats; + } else if (0 == strcmp(line + 8, "EchoReplies")) { + cached_icmp6_mib.icmp6OutEchoReplies = stats; + } else if (0 == strcmp(line + 8, "GroupMembReductions")) { + cached_icmp6_mib.icmp6OutGroupMembReductions = stats; + } else if (0 == strcmp(line + 8, "GroupMembResponses")) { + cached_icmp6_mib.icmp6OutGroupMembResponses = stats; + } else if (0 == strcmp(line + 8, "Msgs")) { + cached_icmp6_mib.icmp6OutMsgs = stats; + } else if (0 == strcmp(line + 8, "NeighborAdvertisements")) { + cached_icmp6_mib.icmp6OutNeighborAdvertisements = stats; + } else if (0 == strcmp(line + 8, "NeighborSolicits")) { + cached_icmp6_mib.icmp6OutNeighborSolicits = stats; + } else if (0 == strcmp(line + 8, "PktTooBigs")) { + cached_icmp6_mib.icmp6OutPktTooBigs = stats; + } else if (0 == strcmp(line + 8, "ParmProblems")) { + cached_icmp6_mib.icmp6OutParmProblems = stats; + } else if (0 == strcmp(line + 8, "Redirects")) { + cached_icmp6_mib.icmp6OutRedirects = stats; + } else if (0 == strcmp(line + 8, "RouterSolicits")) { + cached_icmp6_mib.icmp6OutRouterSolicits = stats; + } else if (0 == strcmp(line + 8, "TimeExcds")) { + cached_icmp6_mib.icmp6OutTimeExcds = stats; + } else { + match = 0; + } + } else { + match = 0; + } + if(!match) + DEBUGMSGTL(("mibII/kernel_linux/icmp6stats", + "%s is an unknown tag\n", line)); + } + + fclose(in); +#endif + + memcpy((char *) icmp6stat, (char *) &cached_icmp6_mib, + sizeof(*icmp6stat)); + return 0; +} + +int +linux_read_icmp6_msg_stat(struct icmp6_mib *icmp6stat, + struct icmp6_msg_mib *icmp6msgstat, + int *support) +{ + if (linux_read_icmp6_parse(icmp6stat, icmp6msgstat, support) < 0) + return -1; + else + return 0; +} + int linux_read_icmp_stat(struct icmp_mib *icmpstat) { memset((char *) icmpstat, (0), sizeof(*icmpstat)); if (linux_read_mibII_stats() == -1) - return -1; + return -1; + memcpy((char *) icmpstat, (char *) &cached_icmp_mib, - sizeof(*icmpstat)); + sizeof(*icmpstat)); return 0; } int +linux_read_icmp6_stat(struct icmp6_mib *icmp6stat) +{ + if (linux_read_icmp6_parse(icmp6stat, NULL, NULL) < 0) + return -1; + else + return 0; +} + +int linux_read_tcp_stat(struct tcp_mib *tcpstat) { memset((char *) tcpstat, (0), sizeof(*tcpstat)); @@ -216,6 +554,73 @@ linux_read_udp_stat(struct udp_mib *udpstat) memset((char *) udpstat, (0), sizeof(*udpstat)); if (linux_read_mibII_stats() == -1) return -1; + +#ifdef NETSNMP_ENABLE_IPV6 + { + struct udp6_mib udp6stat; + memset(&udp6stat, 0, sizeof(udp6stat)); + + if (linux_read_udp6_stat(&udp6stat) == 0) { + cached_udp_mib.udpOutDatagrams += udp6stat.udp6OutDatagrams; + cached_udp_mib.udpNoPorts += udp6stat.udp6NoPorts; + cached_udp_mib.udpInDatagrams += udp6stat.udp6InDatagrams; + cached_udp_mib.udpInErrors += udp6stat.udp6InErrors; + } + } +#endif memcpy((char *) udpstat, (char *) &cached_udp_mib, sizeof(*udpstat)); return 0; } + +int +linux_read_udp6_stat(struct udp6_mib *udp6stat) +{ +#ifdef NETSNMP_ENABLE_IPV6 + FILE *in; + char line[1024]; + unsigned long stats; + char *endp; +#endif + + memset(udp6stat, 0, sizeof(*udp6stat)); + +#ifdef NETSNMP_ENABLE_IPV6 + DEBUGMSGTL(("mibII/kernel_linux/udp6stats", + "Reading /proc/net/snmp6 stats\n")); + if (NULL == (in = fopen("/proc/net/snmp6", "r"))) { + DEBUGMSGTL(("mibII/kernel_linux/udp6stats", + "Failed to open /proc/net/snmp6\n")); + return -1; + } + + while (NULL != fgets(line, sizeof(line), in)) { + if (0 != strncmp(line, UDP6_STATS_LINE, UDP6_STATS_PREFIX_LEN)) + continue; + + if (1 != sscanf(line, "%*s %lu", &stats)) + continue; + + endp = strchr(line, ' '); + *endp = '\0'; + DEBUGMSGTL(("mibII/kernel_linux/udp6stats", "Find tag: %s\n", line)); + + if (0 == strcmp(line + 4, "OutDatagrams")) { + cached_udp6_mib.udp6OutDatagrams = stats; + } else if (0 == strcmp(line + 4, "NoPorts")) { + cached_udp6_mib.udp6NoPorts = stats; + } else if (0 == strcmp(line + 4, "InDatagrams")) { + cached_udp6_mib.udp6InDatagrams = stats; + } else if (0 == strcmp(line + 4, "InErrors")) { + cached_udp6_mib.udp6InErrors = stats; + } else { + DEBUGMSGTL(("mibII/kernel_linux/udp6stats", + "%s is an unknown tag\n", line)); + } + } + + fclose(in); +#endif + + memcpy((char *) udp6stat, (char *) &cached_udp6_mib, sizeof(*udp6stat)); + return 0; +} diff --git a/agent/mibgroup/mibII/kernel_linux.h b/agent/mibgroup/mibII/kernel_linux.h index fb7db96..6bf5d47 100644 --- a/agent/mibgroup/mibII/kernel_linux.h +++ b/agent/mibgroup/mibII/kernel_linux.h @@ -29,6 +29,31 @@ struct ip_mib { unsigned long ipRoutingDiscards; }; +struct ip6_mib { + unsigned long ip6InReceives; + unsigned long ip6InHdrErrors; + unsigned long ip6InTooBigErrors; + unsigned long ip6InNoRoutes; + unsigned long ip6InAddrErrors; + unsigned long ip6InUnknownProtos; + unsigned long ip6InTruncatedPkts; + unsigned long ip6InDiscards; + unsigned long ip6InDelivers; + unsigned long ip6OutForwDatagrams; + unsigned long ip6OutRequests; + unsigned long ip6OutDiscards; + unsigned long ip6OutNoRoutes; + unsigned long ip6ReasmTimeout; + unsigned long ip6ReasmReqds; + unsigned long ip6ReasmOKs; + unsigned long ip6ReasmFails; + unsigned long ip6FragOKs; + unsigned long ip6FragFails; + unsigned long ip6FragCreates; + unsigned long ip6InMcastPkts; + unsigned long ip6OutMcastPkts; +}; + struct icmp_mib { unsigned long icmpInMsgs; unsigned long icmpInErrors; @@ -58,6 +83,51 @@ struct icmp_mib { unsigned long icmpOutAddrMaskReps; }; +struct icmp6_mib { + unsigned long icmp6InMsgs; + unsigned long icmp6InErrors; + unsigned long icmp6InDestUnreachs; + unsigned long icmp6InPktTooBigs; + unsigned long icmp6InTimeExcds; + unsigned long icmp6InParmProblems; + unsigned long icmp6InEchos; + unsigned long icmp6InEchoReplies; + unsigned long icmp6InGroupMembQueries; + unsigned long icmp6InGroupMembResponses; + unsigned long icmp6InGroupMembReductions; + unsigned long icmp6InRouterSolicits; + unsigned long icmp6InRouterAdvertisements; + unsigned long icmp6InNeighborSolicits; + unsigned long icmp6InNeighborAdvertisements; + unsigned long icmp6InRedirects; + unsigned long icmp6OutMsgs; + unsigned long icmp6OutDestUnreachs; + unsigned long icmp6OutPktTooBigs; + unsigned long icmp6OutTimeExcds; + unsigned long icmp6OutParmProblems; + unsigned long icmp6OutEchoReplies; + unsigned long icmp6OutRouterSolicits; + unsigned long icmp6OutNeighborSolicits; + unsigned long icmp6OutNeighborAdvertisements; + unsigned long icmp6OutRedirects; + unsigned long icmp6OutGroupMembResponses; + unsigned long icmp6OutGroupMembReductions; +}; + +struct icmp_msg_mib { + unsigned long InType; + unsigned long OutType; +}; + +/* Lets use wrapper structures for future expansion */ +struct icmp4_msg_mib { + struct icmp_msg_mib vals[255]; +}; + +struct icmp6_msg_mib { + struct icmp_msg_mib vals[255]; +}; + struct udp_mib { unsigned long udpInDatagrams; unsigned long udpNoPorts; @@ -65,6 +135,13 @@ struct udp_mib { unsigned long udpOutDatagrams; }; +struct udp6_mib { + unsigned long udp6InDatagrams; + unsigned long udp6NoPorts; + unsigned long udp6InErrors; + unsigned long udp6OutDatagrams; +}; + struct tcp_mib { unsigned long tcpRtoAlgorithm; unsigned long tcpRtoMin; @@ -86,8 +163,17 @@ struct tcp_mib { int linux_read_ip_stat(struct ip_mib *); +int linux_read_ip6_stat(struct ip6_mib *); int linux_read_icmp_stat(struct icmp_mib *); +int linux_read_icmp6_stat(struct icmp6_mib *); int linux_read_udp_stat(struct udp_mib *); +int linux_read_udp6_stat(struct udp6_mib *); int linux_read_tcp_stat(struct tcp_mib *); +int linux_read_icmp_msg_stat(struct icmp_mib *, + struct icmp4_msg_mib *, + int *flag); +int linux_read_icmp6_msg_stat(struct icmp6_mib *, + struct icmp6_msg_mib *, + int *support); #endif /* _MIBGROUP_KERNEL_LINUX_H */ diff --git a/configure b/configure index 322d5ac..1b062bf 100755 --- a/configure +++ b/configure @@ -33746,7 +33746,7 @@ done -for ac_header in arpa/inet.h netinet/in_systm.h netinet/in.h netinet/ip_var.h netinet/tcp.h netinet/tcpip.h netinet/udp.h net/if.h netinet/in_var.h netinet/ip.h netinet/ip_icmp.h net/if_arp.h net/if_mib.h net/if_var.h netinet/if_ether.h netinet/tcp_timer.h netinet/tcp_var.h netinet/udp_var.h netinet/icmp_var.h netdb.h net/route.h +for ac_header in arpa/inet.h netinet/in_systm.h netinet/in.h netinet/ip_var.h netinet/tcp.h netinet/tcpip.h netinet/udp.h net/if.h netinet/in_var.h netinet/ip.h netinet/ip_icmp.h netinet/icmp6.h net/if_arp.h net/if_mib.h net/if_var.h netinet/if_ether.h netinet/tcp_timer.h netinet/tcp_var.h netinet/udp_var.h netinet/icmp_var.h netdb.h net/route.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_header" >&5 @@ -33794,6 +33794,9 @@ cat >>conftest.$ac_ext <<_ACEOF #if HAVE_NETINET_IP_ICMP_H #include <netinet/ip_icmp.h> #endif +#if HAVE_NETINET_ICMP6_H +#include <netinet/icmp6.h> +#endif #if HAVE_NETINET_TCP_H #include <netinet/tcp.h> #endif diff --git a/configure.in b/configure.in index 82c22b8..3ad7955 100644 --- a/configure.in +++ b/configure.in @@ -3247,7 +3247,7 @@ AC_INCLUDES_DEFAULT([]) ]) AC_CHECK_HEADERS(sys/timeout.h sys/un.h fstab.h sys/fs.h mtab.h ufs/fs.h sys/fixpoint.h machine/param.h sys/vm.h vm/vm.h sys/vmmeter.h sys/vmparam.h sys/vmmac.h sys/vmsystm.h sys/time.h sys/times.h sys/statvfs.h sys/vfs.h sys/mnttab.h sys/select.h mntent.h sys/mntent.h kstat.h utsname.h sys/utsname.h sys/cdefs.h getopt.h locale.h pthread.h sys/loadavg.h regex.h linux/tasks.h pwd.h grp.h utmpx.h) # Network headers -AC_CHECK_HEADERS(arpa/inet.h netinet/in_systm.h netinet/in.h netinet/ip_var.h netinet/tcp.h netinet/tcpip.h netinet/udp.h net/if.h netinet/in_var.h netinet/ip.h netinet/ip_icmp.h net/if_arp.h net/if_mib.h net/if_var.h netinet/if_ether.h netinet/tcp_timer.h netinet/tcp_var.h netinet/udp_var.h netinet/icmp_var.h netdb.h net/route.h,,, +AC_CHECK_HEADERS(arpa/inet.h netinet/in_systm.h netinet/in.h netinet/ip_var.h netinet/tcp.h netinet/tcpip.h netinet/udp.h net/if.h netinet/in_var.h netinet/ip.h netinet/ip_icmp.h netinet/icmp6.h net/if_arp.h net/if_mib.h net/if_var.h netinet/if_ether.h netinet/tcp_timer.h netinet/tcp_var.h netinet/udp_var.h netinet/icmp_var.h netdb.h net/route.h,,, [[ #if HAVE_SYS_TYPES_H #include <sys/types.h> @@ -3282,6 +3282,9 @@ AC_CHECK_HEADERS(arpa/inet.h netinet/in_systm.h netinet/in.h netinet/ip_var.h ne #if HAVE_NETINET_IP_ICMP_H #include <netinet/ip_icmp.h> #endif +#if HAVE_NETINET_ICMP6_H +#include <netinet/icmp6.h> +#endif #if HAVE_NETINET_TCP_H #include <netinet/tcp.h> #endif diff --git a/include/net-snmp/net-snmp-config.h.in b/include/net-snmp/net-snmp-config.h.in index 1be4ca4..2c93d11 100644 --- a/include/net-snmp/net-snmp-config.h.in +++ b/include/net-snmp/net-snmp-config.h.in @@ -588,6 +588,9 @@ /* Define to 1 if you have the <netinet/ip_icmp.h> header file. */ #undef HAVE_NETINET_IP_ICMP_H +/* Define to 1 if you have the <netinet/icmp6.h> header file. */ +#undef HAVE_NETINET_ICMP6_H + /* Define to 1 if you have the <netinet/ip_var.h> header file. */ #undef HAVE_NETINET_IP_VAR_H diff --git a/win32/net-snmp/net-snmp-config.h.in b/win32/net-snmp/net-snmp-config.h.in index bf2d2dc..1654562 100644 --- a/win32/net-snmp/net-snmp-config.h.in +++ b/win32/net-snmp/net-snmp-config.h.in @@ -486,6 +486,9 @@ /* Define to 1 if you have the <netinet/ip_icmp.h> header file. */ /* #undef HAVE_NETINET_IP_ICMP_H */ +/* Define to 1 if you have the <netinet/icmp6.h> header file. */ +/* #undef HAVE_NETINET_ICMP6_H */ + /* Define to 1 if you have the <netinet/ip_var.h> header file. */ /* #undef HAVE_NETINET_IP_VAR_H */ -- 1.6.0.2