Fix ipAddressPrefixTable Source: https://sourceforge.net/tracker/index.php?func=detail&aid=1705594&group_id=12694&atid=312694 Index: include/net-snmp/data_access/ipaddress.h =================================================================== --- include/net-snmp/data_access/ipaddress.h (revision 16331) +++ include/net-snmp/data_access/ipaddress.h (working copy) @@ -47,7 +47,10 @@ 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_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); /**---------------------------------------------------------------------*/ Index: agent/mibgroup/if-mib/data_access/interface_linux.c =================================================================== --- agent/mibgroup/if-mib/data_access/interface_linux.c (revision 16331) +++ agent/mibgroup/if-mib/data_access/interface_linux.c (working copy) @@ -29,6 +29,7 @@ #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> @@ -38,6 +39,13 @@ #include <linux/sockios.h> #include <linux/if_ether.h> +#ifdef INET6 +#include <pthread.h> +#include <linux/rtnetlink.h> +#ifdef RTMGRP_IPV6_PREFIX +#define SUPPORT_PREFIX_FLAGS 1 +#endif /* RTMGRP_IPV6_PREFIX */ +#endif /* INET6 */ unsigned int netsnmp_linux_interface_get_if_speed(int fd, const char *name); #ifdef HAVE_LINUX_ETHTOOL_H @@ -55,6 +65,16 @@ #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) { @@ -87,6 +107,13 @@ 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 } /* @@ -865,3 +892,162 @@ } 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: 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")); + 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")); + 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")); + 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")); + 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")); + 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")); + if(!iret) + DEBUGMSGTL(("access:interface:prefix","Unable to find the node to delete")); + flag1 = 0; + } + } + +} +#endif + + Index: agent/mibgroup/ip-mib/data_access/ipaddress_common.c =================================================================== --- agent/mibgroup/ip-mib/data_access/ipaddress_common.c (revision 16331) +++ agent/mibgroup/ip-mib/data_access/ipaddress_common.c (working copy) @@ -304,7 +304,28 @@ ++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 @@ */ 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; +} + Index: agent/mibgroup/ip-mib/data_access/ipaddress_linux.c =================================================================== --- agent/mibgroup/ip-mib/data_access/ipaddress_linux.c (revision 16331) +++ agent/mibgroup/ip-mib/data_access/ipaddress_linux.c (working copy) @@ -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,12 +21,29 @@ #if defined (INET6) #include <linux/types.h> #include <asm/types.h> +#include <linux/netlink.h> +#include <pthread.h> #include <linux/rtnetlink.h> +#ifdef RTMGRP_IPV6_PREFIX +#define SUPPORT_PREFIX_FLAGS 1 +#endif /* RTMGRP_IPV6_PREFIX */ #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 @@ -185,6 +203,7 @@ 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; @@ -242,6 +261,7 @@ 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, ":")) { @@ -336,7 +356,31 @@ 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")); + } +#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")); + 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 */ @@ -438,5 +482,101 @@ close(sd); return addr; } + +#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 Index: agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_data_access.c =================================================================== --- agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_data_access.c (revision 16331) +++ agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_data_access.c (working copy) @@ -251,6 +251,23 @@ 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 @@ * 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 */ Index: agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable.c =================================================================== --- agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable.c (revision 16331) +++ agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable.c (working copy) @@ -392,10 +392,9 @@ * 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 */ /*--------------------------------------------------------------------- Index: agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_constants.h =================================================================== --- agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_constants.h (revision 16331) +++ agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_constants.h (working copy) @@ -137,3 +137,17 @@ } #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]) + Index: agent/mibgroup/util_funcs.c =================================================================== --- agent/mibgroup/util_funcs.c (revision 16331) +++ agent/mibgroup/util_funcs.c (working copy) @@ -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> @@ -1104,3 +1106,151 @@ *max_idx = table->next_index - 1; return table->data; } + + +#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")); + return -1; + } else if (!iret) { + DEBUGMSGTL(("util_funcs:prefix","Could not find prefix info")); + 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")); + return -1; + } else if (!iret) { + DEBUGMSGTL(("util_funcs:prefix","Unable to find the node to update")); + 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 Index: agent/mibgroup/util_funcs.h =================================================================== --- agent/mibgroup/util_funcs.h (revision 16331) +++ agent/mibgroup/util_funcs.h (working copy) @@ -9,7 +9,18 @@ #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 +48,32 @@ #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)