net-snmp/Add-ICMP-Statistics-Tables-support.patch

1478 lines
52 KiB
Diff

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