$NetBSD: patch-de,v 1.8 2012/05/17 14:37:07 marino Exp $

--- agent/mibgroup/mibII/ipv6.c.orig	2010-12-08 13:17:10.000000000 +0000
+++ agent/mibgroup/mibII/ipv6.c
@@ -11,7 +11,7 @@
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/socket.h>
-#if (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(darwin)
+#if defined(freebsd3) || defined(darwin)
 # if HAVE_SYS_SOCKETVAR_H
 #  include <sys/socketvar.h>
 # endif
@@ -51,7 +51,13 @@
 #endif
 #include <net/if.h>
 #if HAVE_NET_IF_VAR_H
+#  ifdef __DragonFly__
+#  define _KERNEL_STRUCTURES
+#  endif
 #include <net/if_var.h>
+#  ifdef __DragonFly__
+#  undef _KERNEL_STRUCTURES
+#  endif
 #endif
 #if HAVE_NET_IF_DL_H
 #include <net/if_dl.h>
@@ -80,7 +86,7 @@
 # include <netinet6/ip6_var.h>
 #endif
 #include <net/route.h>
-#if (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(darwin)
+#if defined(freebsd3) || defined(darwin)
 # if HAVE_NETINET_IN_PCB_H
 #  include <netinet/in_pcb.h>
 # endif
@@ -616,7 +622,7 @@ if_getifnet(int idx, struct ifnet *resul
             memcpy(result, &tmp, sizeof(tmp));
             return 0;
         }
-#if (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(darwin)
+#if defined(freebsd3) || defined(darwin)
         q = (caddr_t) TAILQ_NEXT(&tmp, if_link);
 #else
 # if defined(__NetBSD__) || defined(__OpenBSD__)
