Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 20db51d70e6b59a061db97ce9b89c771 > files > 21

net-snmp-5.3.2.2-14.el5.src.rpm

Add ipv6 support to inetNetToMediaTable
Source: https://sourceforge.net/tracker/index.php?func=detail&aid=1704105&group_id=12694&atid=312694

Index: configure.in
===================================================================
--- configure.in	(revision 16294)
+++ configure.in	(working copy)
@@ -3280,6 +3280,16 @@
 typedef __u16 u16;         /* ditto */
 typedef __u8 u8;           /* ditto */
 ]])
+# linux rtnetlink
+AC_CHECK_HEADERS(linux/rtnetlink.h,,,
+[[
+#if HAVE_ASM_TYPES_H
+#include <asm/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+]])
 # BSDi3 headers
 AC_CHECK_HEADERS(sys/stat.h)
 # BSDi3/IRIX headers
Index: agent/mibgroup/ip-mib/inetNetToMediaTable/inetNetToMediaTable_data_access.c
===================================================================
--- agent/mibgroup/ip-mib/inetNetToMediaTable/inetNetToMediaTable_data_access.c	(revision 16294)
+++ agent/mibgroup/ip-mib/inetNetToMediaTable/inetNetToMediaTable_data_access.c	(working copy)
@@ -155,7 +155,7 @@
         inetAddressType = INETADDRESSTYPE_IPV4;
         break;
 
-    case 6:
+    case 16:
         inetAddressType = INETADDRESSTYPE_IPV6;
         break;
 
Index: agent/mibgroup/ip-mib/inetNetToMediaTable/inetNetToMediaTable_data_access.c
===================================================================
--- agent/mibgroup/ip-mib/inetNetToMediaTable/inetNetToMediaTable_data_access.c.orig     2007-06-26 14:01:59.000000000 +0200
+++ agent/mibgroup/ip-mib/inetNetToMediaTable/inetNetToMediaTable_data_access.c  2007-06-26 14:01:16.000000000 +0200
@@ -161,7 +161,7 @@
 
     default:
         netsnmp_access_arp_entry_free(arp_entry);
-        snmp_log(LOG_ERR, "unsupported address type\n");
+        DEBUGMSGTL(("verbose:inetNetToMediaTable:_snarf_arp_entry", "unsupported address type")); /* Red Hat: this message seems to be too frequent */
         return;
     }
 
Index: agent/mibgroup/ip-mib/data_access/arp_linux.c
===================================================================
--- agent/mibgroup/ip-mib/data_access/arp_linux.c	(revision 16294)
+++ agent/mibgroup/ip-mib/data_access/arp_linux.c	(working copy)
@@ -14,9 +14,37 @@
 #include <netinet/in.h>
 #include <net/if_arp.h>
 #include <arpa/inet.h>
+#include <linux/types.h>
+#include <asm/types.h>
+#define HAVE_LINUX_RTNETLINK_H
+#ifdef INET6
+#ifdef HAVE_LINUX_RTNETLINK_H
+#include <linux/rtnetlink.h>
+#ifndef NDA_RTA
+#define NDA_RTA(r) \
+ ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg))))
+#endif
+#define NIP6(addr) \
+        ntohs((addr).s6_addr16[0]), \
+        ntohs((addr).s6_addr16[1]), \
+        ntohs((addr).s6_addr16[2]), \
+        ntohs((addr).s6_addr16[3]), \
+        ntohs((addr).s6_addr16[4]), \
+        ntohs((addr).s6_addr16[5]), \
+        ntohs((addr).s6_addr16[6]), \
+        ntohs((addr).s6_addr16[7])
+#define NIP6_FMT "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
+#endif
+#endif
 
 int _load_v4(netsnmp_container *container, int idx_offset);
-
+static int _load_v6(netsnmp_container *container, int idx_offset);
+#ifdef HAVE_LINUX_RTNETLINK_H
+int get_translation_table_info (int sd, int *status, 
+                                char *buff, size_t size);
+int fillup_entry_info(netsnmp_arp_entry *entry,
+                      struct nlmsghdr *nlmp);
+#endif
 /**
  */
 int
@@ -28,11 +51,10 @@
     if(rc < 0) {
         u_int flags = NETSNMP_ACCESS_ARP_FREE_KEEP_CONTAINER;
         netsnmp_access_arp_container_free(container, flags);
-        return rc;
     }
 
-#if defined (INET6) && 0 /* xx-rks: arp for v6? */
-    idx_offset = rc;
+#if defined (INET6)
+    idx_offset = (rc < 0) ? 0 : rc;
 
     rc = _load_v6(container, idx_offset);
     if(rc < 0) {
@@ -187,3 +209,207 @@
 
     return idx_offset;
 }
