877 lines
33 KiB
Diff
877 lines
33 KiB
Diff
From 71ffec9f8c1bcd14a7bf6ca7762bc121ba1efaf1 Mon Sep 17 00:00:00 2001
|
|
From: Mitsuru Chinen <mitch@linux.vnet.ibm.com>
|
|
Date: Mon, 20 Oct 2008 17:42:57 +0900
|
|
Subject: [PATCH] Fix for Internet Address Prefix Table
|
|
|
|
From net-snmp patch tracker:
|
|
[ 1705594 ] ipAddressPrefixTable Fixes
|
|
http://sourceforge.net/tracker/index.php?func=detail&aid=1705594&group_id=12694&atid=312694
|
|
|
|
[ 1902105 ] hide some log messages introduced by patch 1705594
|
|
http://sourceforge.net/tracker/index.php?func=detail&aid=1902105&group_id=12694&atid=312694
|
|
|
|
Signed-off-by: Mitsuru Chinen <mitch@linux.vnet.ibm.com>
|
|
---
|
|
.../mibgroup/if-mib/data_access/interface_linux.c | 186 ++++++++++++++++++++
|
|
.../mibgroup/ip-mib/data_access/ipaddress_common.c | 67 +++++++
|
|
.../mibgroup/ip-mib/data_access/ipaddress_linux.c | 144 +++++++++++++++-
|
|
.../ipAddressPrefixTable/ipAddressPrefixTable.c | 7 +-
|
|
.../ipAddressPrefixTable_constants.h | 14 ++
|
|
.../ipAddressPrefixTable_data_access.c | 27 +++-
|
|
agent/mibgroup/util_funcs.c | 152 ++++++++++++++++-
|
|
agent/mibgroup/util_funcs.h | 41 +++++
|
|
include/net-snmp/data_access/ipaddress.h | 19 ++-
|
|
9 files changed, 645 insertions(+), 12 deletions(-)
|
|
|
|
diff --git a/agent/mibgroup/if-mib/data_access/interface_linux.c b/agent/mibgroup/if-mib/data_access/interface_linux.c
|
|
index 474a904..294963a 100644
|
|
--- a/agent/mibgroup/if-mib/data_access/interface_linux.c
|
|
+++ b/agent/mibgroup/if-mib/data_access/interface_linux.c
|
|
@@ -29,6 +29,7 @@ typedef __u8 u8; /* ditto */
|
|
#include <net-snmp/data_access/interface.h>
|
|
#include <net-snmp/data_access/ipaddress.h>
|
|
#include "if-mib/data_access/interface.h"
|
|
+#include "mibgroup/util_funcs.h"
|
|
#include "interface_ioctl.h"
|
|
|
|
#include <sys/types.h>
|
|
@@ -42,6 +43,15 @@ typedef __u8 u8; /* ditto */
|
|
#define IF_NAMESIZE 16
|
|
#endif
|
|
|
|
+#ifdef NETSNMP_ENABLE_IPV6
|
|
+#if defined(HAVE_PTHREAD_H) && defined(HAVE_LINUX_RTNETLINK_H)
|
|
+#include <pthread.h>
|
|
+#include <linux/rtnetlink.h>
|
|
+#ifdef RTMGRP_IPV6_PREFIX
|
|
+#define SUPPORT_PREFIX_FLAGS 1
|
|
+#endif /* RTMGRP_IPV6_PREFIX */
|
|
+#endif /* HAVE_PTHREAD_H && HAVE_LINUX_RTNETLINK_H */
|
|
+#endif /* NETSNMP_ENABLE_IPV6 */
|
|
unsigned int
|
|
netsnmp_linux_interface_get_if_speed(int fd, const char *name);
|
|
#ifdef HAVE_LINUX_ETHTOOL_H
|
|
@@ -59,6 +69,16 @@ static unsigned short retrans_time_factor = 1;
|
|
#define PROC_SYS_NET_IPVx_BASE_REACHABLE_TIME "/proc/sys/net/ipv%d/neigh/%s/base_reachable_time"
|
|
static const char *proc_sys_basereachable_time;
|
|
static unsigned short basereachable_time_ms = 0;
|
|
+#ifdef SUPPORT_PREFIX_FLAGS
|
|
+prefix_cbx *prefix_head_list = NULL;
|
|
+pthread_mutex_t prefix_mutex_lock = PTHREAD_MUTEX_INITIALIZER;
|
|
+netsnmp_prefix_listen_info list_info;
|
|
+pthread_t thread1;
|
|
+#define IF_PREFIX_ONLINK 0x01
|
|
+#define IF_PREFIX_AUTOCONF 0x02
|
|
+
|
|
+void *netsnmp_prefix_listen(netsnmp_prefix_listen_info *listen_info);
|
|
+#endif
|
|
void
|
|
netsnmp_arch_interface_init(void)
|
|
{
|
|
@@ -91,6 +111,13 @@ netsnmp_arch_interface_init(void)
|
|
else {
|
|
proc_sys_basereachable_time = PROC_SYS_NET_IPVx_BASE_REACHABLE_TIME;
|
|
}
|
|
+#ifdef SUPPORT_PREFIX_FLAGS
|
|
+ list_info.list_head = &prefix_head_list;
|
|
+ list_info.lockinfo = &prefix_mutex_lock;
|
|
+
|
|
+ if(pthread_create(&thread1, NULL, netsnmp_prefix_listen, &list_info) < 0)
|
|
+ snmp_log(LOG_ERR,"Unable to create thread\n");
|
|
+#endif
|
|
}
|
|
|
|
/*
|
|
@@ -885,3 +912,162 @@ netsnmp_linux_interface_get_if_speed(int fd, const char *name)
|
|
}
|
|
return retspeed;
|
|
}
|
|
+#ifdef SUPPORT_PREFIX_FLAGS
|
|
+void *netsnmp_prefix_listen(netsnmp_prefix_listen_info *listen_info)
|
|
+{
|
|
+ struct {
|
|
+ struct nlmsghdr n;
|
|
+ struct ifinfomsg r;
|
|
+ char buf[1024];
|
|
+ } req;
|
|
+
|
|
+ struct rtattr *rta;
|
|
+ int status;
|
|
+ char buf[16384];
|
|
+ struct nlmsghdr *nlmp;
|
|
+ struct rtattr *rtatp;
|
|
+ struct in6_addr *in6p;
|
|
+ struct sockaddr_nl localaddrinfo;
|
|
+ struct ifaddrmsg *ifa;
|
|
+ struct prefixmsg *prefix;
|
|
+ unsigned groups = 0;
|
|
+ struct rtattr *index_table[IFA_MAX+1];
|
|
+ char in6pAddr[40];
|
|
+ int flag1 = 0,flag2 = 0;
|
|
+ int onlink = 2,autonomous = 2; /*Assume as false*/
|
|
+ prefix_cbx *new;
|
|
+ int iret;
|
|
+ int len, req_len, length;
|
|
+ int fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
|
|
+
|
|
+
|
|
+ memset(&localaddrinfo, 0, sizeof(struct sockaddr_nl));
|
|
+ memset(&in6pAddr, '\0', sizeof(in6pAddr));
|
|
+
|
|
+ groups |= RTMGRP_IPV6_IFADDR;
|
|
+ groups |= RTMGRP_IPV6_PREFIX;
|
|
+ localaddrinfo.nl_family = AF_NETLINK;
|
|
+ localaddrinfo.nl_groups = groups;
|
|
+
|
|
+ if (bind(fd, (struct sockaddr*)&localaddrinfo, sizeof(localaddrinfo)) < 0) {
|
|
+ snmp_log(LOG_ERR,"netsnmp_prefix_listen: Bind failed. Exiting thread.\n");
|
|
+ exit(0);
|
|
+ }
|
|
+
|
|
+ memset(&req, 0, sizeof(req));
|
|
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
|
|
+ req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
|
|
+ req.n.nlmsg_type = RTM_GETLINK;
|
|
+ req.r.ifi_family = AF_INET6;
|
|
+ rta = (struct rtattr *)(((char *)&req) + NLMSG_ALIGN(req.n.nlmsg_len));
|
|
+ rta->rta_len = RTA_LENGTH(16);
|
|
+
|
|
+ status = send(fd, &req, req.n.nlmsg_len, 0);
|
|
+ if (status < 0) {
|
|
+ snmp_log(LOG_ERR,"netsnmp_prefix_listen: Send failed. Exiting thread\n");
|
|
+ exit(0);
|
|
+ }
|
|
+
|
|
+ while(1) {
|
|
+ status = recv(fd, buf, sizeof(buf), 0);
|
|
+ if (status < 0) {
|
|
+ snmp_log(LOG_ERR,"netsnmp_prefix_listen: Recieve failed. Exiting thread\n");
|
|
+ exit(0);
|
|
+ }
|
|
+
|
|
+ if(status == 0){
|
|
+ DEBUGMSGTL(("access:interface:prefix", "End of File\n"));
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ for(nlmp = (struct nlmsghdr *)buf; status > sizeof(*nlmp);){
|
|
+ len = nlmp->nlmsg_len;
|
|
+ req_len = len - sizeof(*nlmp);
|
|
+
|
|
+ if (req_len < 0 || len > status) {
|
|
+ snmp_log(LOG_ERR,"netsnmp_prefix_listen: Error in length. Exiting thread\n");
|
|
+ exit(0);
|
|
+ }
|
|
+
|
|
+ if (!NLMSG_OK(nlmp, status)) {
|
|
+ DEBUGMSGTL(("access:interface:prefix", "NLMSG not OK\n"));
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ if (nlmp->nlmsg_type == RTM_NEWADDR || nlmp->nlmsg_type == RTM_DELADDR) {
|
|
+ ifa = NLMSG_DATA(nlmp);
|
|
+ length = nlmp->nlmsg_len;
|
|
+ length -= NLMSG_LENGTH(sizeof(*ifa));
|
|
+
|
|
+ if (length < 0) {
|
|
+ DEBUGMSGTL(("access:interface:prefix", "wrong nlmsg length %d\n", length));
|
|
+ continue;
|
|
+ }
|
|
+ memset(index_table, 0, sizeof(struct rtattr *) * (IFA_MAX + 1));
|
|
+ if(!ifa->ifa_flags) {
|
|
+ rtatp = IFA_RTA(ifa);
|
|
+ while (RTA_OK(rtatp, length)) {
|
|
+ if (rtatp->rta_type <= IFA_MAX)
|
|
+ index_table[rtatp->rta_type] = rtatp;
|
|
+ rtatp = RTA_NEXT(rtatp,length);
|
|
+ }
|
|
+ if (index_table[IFA_ADDRESS]) {
|
|
+ in6p = (struct in6_addr *)RTA_DATA(index_table[IFA_ADDRESS]);
|
|
+ if(nlmp->nlmsg_type == RTM_DELADDR) {
|
|
+ sprintf(in6pAddr, "%04x%04x%04x%04x%04x%04x%04x%04x", NIP6(*in6p));
|
|
+ flag1 = -1;
|
|
+ } else {
|
|
+ sprintf(in6pAddr, "%04x%04x%04x%04x%04x%04x%04x%04x", NIP6(*in6p));
|
|
+ flag1 = 1;
|
|
+ }
|
|
+
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if(nlmp->nlmsg_type == RTM_NEWPREFIX) {
|
|
+ prefix = NLMSG_DATA(nlmp);
|
|
+ length = nlmp->nlmsg_len;
|
|
+ length -= NLMSG_LENGTH(sizeof(*prefix));
|
|
+
|
|
+ if (length < 0) {
|
|
+ DEBUGMSGTL(("access:interface:prefix", "wrong nlmsg length %d\n", length));
|
|
+ continue;
|
|
+ }
|
|
+ flag2 = 1;
|
|
+ if (prefix->prefix_flags & IF_PREFIX_ONLINK)
|
|
+ onlink = 1;
|
|
+ if (prefix->prefix_flags & IF_PREFIX_AUTOCONF)
|
|
+ autonomous = 1;
|
|
+ }
|
|
+ status -= NLMSG_ALIGN(len);
|
|
+ nlmp = (struct nlmsghdr*)((char*)nlmp + NLMSG_ALIGN(len));
|
|
+ }
|
|
+ if((flag1 == 1) && (flag2 == 1)){
|
|
+ if(!(new = net_snmp_create_prefix_info (onlink, autonomous, in6pAddr)))
|
|
+ DEBUGMSGTL(("access:interface:prefix", "Unable to create prefix info\n"));
|
|
+ else {
|
|
+ iret = net_snmp_update_prefix_info (listen_info->list_head, new, listen_info->lockinfo);
|
|
+ if(iret < 0) {
|
|
+ DEBUGMSGTL(("access:interface:prefix", "Unable to add/update prefix info\n"));
|
|
+ free(new);
|
|
+ }
|
|
+ if(iret == 2) /*Only when enrty already exists and we are only updating*/
|
|
+ free(new);
|
|
+ }
|
|
+ flag1 = flag2 = 0;
|
|
+ onlink = autonomous = 2; /*Set to defaults again*/
|
|
+ } else if (flag1 == -1) {
|
|
+ iret = net_snmp_delete_prefix_info (listen_info->list_head, in6pAddr, listen_info->lockinfo);
|
|
+ if(iret < 0)
|
|
+ DEBUGMSGTL(("access:interface:prefix", "Unable to delete the prefix info\n"));
|
|
+ if(!iret)
|
|
+ DEBUGMSGTL(("access:interface:prefix", "Unable to find the node to delete\n"));
|
|
+ flag1 = 0;
|
|
+ }
|
|
+ }
|
|
+
|
|
+}
|
|
+#endif
|
|
+
|
|
+
|
|
diff --git a/agent/mibgroup/ip-mib/data_access/ipaddress_common.c b/agent/mibgroup/ip-mib/data_access/ipaddress_common.c
|
|
index 396fc96..3eef0cc 100644
|
|
--- a/agent/mibgroup/ip-mib/data_access/ipaddress_common.c
|
|
+++ b/agent/mibgroup/ip-mib/data_access/ipaddress_common.c
|
|
@@ -304,6 +304,27 @@ netsnmp_access_ipaddress_entry_update(netsnmp_ipaddress_entry *lhs,
|
|
++changed;
|
|
lhs->ia_origin = rhs->ia_origin;
|
|
}
|
|
+
|
|
+ if (lhs->ia_onlink_flag != rhs->ia_onlink_flag) {
|
|
+ ++changed;
|
|
+ lhs->ia_onlink_flag = rhs->ia_onlink_flag;
|
|
+ }
|
|
+
|
|
+ if (lhs->ia_autonomous_flag != rhs->ia_autonomous_flag) {
|
|
+ ++changed;
|
|
+ lhs->ia_autonomous_flag = rhs->ia_autonomous_flag;
|
|
+ }
|
|
+
|
|
+ if (lhs->ia_prefered_lifetime != rhs->ia_prefered_lifetime) {
|
|
+ ++changed;
|
|
+ lhs->ia_prefered_lifetime = rhs->ia_prefered_lifetime;
|
|
+ }
|
|
+
|
|
+ if (lhs->ia_valid_lifetime != rhs->ia_valid_lifetime) {
|
|
+ ++changed;
|
|
+ lhs->ia_valid_lifetime = rhs->ia_valid_lifetime;
|
|
+ }
|
|
+
|
|
|
|
return changed;
|
|
}
|
|
@@ -428,3 +449,49 @@ static int _access_ipaddress_entry_compare_addr(const void *lhs,
|
|
*/
|
|
return memcmp(lh->ia_address, rh->ia_address, lh->ia_address_len);
|
|
}
|
|
+
|
|
+int
|
|
+netsnmp_ipaddress_flags_copy(u_long *ipAddressPrefixAdvPreferredLifetime,
|
|
+ u_long *ipAddressPrefixAdvValidLifetime,
|
|
+ u_long *ipAddressPrefixOnLinkFlag,
|
|
+ u_long *ipAddressPrefixAutonomousFlag,
|
|
+ u_long *ia_prefered_lifetime,
|
|
+ u_long *ia_valid_lifetime,
|
|
+ u_char *ia_onlink_flag,
|
|
+ u_char *ia_autonomous_flag)
|
|
+{
|
|
+
|
|
+ /*Copy all the flags*/
|
|
+ *ipAddressPrefixAdvPreferredLifetime = *ia_prefered_lifetime;
|
|
+ *ipAddressPrefixAdvValidLifetime = *ia_valid_lifetime;
|
|
+ *ipAddressPrefixOnLinkFlag = *ia_onlink_flag;
|
|
+ *ipAddressPrefixAutonomousFlag = *ia_autonomous_flag;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int
|
|
+netsnmp_ipaddress_prefix_origin_copy(u_long *ipAddressPrefixOrigin,
|
|
+ u_char ia_origin,
|
|
+ int flags,
|
|
+ u_long ipAddressAddrType)
|
|
+{
|
|
+ if(ipAddressAddrType == INETADDRESSTYPE_IPV4){
|
|
+ if(ia_origin == 6) /*Random*/
|
|
+ (*ipAddressPrefixOrigin) = 3 /*IPADDRESSPREFIXORIGINTC_WELLKNOWN*/;
|
|
+ else
|
|
+ (*ipAddressPrefixOrigin) = ia_origin;
|
|
+ } else {
|
|
+ if(ia_origin == 5) { /*Link Layer*/
|
|
+ if(!flags) /*Global address assigned by router adv*/
|
|
+ (*ipAddressPrefixOrigin) = 5 /*IPADDRESSPREFIXORIGINTC_ROUTERADV*/;
|
|
+ else
|
|
+ (*ipAddressPrefixOrigin) = 3 /*IPADDRESSPREFIXORIGINTC_WELLKNOWN*/;
|
|
+ }
|
|
+ else if(ia_origin == 6) /*Random*/
|
|
+ (*ipAddressPrefixOrigin) = 5 /*IPADDRESSPREFIXORIGINTC_ROUTERADV*/;
|
|
+ else
|
|
+ (*ipAddressPrefixOrigin) = ia_origin;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
diff --git a/agent/mibgroup/ip-mib/data_access/ipaddress_linux.c b/agent/mibgroup/ip-mib/data_access/ipaddress_linux.c
|
|
index 4616649..c6e5fec 100644
|
|
--- a/agent/mibgroup/ip-mib/data_access/ipaddress_linux.c
|
|
+++ b/agent/mibgroup/ip-mib/data_access/ipaddress_linux.c
|
|
@@ -12,6 +12,8 @@
|
|
#include <net-snmp/data_access/interface.h>
|
|
|
|
#include "ip-mib/ipAddressTable/ipAddressTable_constants.h"
|
|
+#include "ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_constants.h"
|
|
+#include "mibgroup/util_funcs.h"
|
|
|
|
#include <errno.h>
|
|
#include <sys/ioctl.h>
|
|
@@ -19,15 +21,29 @@
|
|
#if defined (NETSNMP_ENABLE_IPV6)
|
|
#include <linux/types.h>
|
|
#include <asm/types.h>
|
|
-#ifdef HAVE_LINUX_RTNETLINK_H
|
|
+#if defined(HAVE_PTHREAD_H) && defined(HAVE_LINUX_RTNETLINK_H)
|
|
#include <linux/netlink.h>
|
|
+#include <pthread.h>
|
|
#include <linux/rtnetlink.h>
|
|
-#endif
|
|
+#ifdef RTMGRP_IPV6_PREFIX
|
|
+#define SUPPORT_PREFIX_FLAGS 1
|
|
+#endif /* RTMGRP_IPV6_PREFIX */
|
|
+#endif /* HAVE_PTHREAD_H && HAVE_LINUX_RTNETLINK_H */
|
|
#endif
|
|
|
|
#include "ipaddress_ioctl.h"
|
|
-
|
|
+#ifdef SUPPORT_PREFIX_FLAGS
|
|
+extern prefix_cbx *prefix_head_list;
|
|
+extern pthread_mutex_t prefix_mutex_lock;
|
|
+#endif
|
|
int _load_v6(netsnmp_container *container, int idx_offset);
|
|
+#ifdef HAVE_LINUX_RTNETLINK_H
|
|
+int
|
|
+netsnmp_access_ipaddress_extra_prefix_info(int index,
|
|
+ u_long *preferedlt,
|
|
+ ulong *validlt,
|
|
+ char *addr);
|
|
+#endif
|
|
|
|
/*
|
|
* initialize arch specific storage
|
|
@@ -194,6 +210,7 @@ _load_v6(netsnmp_container *container, int idx_offset)
|
|
u_char *buf;
|
|
int if_index, pfx_len, scope, flags, rc = 0;
|
|
size_t in_len, out_len;
|
|
+ prefix_cbx prefix_val;
|
|
netsnmp_ipaddress_entry *entry;
|
|
_ioctl_extras *extras;
|
|
static int log_open_err = 1;
|
|
@@ -251,6 +268,7 @@ _load_v6(netsnmp_container *container, int idx_offset)
|
|
in_len = entry->ia_address_len = sizeof(entry->ia_address);
|
|
netsnmp_assert(16 == in_len);
|
|
out_len = 0;
|
|
+ entry->flags = flags;
|
|
buf = entry->ia_address;
|
|
if(1 != netsnmp_hex_to_binary(&buf, &in_len,
|
|
&out_len, 0, addr, ":")) {
|
|
@@ -341,6 +359,30 @@ _load_v6(netsnmp_container *container, int idx_offset)
|
|
entry->ia_storagetype = STORAGETYPE_PERMANENT;
|
|
|
|
/* xxx-rks: what can we do with scope? */
|
|
+#ifdef HAVE_LINUX_RTNETLINK_H
|
|
+ if(netsnmp_access_ipaddress_extra_prefix_info(entry->if_index, &entry->ia_prefered_lifetime
|
|
+ ,&entry->ia_valid_lifetime, addr) < 0){
|
|
+ DEBUGMSGTL(("access:ipaddress:container", "unable to fetch extra prefix info\n"));
|
|
+ }
|
|
+#else
|
|
+ entry->ia_prefered_lifetime = 0;
|
|
+ entry->ia_valid_lifetime = 0;
|
|
+#endif
|
|
+#ifdef SUPPORT_PREFIX_FLAGS
|
|
+ memset(&prefix_val, 0, sizeof(prefix_cbx));
|
|
+ if(net_snmp_find_prefix_info(&prefix_head_list, addr, &prefix_val, &prefix_mutex_lock) < 0) {
|
|
+ DEBUGMSGTL(("access:ipaddress:container", "unable to find info\n"));
|
|
+ entry->ia_onlink_flag = 1; /*Set by default as true*/
|
|
+ entry->ia_autonomous_flag = 2; /*Set by default as false*/
|
|
+
|
|
+ } else {
|
|
+ entry->ia_onlink_flag = prefix_val.ipAddressPrefixOnLinkFlag;
|
|
+ entry->ia_autonomous_flag = prefix_val.ipAddressPrefixAutonomousFlag;
|
|
+ }
|
|
+#else
|
|
+ entry->ia_onlink_flag = 1; /*Set by default as true*/
|
|
+ entry->ia_autonomous_flag = 2; /*Set by default as false*/
|
|
+#endif
|
|
|
|
/*
|
|
* add entry to container
|
|
@@ -448,4 +490,100 @@ netsnmp_access_other_info_get(int index, int family)
|
|
return addr;
|
|
#endif
|
|
}
|
|
+
|
|
+#ifdef HAVE_LINUX_RTNETLINK_H
|
|
+int
|
|
+netsnmp_access_ipaddress_extra_prefix_info(int index, u_long *preferedlt,
|
|
+ ulong *validlt, char *addr)
|
|
+{
|
|
+
|
|
+ struct {
|
|
+ struct nlmsghdr nlhdr;
|
|
+ struct ifaddrmsg ifaceinfo;
|
|
+ char buf[1024];
|
|
+ } req;
|
|
+
|
|
+ struct rtattr *rta;
|
|
+ int status;
|
|
+ char buf[16384];
|
|
+ char tmpaddr[40];
|
|
+ struct nlmsghdr *nlmp;
|
|
+ struct ifaddrmsg *rtmp;
|
|
+ struct rtattr *rtatp;
|
|
+ struct ifa_cacheinfo *cache_info;
|
|
+ struct in6_addr *in6p;
|
|
+ int rtattrlen;
|
|
+ int sd;
|
|
+ int reqaddr = 0;
|
|
+ sd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
|
|
+ if(sd < 0) {
|
|
+ snmp_log(LOG_ERR, "could not open netlink socket\n");
|
|
+ return -1;
|
|
+ }
|
|
+ memset(&req, 0, sizeof(req));
|
|
+ req.nlhdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
|
|
+ req.nlhdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
|
|
+ req.nlhdr.nlmsg_type = RTM_GETADDR;
|
|
+ req.ifaceinfo.ifa_family = AF_INET6;
|
|
+ rta = (struct rtattr *)(((char *)&req) + NLMSG_ALIGN(req.nlhdr.nlmsg_len));
|
|
+ rta->rta_len = RTA_LENGTH(16); /*For ipv6*/
|
|
+
|
|
+ status = send (sd, &req, req.nlhdr.nlmsg_len, 0);
|
|
+ if (status < 0) {
|
|
+ snmp_log(LOG_ERR, "could not send netlink request\n");
|
|
+ return -1;
|
|
+ }
|
|
+ status = recv (sd, buf, sizeof(buf), 0);
|
|
+ if (status < 0) {
|
|
+ snmp_log (LOG_ERR, "could not recieve netlink request\n");
|
|
+ return -1;
|
|
+ }
|
|
+ if (status == 0) {
|
|
+ snmp_log (LOG_ERR, "nothing to read\n");
|
|
+ return -1;
|
|
+ }
|
|
+ for (nlmp = (struct nlmsghdr *)buf; status > sizeof(*nlmp); ){
|
|
+
|
|
+ int len = nlmp->nlmsg_len;
|
|
+ int req_len = len - sizeof(*nlmp);
|
|
+
|
|
+ if (req_len < 0 || len > status) {
|
|
+ snmp_log (LOG_ERR, "invalid netlink message\n");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (!NLMSG_OK (nlmp, status)) {
|
|
+ snmp_log (LOG_ERR, "invalid NLMSG message\n");
|
|
+ return -1;
|
|
+ }
|
|
+ rtmp = (struct ifaddrmsg *)NLMSG_DATA(nlmp);
|
|
+ rtatp = (struct rtattr *)IFA_RTA(rtmp);
|
|
+ rtattrlen = IFA_PAYLOAD(nlmp);
|
|
+ if(index == rtmp->ifa_index) {
|
|
+ for (; RTA_OK(rtatp, rtattrlen); rtatp = RTA_NEXT(rtatp, rtattrlen)) {
|
|
+ if(rtatp->rta_type == IFA_ADDRESS) {
|
|
+ in6p = (struct in6_addr *)RTA_DATA(rtatp);
|
|
+ sprintf(tmpaddr, "%04x%04x%04x%04x%04x%04x%04x%04x", NIP6(*in6p));
|
|
+ if(!strcmp(tmpaddr ,addr))
|
|
+ reqaddr = 1;
|
|
+ }
|
|
+ if(rtatp->rta_type == IFA_CACHEINFO) {
|
|
+ cache_info = (struct ifa_cacheinfo *)RTA_DATA(rtatp);
|
|
+ if(reqaddr) {
|
|
+ reqaddr = 0;
|
|
+ *validlt = cache_info->ifa_valid;
|
|
+ *preferedlt = cache_info->ifa_prefered;
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ }
|
|
+ }
|
|
+ status -= NLMSG_ALIGN(len);
|
|
+ nlmp = (struct nlmsghdr*)((char*)nlmp + NLMSG_ALIGN(len));
|
|
+ }
|
|
+ close(sd);
|
|
+ return 0;
|
|
+}
|
|
+#endif
|
|
#endif
|
|
diff --git a/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable.c b/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable.c
|
|
index ecd26a0..9188f93 100644
|
|
--- a/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable.c
|
|
+++ b/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable.c
|
|
@@ -392,10 +392,9 @@ ipAddressPrefixOrigin_get(ipAddressPrefixTable_rowreq_ctx * rowreq_ctx,
|
|
* TODO:231:o: |-> Extract the current value of the ipAddressPrefixOrigin data.
|
|
* copy (* ipAddressPrefixOrigin_val_ptr ) from rowreq_ctx->data
|
|
*/
|
|
- (*ipAddressPrefixOrigin_val_ptr) =
|
|
- rowreq_ctx->data.ipAddressPrefixOrigin;
|
|
-
|
|
- return MFD_SUCCESS;
|
|
+ (*ipAddressPrefixOrigin_val_ptr) = rowreq_ctx->data.ipAddressPrefixOrigin;
|
|
+
|
|
+ return MFD_SUCCESS;
|
|
} /* ipAddressPrefixOrigin_get */
|
|
|
|
/*---------------------------------------------------------------------
|
|
diff --git a/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_constants.h b/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_constants.h
|
|
index d9c0cb0..6dd440d 100644
|
|
--- a/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_constants.h
|
|
+++ b/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_constants.h
|
|
@@ -137,3 +137,17 @@ extern "C" {
|
|
}
|
|
#endif
|
|
#endif /* IPADDRESSPREFIXTABLE_OIDS_H */
|
|
+/****************************************************************
|
|
+* Additional constants and definitions for common implementation
|
|
+*/
|
|
+#define INFINITY_LIFE_TIME 0xFFFFFFFFU
|
|
+#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])
|
|
+
|
|
diff --git a/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_data_access.c b/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_data_access.c
|
|
index 4cda4de..9e0b5fe 100644
|
|
--- a/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_data_access.c
|
|
+++ b/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_data_access.c
|
|
@@ -251,6 +251,23 @@ ipAddressPrefixTable_container_load(netsnmp_container *container)
|
|
ia_address_len,
|
|
addr_rowreq_ctx->data->
|
|
ia_prefix_len);
|
|
+ netsnmp_ipaddress_flags_copy(&rowreq_ctx->data.
|
|
+ ipAddressPrefixAdvPreferredLifetime,
|
|
+ &rowreq_ctx->data.
|
|
+ ipAddressPrefixAdvValidLifetime,
|
|
+ &rowreq_ctx->data.
|
|
+ ipAddressPrefixOnLinkFlag,
|
|
+ &rowreq_ctx->data.
|
|
+ ipAddressPrefixAutonomousFlag,
|
|
+ &addr_rowreq_ctx->data->
|
|
+ ia_prefered_lifetime,
|
|
+ &addr_rowreq_ctx->data->
|
|
+ ia_valid_lifetime,
|
|
+ &addr_rowreq_ctx->data->
|
|
+ ia_onlink_flag,
|
|
+ &addr_rowreq_ctx->data->
|
|
+ ia_autonomous_flag);
|
|
+
|
|
if (MFD_SUCCESS !=
|
|
ipAddressPrefixTable_indexes_set(rowreq_ctx,
|
|
addr_rowreq_ctx->data->
|
|
@@ -277,8 +294,14 @@ ipAddressPrefixTable_container_load(netsnmp_container *container)
|
|
* TODO:352:r: | |-> populate ipAddressPrefixTable data context.
|
|
* Populate data context here. (optionally, delay until row prep)
|
|
*/
|
|
- rowreq_ctx->data.ipAddressPrefixOrigin =
|
|
- addr_rowreq_ctx->data->ia_origin;
|
|
+ netsnmp_ipaddress_prefix_origin_copy(&rowreq_ctx->data.
|
|
+ ipAddressPrefixOrigin,
|
|
+ addr_rowreq_ctx->data->
|
|
+ ia_origin,
|
|
+ addr_rowreq_ctx->data->
|
|
+ flags,
|
|
+ addr_rowreq_ctx->tbl_idx.
|
|
+ ipAddressAddrType);
|
|
|
|
/** defer the rest til row prep */
|
|
|
|
diff --git a/agent/mibgroup/util_funcs.c b/agent/mibgroup/util_funcs.c
|
|
index 26826f7..d060721 100644
|
|
--- a/agent/mibgroup/util_funcs.c
|
|
+++ b/agent/mibgroup/util_funcs.c
|
|
@@ -100,7 +100,9 @@
|
|
# include <ndir.h>
|
|
# endif
|
|
#endif
|
|
-
|
|
+#ifdef HAVE_PTHREAD_H
|
|
+#include <pthread.h>
|
|
+#endif
|
|
#include <net-snmp/net-snmp-includes.h>
|
|
#include <net-snmp/agent/net-snmp-agent-includes.h>
|
|
|
|
@@ -1292,3 +1294,151 @@ get_pid_from_inode(unsigned long long inode)
|
|
}
|
|
|
|
#endif /* #ifdef linux */
|
|
+
|
|
+#if defined(HAVE_PTHREAD_H)
|
|
+prefix_cbx *net_snmp_create_prefix_info(unsigned long OnLinkFlag,
|
|
+ unsigned long AutonomousFlag,
|
|
+ char *in6ptr)
|
|
+{
|
|
+ prefix_cbx *node = SNMP_MALLOC_TYPEDEF(prefix_cbx);
|
|
+ if(!in6ptr) {
|
|
+ free(node);
|
|
+ return NULL;
|
|
+ }
|
|
+ if(!node) {
|
|
+ free(node);
|
|
+ return NULL;
|
|
+ }
|
|
+ node->next_info = NULL;
|
|
+ node->ipAddressPrefixOnLinkFlag = OnLinkFlag;
|
|
+ node->ipAddressPrefixAutonomousFlag = AutonomousFlag;
|
|
+ memcpy(node->in6p, in6ptr, sizeof(node->in6p));
|
|
+
|
|
+ return node;
|
|
+}
|
|
+
|
|
+int net_snmp_find_prefix_info(prefix_cbx **head,
|
|
+ char *address,
|
|
+ prefix_cbx *node_to_find,
|
|
+ pthread_mutex_t *lockid)
|
|
+{
|
|
+ int iret;
|
|
+ memset(node_to_find, 0, sizeof(prefix_cbx));
|
|
+ if(!*head)
|
|
+ return -1;
|
|
+ memcpy(node_to_find->in6p, address, sizeof(node_to_find->in6p));
|
|
+
|
|
+ iret = net_snmp_search_update_prefix_info(head, node_to_find, 1, lockid);
|
|
+ if(iret < 0) {
|
|
+ DEBUGMSGTL(("util_funcs:prefix", "Unable to search the list\n"));
|
|
+ return -1;
|
|
+ } else if (!iret) {
|
|
+ DEBUGMSGTL(("util_funcs:prefix", "Could not find prefix info\n"));
|
|
+ return -1;
|
|
+ } else
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int net_snmp_update_prefix_info(prefix_cbx **head,
|
|
+ prefix_cbx *node_to_update,
|
|
+ pthread_mutex_t *lockid)
|
|
+{
|
|
+ int iret;
|
|
+ iret = net_snmp_search_update_prefix_info(head, node_to_update, 0, lockid);
|
|
+ if(iret < 0) {
|
|
+ DEBUGMSGTL(("util_funcs:prefix", "Unable to update prefix info\n"));
|
|
+ return -1;
|
|
+ } else if (!iret) {
|
|
+ DEBUGMSGTL(("util_funcs:prefix", "Unable to find the node to update\n"));
|
|
+ return -1;
|
|
+ } else
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int net_snmp_search_update_prefix_info(prefix_cbx **head,
|
|
+ prefix_cbx *node_to_use,
|
|
+ int functionality,
|
|
+ pthread_mutex_t *lockid)
|
|
+{
|
|
+
|
|
+ /* We define functionality based on need *
|
|
+ * 0 - Need to do a search and update. We have to provide the node_to_use structure filled fully *
|
|
+ * 1 - Need to do only search. Provide the node_to_use with in6p value filled */
|
|
+
|
|
+ prefix_cbx *temp_node;
|
|
+ netsnmp_assert(NULL != head);
|
|
+ netsnmp_assert(NULL != node_to_use);
|
|
+
|
|
+ if(functionality > 1)
|
|
+ return -1;
|
|
+ if(!node_to_use)
|
|
+ return -1;
|
|
+
|
|
+
|
|
+ if (!functionality) {
|
|
+ if (!*head) {
|
|
+ *head = node_to_use;
|
|
+ return 1;
|
|
+ }
|
|
+
|
|
+ pthread_mutex_lock( lockid );
|
|
+ for (temp_node = *head; temp_node->next_info != NULL ; temp_node = temp_node->next_info) {
|
|
+ if (0 == strcmp(temp_node->in6p, node_to_use->in6p)) {
|
|
+ temp_node->ipAddressPrefixOnLinkFlag = node_to_use->ipAddressPrefixOnLinkFlag;
|
|
+ temp_node->ipAddressPrefixAutonomousFlag = node_to_use->ipAddressPrefixAutonomousFlag;
|
|
+ pthread_mutex_unlock( lockid );
|
|
+ return 2;
|
|
+ }
|
|
+ }
|
|
+ temp_node->next_info = node_to_use;
|
|
+ pthread_mutex_unlock( lockid );
|
|
+ return 1;
|
|
+ } else {
|
|
+ pthread_mutex_lock( lockid );
|
|
+ for (temp_node = *head; temp_node != NULL ; temp_node = temp_node->next_info) {
|
|
+ if (0 == strcmp(temp_node->in6p, node_to_use->in6p)) {
|
|
+ /*need yo put sem here as i read here */
|
|
+ node_to_use->ipAddressPrefixOnLinkFlag = temp_node->ipAddressPrefixOnLinkFlag;
|
|
+ node_to_use->ipAddressPrefixAutonomousFlag = temp_node->ipAddressPrefixAutonomousFlag;
|
|
+ pthread_mutex_unlock( lockid );
|
|
+ return 1;
|
|
+ }
|
|
+ }
|
|
+ pthread_mutex_unlock( lockid );
|
|
+ return 0;
|
|
+ }
|
|
+}
|
|
+
|
|
+int net_snmp_delete_prefix_info(prefix_cbx **head,
|
|
+ char *address,
|
|
+ pthread_mutex_t *lockid)
|
|
+{
|
|
+
|
|
+ prefix_cbx *temp_node,*prev_node;
|
|
+ if(!address)
|
|
+ return -1;
|
|
+ if(!head)
|
|
+ return -1;
|
|
+
|
|
+ /*Need to acquire lock here */
|
|
+ pthread_mutex_lock( lockid );
|
|
+ for (temp_node = *head, prev_node = NULL; temp_node;
|
|
+ prev_node = temp_node, temp_node = temp_node->next_info) {
|
|
+
|
|
+ if (temp_node->in6p && strcmp(temp_node->in6p, address) == 0) {
|
|
+ if (prev_node)
|
|
+ prev_node->next_info = temp_node->next_info;
|
|
+ else
|
|
+ *head = temp_node->next_info;
|
|
+ free(temp_node);
|
|
+ pthread_mutex_unlock( lockid );
|
|
+ return 1;
|
|
+ }
|
|
+
|
|
+ }
|
|
+ /*Release Lock here */
|
|
+ pthread_mutex_unlock( lockid );
|
|
+ return 0;
|
|
+}
|
|
+#endif
|
|
+
|
|
diff --git a/agent/mibgroup/util_funcs.h b/agent/mibgroup/util_funcs.h
|
|
index 4a0b99e..aa4257f 100644
|
|
--- a/agent/mibgroup/util_funcs.h
|
|
+++ b/agent/mibgroup/util_funcs.h
|
|
@@ -8,8 +8,23 @@
|
|
extern "C" {
|
|
#endif
|
|
|
|
+#ifdef HAVE_PTHREAD_H
|
|
+#include <pthread.h>
|
|
+#endif
|
|
#include "struct.h"
|
|
|
|
+typedef struct prefix_info
|
|
+{
|
|
+ struct prefix_info *next_info;
|
|
+ unsigned long ipAddressPrefixOnLinkFlag;
|
|
+ unsigned long ipAddressPrefixAutonomousFlag;
|
|
+ char in6p[40];
|
|
+}prefix_cbx;
|
|
+typedef struct
|
|
+{
|
|
+ prefix_cbx **list_head;
|
|
+ pthread_mutex_t *lockinfo;
|
|
+}netsnmp_prefix_listen_info;
|
|
void Exit(int);
|
|
int shell_command(struct extensible *);
|
|
int exec_command(struct extensible *);
|
|
@@ -37,6 +52,32 @@ const char *make_tempfile(void);
|
|
#ifdef linux
|
|
unsigned int get_pid_from_inode(unsigned long long);
|
|
#endif
|
|
+prefix_cbx *net_snmp_create_prefix_info(unsigned long OnLinkFlag,
|
|
+ unsigned long AutonomousFlag,
|
|
+ char *in6ptr);
|
|
+int net_snmp_find_prefix_info(prefix_cbx **head,
|
|
+ char *address,
|
|
+ prefix_cbx *node_to_find,
|
|
+ pthread_mutex_t *lockid);
|
|
+int net_snmp_update_prefix_info(prefix_cbx **head,
|
|
+ prefix_cbx *node_to_update,
|
|
+ pthread_mutex_t *lockid);
|
|
+int net_snmp_search_update_prefix_info(prefix_cbx **head,
|
|
+ prefix_cbx *node_to_use,
|
|
+ int functionality,
|
|
+ pthread_mutex_t *lockid);
|
|
+int net_snmp_delete_prefix_info(prefix_cbx **head,
|
|
+ char *address,
|
|
+ pthread_mutex_t *lockid);
|
|
+#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 satosin(x) ((struct sockaddr_in *) &(x))
|
|
#define SOCKADDR(x) (satosin(x)->sin_addr.s_addr)
|
|
diff --git a/include/net-snmp/data_access/ipaddress.h b/include/net-snmp/data_access/ipaddress.h
|
|
index b751b47..37083be 100644
|
|
--- a/include/net-snmp/data_access/ipaddress.h
|
|
+++ b/include/net-snmp/data_access/ipaddress.h
|
|
@@ -47,7 +47,10 @@ typedef struct netsnmp_ipaddress_s {
|
|
u_char ia_status; /* IpAddressStatus (1-7) */
|
|
u_char ia_origin; /* IpAddressOrigin (1-6) */
|
|
u_char ia_storagetype; /* IpAddressStorageType (1-5) */
|
|
-
|
|
+ u_char ia_onlink_flag; /* IpOnlinkFlag */
|
|
+ u_char ia_autonomous_flag; /*IpAutonomousFlag */
|
|
+ u_long ia_prefered_lifetime;/*IpPreferedLifeTime*/
|
|
+ u_long ia_valid_lifetime;/*IpValidLifeTime*/
|
|
netsnmp_data_list *arch_data; /* arch specific data */
|
|
|
|
} netsnmp_ipaddress_entry;
|
|
@@ -142,7 +145,19 @@ int netsnmp_ipaddress_prefix_copy(u_char *dst, u_char *src,
|
|
|
|
int netsnmp_ipaddress_ipv4_prefix_len(in_addr_t mask);
|
|
|
|
-
|
|
+int netsnmp_ipaddress_flags_copy(u_long *ipAddressPrefixAdvPreferredLifetime,
|
|
+ u_long *ipAddressPrefixAdvValidLifetime,
|
|
+ u_long *ipAddressPrefixOnLinkFlag,
|
|
+ u_long *ipAddressPrefixAutonomousFlag,
|
|
+ u_long *ia_prefered_lifetime,
|
|
+ u_long *ia_valid_lifetime,
|
|
+ u_char *ia_onlink_flag,
|
|
+ u_char *ia_autonomous_flag);
|
|
+
|
|
+int netsnmp_ipaddress_prefix_origin_copy(u_long *ipAddressPrefixOrigin,
|
|
+ u_char ia_origin,
|
|
+ int flags,
|
|
+ u_long ipAddressAddrType);
|
|
|
|
/**---------------------------------------------------------------------*/
|
|
|
|
--
|
|
1.6.0.2
|
|
|