@@ -846,13 +852,36 @@ var_ifv6Entry(register struct variable *
         {
             struct ifnet    ifnet;
             struct ifaddr   ifaddr;
+#if defined(__DragonFly__) && __DragonFly_version >= 197700
+            struct ifaddr_container ifac;
+            struct ifaddrhead head;
+#endif
             static struct sockaddr_dl sdl;
             caddr_t         ifa;
 
             if (if_getifnet(interface, &ifnet) < 0)
                 break;
-#if (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(darwin)
+#if defined(freebsd3) || defined(darwin)
+# if defined(__DragonFly__) && __DragonFly_version >= 197700
+            /*
+             * Locate ifaddr head on CPU0
+             */
+            if (!NETSNMP_KLOOKUP(ifnet.if_addrheads, (char *)&head, sizeof(head))) {
+                DEBUGMSGTL(("mibII/ipv6:var_ipv6", "klookup head failed\n"));
+                break;
+            }
+            if (TAILQ_FIRST(&head) != NULL) {
+                 if (!NETSNMP_KLOOKUP(TAILQ_FIRST(&head), (char *) &ifac, sizeof(ifac))) {
+                    DEBUGMSGTL(("mibII/ipv6:var_ipv6", "klookup ifac failed\n"));
+                    break;
+                }
+                ifa = (caddr_t)ifac.ifa;
+            } else {
+                ifa = NULL;
+            }
+# else
             ifa = (caddr_t) TAILQ_FIRST(&ifnet.if_addrhead);
+# endif
 #else
 # if defined(__NetBSD__) || defined(__OpenBSD__)
             ifa = (caddr_t) TAILQ_FIRST(&ifnet.if_addrlist);
@@ -878,8 +907,20 @@ var_ifv6Entry(register struct variable *
                     *var_len = sdl.sdl_alen;
                     return (u_char *) (sdl.sdl_data + sdl.sdl_nlen);
                 }
-#if (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(darwin)
+#if defined(freebsd3) || defined(darwin)
+# if defined(__DragonFly__) && __DragonFly_version >= 197700
+                if (TAILQ_NEXT(&ifac, ifa_link) == NULL) {
+                    ifa = NULL;
+                } else {
+                    if (!NETSNMP_KLOOKUP(TAILQ_NEXT(&ifac, ifa_link), (char *)&ifac, sizeof(ifac))) {
+                        DEBUGMSGTL(("mibII/ipv6:var_ipv6", "klookup ifac next failed\n"));
+                        break;
+                    }
+                    ifa = (caddr_t)ifac.ifa;
+                }
+# else
                 ifa = (caddr_t) TAILQ_NEXT(&ifaddr, ifa_link);
+# endif
 #else
 # if defined(__NetBSD__) || defined(__OpenBSD__)
                 ifa = (caddr_t) TAILQ_NEXT(&ifaddr, ifa_list);
@@ -1285,7 +1326,11 @@ var_udp6(register struct variable * vp,
 #if defined(__NetBSD__) && __NetBSD_Version__ >= 106250000	/*1.6Y*/
     struct inpcbtable udbtable;
     caddr_t	    first;
-#elif (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(darwin)
+#elif defined(dragonfly)
+    char           *sysctl_buf;
+    struct xinpcb  *xig;
+    size_t          sysctl_len;
+#elif defined(freebsd3) || defined(darwin)
     char           *sysctl_buf;
     struct xinpgen *xig, *oxig;
 #else
@@ -1300,10 +1345,31 @@ var_udp6(register struct variable * vp,
     if (!auto_nlist("udbtable", (char *) &udbtable, sizeof(udbtable)))
         return NULL;
     first = p = (caddr_t)udbtable.inpt_queue.cqh_first;
-#elif !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined(darwin)
+#elif !defined(freebsd3) && !defined(darwin)
     if (!auto_nlist("udb6", (char *) &udb6, sizeof(udb6)))
         return NULL;
     p = (caddr_t) udb6.in6p_next;
+#elif defined(dragonfly)
+    {
+        const char     *udblist = "net.inet.udp.pcblist";
+        const char     *pp = udblist;
+
+        if (sysctlbyname(udblist, 0, &sysctl_len, 0, 0) < 0)
+            return NULL;
+        if ((sysctl_buf = malloc(sysctl_len)) == NULL)
+            return NULL;
+        udblist = pp;
+        if (sysctlbyname(udblist, sysctl_buf, &sysctl_len, 0, 0) < 0) {
+            free(sysctl_buf);
+            return NULL;
+        }
+        xig = (struct xinpcb *) sysctl_buf;
+	if (xig->xi_len != sizeof(*xig)) {
+	    free(sysctl_buf);
+	    return NULL;
+	}
+        p = (caddr_t) ((char *) xig); /* silence compiler warning */
+    }
 #else
     {
         const char     *udblist = "net.inet.udp.pcblist";
@@ -1331,15 +1397,17 @@ var_udp6(register struct variable * vp,
     while (
 #if defined(__NetBSD__) && __NetBSD_Version__ >= 106250000	/*1.6Y*/
               p &&  p != first
-#elif !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined(darwin)
+#elif !defined(freebsd3) && !defined(darwin)
               p && (u_long) p != auto_nlist_value("udb6")
+#elif defined(dragonfly)
+	      (char *)xig + xig->xi_len <= sysctl_buf + sysctl_len
 #else
               xig->xig_len > sizeof(struct xinpgen)
 #endif
         ) {
         DEBUGMSGTL(("mibII/ipv6", "looping: p=%x\n", p));
 
-#if !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined(darwin)
+#if !defined(freebsd3) && !defined(darwin)
         if (!NETSNMP_KLOOKUP(p, (char *) &in6pcb, sizeof(in6pcb))) {
             DEBUGMSGTL(("mibII/ipv6", "klookup fail for udb6 at %x\n",
                         p));
@@ -1352,7 +1420,7 @@ var_udp6(register struct variable * vp,
 #if defined(__NetBSD__) && __NetBSD_Version__ >= 106250000	/*1.6Y*/
         if (in6pcb.in6p_af != AF_INET6)
             goto skip;
-#elif (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(darwin)
+#elif defined(freebsd3) || defined(darwin)
         if (0 == (in6pcb.inp_vflag & INP_IPV6))
             goto skip;
 #endif
@@ -1395,13 +1463,15 @@ var_udp6(register struct variable * vp,
       skip:
 #if defined(__NetBSD__) && __NetBSD_Version__ >= 106250000	/*1.6Y*/
         p = (caddr_t)in6pcb.in6p_queue.cqe_next;
-#elif !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined(darwin)
+#elif !defined(freebsd3) && !defined(darwin)
         p = (caddr_t) in6pcb.in6p_next;
+#elif defined(__DragonFly__)
+        xig = (struct xinpcb *) ((char *) xig + xig->xi_len);
 #else
         xig = (struct xinpgen *) ((char *) xig + xig->xig_len);
 #endif
     }
-#if (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(darwin)
+#if defined(freebsd3) || defined(darwin)
     free(sysctl_buf);
 #endif
     DEBUGMSGTL(("mibII/ipv6", "found=%d\n", found));
@@ -1460,7 +1530,7 @@ var_tcp6(register struct variable * vp,
 #if defined(__NetBSD__) && __NetBSD_Version__ >= 106250000	/*1.6Y*/
     struct inpcbtable tcbtable;
     caddr_t	    first;
-#elif (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(darwin)
+#elif defined(freebsd3) || defined(darwin)
     char           *sysctl_buf;
     struct xinpgen *xig, *oxig;
 #else
@@ -1490,7 +1560,7 @@ var_tcp6(register struct variable * vp,
     if (!auto_nlist("tcbtable", (char *) &tcbtable, sizeof(tcbtable)))
         return NULL;
     first = p = (caddr_t)tcbtable.inpt_queue.cqh_first;
-#elif !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined(darwin)
+#elif !defined(freebsd3) && !defined(darwin)
     if (!auto_nlist("tcb6", (char *) &tcb6, sizeof(tcb6)))
         return NULL;
     p = (caddr_t) tcb6.in6p_next;
@@ -1521,7 +1591,7 @@ var_tcp6(register struct variable * vp,
     while (
 #if defined(__NetBSD__) && __NetBSD_Version__ >= 106250000	/*1.6Y*/
               p &&  p != first
-#elif !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined(darwin)
+#elif !defined(freebsd3) && !defined(darwin)
               p && (u_long) p != auto_nlist_value("tcb6")
 #else
               xig->xig_len > sizeof(struct xinpgen)
@@ -1529,7 +1599,7 @@ var_tcp6(register struct variable * vp,
         ) {
         DEBUGMSGTL(("mibII/ipv6", "looping: p=%x\n", p));
 
-#if !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined(darwin)
+#if !defined(freebsd3) && !defined(darwin)
         if (!NETSNMP_KLOOKUP(p, (char *) &in6pcb, sizeof(in6pcb))) {
             DEBUGMSGTL(("mibII/ipv6", "klookup fail for tcb6 at %x\n",
                         p));
@@ -1542,7 +1612,7 @@ var_tcp6(register struct variable * vp,
 #if defined(__NetBSD__) && __NetBSD_Version__ >= 106250000	/*1.6Y*/
         if (in6pcb.in6p_af != AF_INET6)
             goto skip;
-#elif (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(darwin)
+#elif defined(freebsd3) || defined(darwin)
         if (0 == (in6pcb.inp_vflag & INP_IPV6))
             goto skip;
 #endif
@@ -1599,13 +1669,13 @@ var_tcp6(register struct variable * vp,
       skip:
 #if defined(__NetBSD__) && __NetBSD_Version__ >= 106250000	/*1.6Y*/
         p = (caddr_t)in6pcb.in6p_queue.cqe_next;
-#elif !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined(darwin)
+#elif !defined(freebsd3) && !defined(darwin)
         p = (caddr_t) in6pcb.in6p_next;
 #else
         xig = (struct xinpgen *) ((char *) xig + xig->xig_len);
 #endif
     }
-#if (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(darwin)
+#if defined(freebsd3) || defined(darwin)
     free(sysctl_buf);
 #endif
     DEBUGMSGTL(("mibII/ipv6", "found=%d\n", found));
@@ -1697,7 +1767,11 @@ var_tcp6(register struct variable * vp,
 #if defined(__NetBSD__) && __NetBSD_Version__ >= 106250000	/*1.6Y*/
     struct inpcbtable tcbtable;
     caddr_t	    first;
-#elif (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(darwin)
+#elif defined(dragonfly)
+    char           *sysctl_buf;
+    size_t          sysctl_len;
+    struct xtcpcb  *xtp;
+#elif defined(freebsd3) || defined(darwin)
     char           *sysctl_buf;
     struct xinpgen *xig, *oxig;
 #else
@@ -1712,10 +1786,31 @@ var_tcp6(register struct variable * vp,
     if (!auto_nlist("tcbtable", (char *) &tcbtable, sizeof(tcbtable)))
         return NULL;
     first = p = (caddr_t)tcbtable.inpt_queue.cqh_first;
-#elif !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined(darwin)
+#elif !defined(freebsd3) && !defined(darwin)
     if (!auto_nlist("tcb6", (char *) &tcb6, sizeof(tcb6)))
         return NULL;
     p = (caddr_t) tcb6.in6p_next;
+#elif defined(dragonfly)
+    {
+        const char     *tcblist = "net.inet.tcp.pcblist";
+        const char     *pp = tcblist;
+
+        if (sysctlbyname(tcblist, 0, &sysctl_len, 0, 0) < 0)
+            return NULL;
+        if ((sysctl_buf = malloc(sysctl_len)) == NULL)
+            return NULL;
+        tcblist = pp;
+        if (sysctlbyname(tcblist, sysctl_buf, &sysctl_len, 0, 0) < 0) {
+            free(sysctl_buf);
+            return NULL;
+        }
+        xtp = (struct xtcpcb *) sysctl_buf;
+	if (xtp->xt_len != sizeof(*xtp)) {
+	    free(sysctl_buf);
+	    return NULL;
+	}
+        p = (caddr_t) ((char *) xtp); /* silence compiler warning */
+    }
 #else
     {
         const char     *tcblist = "net.inet.tcp.pcblist";
@@ -1732,7 +1827,8 @@ var_tcp6(register struct variable * vp,
             return NULL;
         }
         oxig = (struct xinpgen *) sysctl_buf;
-        xig = (struct xinpgen *) ((char *) oxig + oxig->xig_len);
+        xig = (struct xinpgen *) ((char *) oxtp + oxtp->xt_len);
+	if (oxig
         p = (caddr_t) ((char *) xig); /* silence compiler warning */
     }
 #endif
@@ -1743,28 +1839,32 @@ var_tcp6(register struct variable * vp,
     while (
 #if defined(__NetBSD__) && __NetBSD_Version__ >= 106250000	/*1.6Y*/
               p && p != first
-#elif !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined(darwin)
+#elif !defined(freebsd3) && !defined(darwin)
               p && (u_long) p != auto_nlist_value("tcb6")
+#elif defined(dragonfly)
+	      (char *)xtp + xtp->xt_len < sysctl_buf + sysctl_len
 #else
               xig->xig_len > sizeof(struct xinpgen)
 #endif
         ) {
         DEBUGMSGTL(("mibII/ipv6", "looping: p=%x\n", p));
 
-#if !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined(darwin)
+#if !defined(freebsd3) && !defined(darwin)
         if (!NETSNMP_KLOOKUP(p, (char *) &in6pcb, sizeof(in6pcb))) {
             DEBUGMSGTL(("mibII/ipv6", "klookup fail for tcb6 at %x\n",
                         p));
             found = 0;
             break;
         }
+#elif defined(dragonfly)
+	in6pcb = xtp->xt_inp;
 #else
         in6pcb = ((struct xinpcb *) xig)->xi_inp;
 #endif
 #if defined(__NetBSD__) && __NetBSD_Version__ >= 106250000	/*1.6Y*/
         if (in6pcb.in6p_af != AF_INET6)
             goto skip;
-#elif (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(darwin)
+#elif defined(freebsd3) || defined(darwin)
         if (0 == (in6pcb.inp_vflag & INP_IPV6))
             goto skip;
 #endif
@@ -1820,13 +1920,15 @@ var_tcp6(register struct variable * vp,
       skip:
 #if defined(__NetBSD__) && __NetBSD_Version__ >= 106250000	/*1.6Y*/
         p = (caddr_t)in6pcb.in6p_queue.cqe_next;
-#elif !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined(darwin)
+#elif !defined(freebsd3) && !defined(darwin)
         p = (caddr_t) in6pcb.in6p_next;
+#elif defined(dragonfly)
+	xtp = (struct xtcpcb *) ((char *)xtp + xtp->xt_len);
 #else
         xig = (struct xinpgen *) ((char *) xig + xig->xig_len);
 #endif
     }
-#if (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(darwin)
+#if defined(freebsd3) || defined(darwin)
     free(sysctl_buf);
 #endif
     DEBUGMSGTL(("mibII/ipv6", "found=%d\n", found));
