Search
j0ke.net Open Build Service
>
Projects
>
GFS
>
net-snmp
> Add-IPv6-support-on-Internet-Address-Translation-Tab.patch
Sign Up
|
Log In
Username
Password
Cancel
Overview
Repositories
Revisions
Requests
Users
Advanced
Attributes
Meta
File Add-IPv6-support-on-Internet-Address-Translation-Tab.patch of Package net-snmp (Revision 3)
Currently displaying revision
3
,
show latest
From ecd91d8a2b532bd1a987369e76d75fef454f2bcf Mon Sep 17 00:00:00 2001 From: Mitsuru Chinen <mitch@linux.vnet.ibm.com> Date: Mon, 20 Oct 2008 17:33:11 +0900 Subject: [PATCH] Add IPv6 support on Internet Address Translation Table [ 1708243 ] add linux support for ipDefaultRouterTable OID to net-snmp http://sourceforge.net/tracker/index.php?func=detail&aid=1708243&group_id=12694&atid=312694 [ 1724602 ] [Linux] ipDefaultRouterTable improvement http://sourceforge.net/tracker/index.php?func=detail&aid=1724602&group_id=12694&atid=312694 [ 1728223 ] [Linux] add configure check for netlink socket http://sourceforge.net/tracker/index.php?func=detail&aid=1728223&group_id=12694&atid=312694 Signed-off-by: Mitsuru Chinen <mitch@linux.vnet.ibm.com> --- agent/mibgroup/ip-mib/data_access/arp_linux.c | 243 +++++++++++++++++++- .../inetNetToMediaTable_data_access.c | 2 +- configure.in | 10 + 3 files changed, 249 insertions(+), 6 deletions(-) diff --git a/agent/mibgroup/ip-mib/data_access/arp_linux.c b/agent/mibgroup/ip-mib/data_access/arp_linux.c index e1d20c1..a25e4d8 100644 --- a/agent/mibgroup/ip-mib/data_access/arp_linux.c +++ b/agent/mibgroup/ip-mib/data_access/arp_linux.c @@ -14,9 +14,32 @@ #include <netinet/in.h> #include <net/if_arp.h> #include <arpa/inet.h> +#include <linux/types.h> +#include <asm/types.h> +#ifdef NETSNMP_ENABLE_IPV6 +#ifdef HAVE_LINUX_RTNETLINK_H +#include <linux/rtnetlink.h> +#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 @@ netsnmp_access_arp_container_arch_load(netsnmp_container *container) if(rc < 0) { u_int flags = NETSNMP_ACCESS_ARP_FREE_KEEP_CONTAINER; netsnmp_access_arp_container_free(container, flags); - return rc; } -#if defined (NETSNMP_ENABLE_IPV6) && 0 /* xx-rks: arp for v6? */ - idx_offset = rc; +#if defined (NETSNMP_ENABLE_IPV6) + idx_offset = (rc < 0) ? 0 : rc; rc = _load_v6(container, idx_offset); if(rc < 0) { @@ -64,7 +86,7 @@ _load_v4(netsnmp_container *container, int idx_offset) #define PROCFILE "/proc/net/arp" if (!(in = fopen(PROCFILE, "r"))) { - snmp_log(LOG_ERR,"could not open " PROCFILE "\n"); + snmp_log(LOG_DEBUG,"could not open " PROCFILE "\n"); return -2; } @@ -192,3 +214,214 @@ _load_v4(netsnmp_container *container, int idx_offset) return idx_offset; } + +#if defined (NETSNMP_ENABLE_IPV6) +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) { + DEBUGMSGTL(("access:arp:load_v6", "filling entry info failed\n")); + netsnmp_access_arp_entry_free(entry); + status -= NLMSG_ALIGN(len); + nlmp = (struct nlmsghdr*)((char*)nlmp + NLMSG_ALIGN(len)); + 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; + unsigned int 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)); + /* this is what the kernel-removed NDA_RTA define did */ + rta = ((struct rtattr*)(((char*)(rtmp)) + + NLMSG_ALIGN(sizeof(struct ndmsg)))); + 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; + } + } else { + return -1; /* could not create data for this interface */ + } + return 0; +} +#endif +#endif diff --git a/agent/mibgroup/ip-mib/inetNetToMediaTable/inetNetToMediaTable_data_access.c b/agent/mibgroup/ip-mib/inetNetToMediaTable/inetNetToMediaTable_data_access.c index cad942c..dcc7900 100644 --- a/agent/mibgroup/ip-mib/inetNetToMediaTable/inetNetToMediaTable_data_access.c +++ b/agent/mibgroup/ip-mib/inetNetToMediaTable/inetNetToMediaTable_data_access.c @@ -155,7 +155,7 @@ _snarf_arp_entry(netsnmp_arp_entry *arp_entry, inetAddressType = INETADDRESSTYPE_IPV4; break; - case 6: + case 16: inetAddressType = INETADDRESSTYPE_IPV6; break; diff --git a/configure.in b/configure.in index c5e05ba..220506a 100644 --- a/configure.in +++ b/configure.in @@ -3365,6 +3365,16 @@ AC_CHECK_HEADERS(linux/rtnetlink.h,,, #include <linux/netlink.h> #endif ]]) +# 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 -- 1.6.0.2