Search
j0ke.net Open Build Service
>
Projects
>
GFS
>
net-snmp
> Fix-for-Internet-Address-Prefix-Table.patch
Sign Up
|
Log In
Username
Password
Cancel
Overview
Repositories
Revisions
Requests
Users
Advanced
Attributes
Meta
File Fix-for-Internet-Address-Prefix-Table.patch of Package net-snmp
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