+
+#if defined (INET6)
+static int
+_load_v6(netsnmp_container *container, int idx_offset)
+{
+    char              buffer[16384];
+#if defined(HAVE_LINUX_RTNETLINK_H)
+    struct nlmsghdr   *nlmp;
+#endif
+    int               sd = 0;
+    int               status = 0;
+    int               rc = 0;
+    int               len, req_len;
+    netsnmp_arp_entry *entry;
+
+    netsnmp_assert(NULL != container);
+#if defined(HAVE_LINUX_RTNETLINK_H)
+    if((sd = socket (PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0) {
+        snmp_log(LOG_ERR,"Unable to create netlink socket\n");
+        return -2;
+    }
+
+    if(get_translation_table_info (sd, &status, buffer, sizeof(buffer)) < 0) {
+       snmp_log(LOG_ERR,"Unable to fetch translation table info\n");
+       close(sd);
+       return -2;
+    }
+
+    for (nlmp = (struct nlmsghdr *)buffer; status > sizeof(*nlmp); ) {
+         len = nlmp->nlmsg_len;
+         req_len = len - sizeof(*nlmp);
+         if (req_len < 0 || len > status) {
+             snmp_log(LOG_ERR,"invalid length\n");
+             return -2;
+         }
+         if (!NLMSG_OK (nlmp, status)) {
+             snmp_log(LOG_ERR,"NLMSG not OK\n");
+             return -2;
+         }
+         entry = netsnmp_access_arp_entry_create();
+         if(NULL == entry) {
+            rc = -3;
+            break;
+         }
+         entry->ns_arp_index = ++idx_offset;
+         if(fillup_entry_info (entry, nlmp) < 0) {
+            snmp_log(LOG_ERR, "filling entry info failed\n");
+            netsnmp_access_arp_entry_free(entry);
+            continue;
+         }
+         CONTAINER_INSERT(container, entry);
+         status -= NLMSG_ALIGN(len);
+         nlmp = (struct nlmsghdr*)((char*)nlmp + NLMSG_ALIGN(len));
+    }
+
+    close(sd);
+#endif
+    if(rc<0) {
+        return rc;
+    }
+
+    return idx_offset;
+}
+#if defined(HAVE_LINUX_RTNETLINK_H)
+int 
+get_translation_table_info (int sd, int *status, char *buff, size_t size)
+{
+    struct {
+                struct nlmsghdr n;
+                struct ndmsg r;
+                char   buf[1024];
+    } req;
+    struct rtattr   *rta;
+
+    memset(&req, 0, sizeof(req));
+    req.n.nlmsg_len = NLMSG_LENGTH (sizeof(struct ndmsg));
+    req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
+    req.n.nlmsg_type = RTM_GETNEIGH;
+
+    req.r.ndm_family = AF_INET6;
+    rta = (struct rtattr *)(((char *)&req) + NLMSG_ALIGN(req.n.nlmsg_len));
+    rta->rta_len = RTA_LENGTH(16);
+
+    if(send(sd, &req, req.n.nlmsg_len, 0) < 0) {
+       snmp_log(LOG_ERR,"Sending request failed\n");
+       return -1;
+    }
+    if((*status = recv(sd, buff, size, 0)) < 0) {
+       snmp_log(LOG_ERR,"Recieving request failed\n");
+       return -1;
+    }
+    if(*status == 0) {
+       snmp_log(LOG_ERR,"End of file\n");
+       return -1;
+    }
+    return 0;
+}
+
+int
+fillup_entry_info(netsnmp_arp_entry *entry, struct nlmsghdr *nlmp)
+{
+    struct ndmsg    *rtmp;
+    struct in6_addr *in6p;
+    struct rtattr   *tb[NDA_MAX+1], *rta;
+    size_t    	     in_len, out_len, i;
+    int             length;
+    char            addr[40];
+    u_char          *buf;
+    u_char          *hwaddr;
+
+    rtmp = (struct ndmsg *)NLMSG_DATA(nlmp);
+    if (nlmp->nlmsg_type != RTM_NEWNEIGH && nlmp->nlmsg_type != RTM_DELNEIGH)
+        return -1;
+
+    if(rtmp->ndm_state != NUD_NOARP) {
+       memset(tb, 0, sizeof(struct rtattr *) * (NDA_MAX + 1));
+       length = nlmp->nlmsg_len - NLMSG_LENGTH(sizeof(*rtmp));
+       rta = NDA_RTA(rtmp);
+       while (RTA_OK(rta, length)) {
+              if (rta->rta_type <= NDA_MAX)
+                  tb[rta->rta_type] = rta;
+              rta = RTA_NEXT(rta,length);
+       }
+       if(length)
+          return -1;
+       /* Fill up the index
+       */
+       entry->if_index = rtmp->ndm_ifindex;
+       /* Fill up ip address */
+       if (tb[NDA_DST]) {
+           memset(&addr, '\0', sizeof(addr));
+           in6p = (struct in6_addr *)RTA_DATA(tb[NDA_DST]);
+           sprintf(addr, NIP6_FMT, NIP6(*in6p));
+           in_len = entry->arp_ipaddress_len = sizeof(entry->arp_ipaddress);
+           netsnmp_assert(16 == in_len);
+           out_len = 0;
+           buf = entry->arp_ipaddress;
+           if(1 != netsnmp_hex_to_binary(&buf, &in_len,
+                                         &out_len, 0, addr, ":")) {
+              snmp_log(LOG_ERR,"error parsing '%s', skipping\n",
+                     entry->arp_ipaddress);
+              return -1;
+           }
+           netsnmp_assert(16 == out_len);
+           entry->arp_ipaddress_len = out_len;
+       }
+       if (tb[NDA_LLADDR]) {
+           memset(&addr, '\0', sizeof(addr));
+           hwaddr = RTA_DATA(tb[NDA_LLADDR]);
+           entry->arp_physaddress_len = RTA_PAYLOAD(tb[NDA_LLADDR]);
+           buf = entry->arp_physaddress;
+           for (i = 0; i < entry->arp_physaddress_len; i++)
+                entry->arp_physaddress[i] = hwaddr[i];
+       }
+
+       switch (rtmp->ndm_state) {
+        case NUD_INCOMPLETE:
+             entry->arp_state = INETNETTOMEDIASTATE_INCOMPLETE;
+             break;
+        case NUD_REACHABLE:
+        case NUD_PERMANENT:
+             entry->arp_state = INETNETTOMEDIASTATE_REACHABLE;
+             break;
+        case NUD_STALE:
+             entry->arp_state = INETNETTOMEDIASTATE_STALE;
+             break;
+        case NUD_DELAY:
+             entry->arp_state = INETNETTOMEDIASTATE_DELAY;
+             break;
+        case NUD_PROBE:
+             entry->arp_state = INETNETTOMEDIASTATE_PROBE;
+             break;
+        case NUD_FAILED:
+            entry->arp_state = INETNETTOMEDIASTATE_INVALID;
+             break;
+        case NUD_NONE:
+             entry->arp_state = INETNETTOMEDIASTATE_UNKNOWN;
+             break;
+       }
+
+       switch (rtmp->ndm_state) {
+        case NUD_INCOMPLETE:
+        case NUD_FAILED    :
+        case NUD_NONE      :
+             entry->arp_type = INETNETTOMEDIATYPE_INVALID;
+             break;
+        case NUD_REACHABLE:
+        case NUD_STALE    :
+        case NUD_DELAY    :
+        case NUD_PROBE    :
+             entry->arp_type = INETNETTOMEDIATYPE_DYNAMIC;
+             break;
+        case NUD_PERMANENT:
+             entry->arp_type = INETNETTOMEDIATYPE_STATIC;
+             break;
+        default:
+             entry->arp_type = INETNETTOMEDIATYPE_LOCAL;
+             break;
+       }      
+    }
+    return 0;
+}
+#endif
+#endif

 	  	 


--- configure.orig	2007-10-04 12:29:01.000000000 +0200
+++ configure	2007-10-04 12:43:17.000000000 +0200
@@ -20435,6 +20435,75 @@
 
 done
 
+# linux rtnetlink
+
+for ac_header in linux/rtnetlink.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#if HAVE_ASM_TYPES_H
+#include <asm/types.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+     { ac_try='test -z "$ac_c_werror_flag"
+	     || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+     { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
 # BSDi3 headers
 
 for ac_header in sys/stat.h
--- include/net-snmp/net-snmp-config.h.in.orig	2007-10-04 13:04:06.000000000 +0200
+++ include/net-snmp/net-snmp-config.h.in	2007-10-04 13:06:37.000000000 +0200
@@ -1623,4 +1623,7 @@
 
 #undef HEIMDAL
 
+/* define if you have linux/rtnetlink.h */
+#undef HAVE_LINUX_RTNETLINK_H
+
 #endif /* NET_SNMP_CONFIG_H */