Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > c0394d3068b44395994f031447c8052d > files > 22

net-snmp-5.3.2.2-7.el5_4.2.src.rpm

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)