---------------------
PatchSet 5934 
Date: 2007/10/08 13:50:27
Author: amosjeffries
Branch: squid3-ipv6
Tag: (none) 
Log:
Add ICMPv6 module class to pinger.

Squid will still not pass IPv6 addresses to pinger. I have some detailed
testing still to do before enabling that.
Also, this class does not yet resolve Hops from TTL on packet headers.

Members: 
	configure.in:1.63.2.64->1.63.2.65 
	src/ICMP.h:1.1.2.5->1.1.2.6 
	src/ICMPv4.cc:1.1.2.2->1.1.2.3 
	src/ICMPv4.h:1.1.2.2->1.1.2.3 
	src/ICMPv6.cc:1.1->1.1.2.1 
	src/ICMPv6.h:1.1->1.1.2.1 
	src/Makefile.am:1.58.2.23->1.58.2.24 
	src/pinger.cc:1.9.8.10->1.9.8.11 

Index: squid3/configure.in
===================================================================
RCS file: /cvsroot/squid-sf//squid3/configure.in,v
retrieving revision 1.63.2.64
retrieving revision 1.63.2.65
diff -u -r1.63.2.64 -r1.63.2.65
--- squid3/configure.in	6 Oct 2007 15:17:04 -0000	1.63.2.64
+++ squid3/configure.in	8 Oct 2007 13:50:27 -0000	1.63.2.65
@@ -1,7 +1,7 @@
 
 dnl  Configuration input file for Squid
 dnl
-dnl  $Id: configure.in,v 1.63.2.64 2007/10/06 15:17:04 amosjeffries Exp $
+dnl  $Id: configure.in,v 1.63.2.65 2007/10/08 13:50:27 amosjeffries Exp $
 dnl
 dnl
 dnl
@@ -11,7 +11,7 @@
 AC_CONFIG_AUX_DIR(cfgaux)
 AC_CONFIG_SRCDIR([src/main.cc])
 AM_INIT_AUTOMAKE([tar-ustar])
-AC_REVISION($Revision: 1.63.2.64 $)dnl
+AC_REVISION($Revision: 1.63.2.65 $)dnl
 AC_PREFIX_DEFAULT(/usr/local/squid)
 AM_MAINTAINER_MODE
 
@@ -1931,6 +1931,7 @@
 	netdb.h \
 	netinet/in.h \
 	netinet/tcp.h \
+	netinet/icmp6.h \
 	netinet/ip.h \
 	netinet/ip_icmp.h \
 	netinet/ip_fil_compat.h \
Index: squid3/src/ICMP.h
===================================================================
RCS file: /cvsroot/squid-sf//squid3/src/Attic/ICMP.h,v
retrieving revision 1.1.2.5
retrieving revision 1.1.2.6
diff -u -r1.1.2.5 -r1.1.2.6
--- squid3/src/ICMP.h	7 Oct 2007 11:37:20 -0000	1.1.2.5
+++ squid3/src/ICMP.h	8 Oct 2007 13:50:28 -0000	1.1.2.6
@@ -1,5 +1,5 @@
 /*
- * $Id: ICMP.h,v 1.1.2.5 2007/10/07 11:37:20 amosjeffries Exp $
+ * $Id: ICMP.h,v 1.1.2.6 2007/10/08 13:50:28 amosjeffries Exp $
  *
  * DEBUG: section 37    ICMP Routines
  * AUTHOR: Duane Wessels, Amos Jeffries
@@ -38,12 +38,20 @@
 #include "IPAddress.h"
 
 #if ALLOW_SOURCE_PING
-#define MAX_PKT_SZ 8192
+#define MAX_PKT4_SZ 8192
 #define MAX_PAYLOAD (MAX_PKT_SZ - sizeof(struct icmphdr) - sizeof (char) - sizeof(struct timeval) - 1)
-#else
+#if USE_IPV6
+#define MAX_PKT6_SZ (MAX_PAYLOAD + sizeof(struct timeval) + sizeof (char) + sizeof(struct icmp6_hdr) + 1)
+#endif /* USE_IPV6 */
+
+#else /* ! ALLOW_SOURCE_PING */
 #define MAX_PAYLOAD SQUIDHOSTNAMELEN
-#define MAX_PKT_SZ (MAX_PAYLOAD + sizeof(struct timeval) + sizeof (char) + sizeof(struct icmphdr) + 1)
-#endif
+#define MAX_PKT4_SZ (MAX_PAYLOAD + sizeof(struct timeval) + sizeof (char) + sizeof(struct icmphdr) + 1)
+#if USE_IPV6
+#define MAX_PKT6_SZ (MAX_PAYLOAD + sizeof(struct timeval) + sizeof (char) + sizeof(struct icmp6_hdr) + 1)
+#endif /* USE_IPV6 */
+
+#endif /* ALLOW_SOURCE_PING */
 
 struct icmpEchoData
 {
@@ -52,7 +60,7 @@
     char payload[MAX_PAYLOAD];
 };
 
-extern int icmp_pkts_sent;
+SQUIDCEXTERN int icmp_pkts_sent;
 
 /**
  * Implements the squid interface to access ICMP operations
Index: squid3/src/ICMPv4.cc
===================================================================
RCS file: /cvsroot/squid-sf//squid3/src/Attic/ICMPv4.cc,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -u -r1.1.2.2 -r1.1.2.3
--- squid3/src/ICMPv4.cc	7 Oct 2007 01:34:24 -0000	1.1.2.2
+++ squid3/src/ICMPv4.cc	8 Oct 2007 13:50:28 -0000	1.1.2.3
@@ -1,5 +1,5 @@
 /*
- * $Id: ICMPv4.cc,v 1.1.2.2 2007/10/07 01:34:24 amosjeffries Exp $
+ * $Id: ICMPv4.cc,v 1.1.2.3 2007/10/08 13:50:28 amosjeffries Exp $
  *
  * DEBUG: section 42    ICMP Pinger program
  * AUTHOR: Duane Wessels, Amos Jeffries
@@ -142,15 +142,15 @@
     struct protoent *proto = NULL;
 
     if ((proto = getprotobyname("icmp")) == 0) {
-        debugs(42, 0, "pingerOpen: unknown protocol: icmp");
-        exit(1);
+        debugs(42, 0, HERE << " unknown protocol: icmp");
+        return -1;
     }
 
     icmp_sock = socket(PF_INET, SOCK_RAW, proto->p_proto);
 
     if (icmp_sock < 0) {
-        debugs(50, 0, "pingerOpen: icmp_sock: " << xstrerror());
-        exit(1);
+        debugs(50, 0, HERE << " icmp_sock: " << xstrerror());
+        return -1;
     }
 
     icmp_ident = getpid() & 0xffff;
@@ -162,14 +162,14 @@
 void
 ICMPv4::SendEcho(IPAddress &to, int opcode, const char *payload, int len)
 {
-    LOCAL_ARRAY(char, pkt, MAX_PKT_SZ);
+    LOCAL_ARRAY(char, pkt, MAX_PKT4_SZ);
 
     struct icmphdr *icmp = NULL;
     icmpEchoData *echo;
     size_t icmp_pktsize = sizeof(struct icmphdr);
     struct addrinfo *S = NULL;
 
-    memset(pkt, '\0', MAX_PKT_SZ);
+    memset(pkt, '\0', MAX_PKT4_SZ);
 
     icmp = (struct icmphdr *) (void *) pkt;
 
@@ -210,7 +210,7 @@
 
     to.GetAddrInfo(S);
     ((sockaddr_in*)S->ai_addr)->sin_port = 0;
-    assert(icmp_pktsize <= MAX_PKT_SZ);
+    assert(icmp_pktsize <= MAX_PKT4_SZ);
     sendto(icmp_sock,
            (const void *) pkt,
            icmp_pktsize,
@@ -242,13 +242,16 @@
     icmpEchoData *echo;
     static pingerReplyData preply;
 
+    if(icmp_sock < 0)
+        return;
+
     if (pkt == NULL)
-        pkt = (char *)xmalloc(MAX_PKT_SZ);
+        pkt = (char *)xmalloc(MAX_PKT4_SZ);
 
     preply.from.InitAddrInfo(from);
     n = recvfrom(icmp_sock,
                  (void *)pkt,
-                 MAX_PKT_SZ,
+                 MAX_PKT4_SZ,
                  0,
                  from->ai_addr,
                  &from->ai_addrlen);
@@ -301,7 +304,7 @@
 
     preply.rtt = tvSubMsec(echo->tv, now);
 
-    preply.psize = n - iphdrlen - (sizeof(icmpEchoData) - MAX_PKT_SZ);
+    preply.psize = n - iphdrlen - (sizeof(icmpEchoData) - MAX_PKT4_SZ);
 
     pingerSendtoSquid(&preply);
 
Index: squid3/src/ICMPv4.h
===================================================================
RCS file: /cvsroot/squid-sf//squid3/src/Attic/ICMPv4.h,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -u -r1.1.2.2 -r1.1.2.3
--- squid3/src/ICMPv4.h	7 Oct 2007 01:34:24 -0000	1.1.2.2
+++ squid3/src/ICMPv4.h	8 Oct 2007 13:50:28 -0000	1.1.2.3
@@ -1,5 +1,5 @@
 /*
- * $Id: ICMPv4.h,v 1.1.2.2 2007/10/07 01:34:24 amosjeffries Exp $
+ * $Id: ICMPv4.h,v 1.1.2.3 2007/10/08 13:50:28 amosjeffries Exp $
  *
  * DEBUG: section 37    ICMP Routines
  * AUTHOR: Duane Wessels, Amos Jeffries
@@ -133,10 +133,19 @@
 #define ICMP_ECHO 8
 #endif
 
-#ifndef ICMPECHOREPLY
+#ifndef ICMP_ECHOREPLY
 #define ICMP_ECHOREPLY 0
 #endif
 
+// TODO: which OS needs this ??
+#ifndef _SQUID_LINUX_
+#ifndef _SQUID_CYGWIN_
+#ifndef _SQUID_MSWIN_
+#define icmphdr icmp
+#define iphdr ip
+#endif
+#endif
+#endif
 
 /**
  * Class partially implementing RFC 792 - ICMP for IP version 4.
--- /dev/null	Fri Oct 12 00:20:28 2007
+++ squid3/src/ICMPv6.cc	Fri Oct 12 00:20:28 2007
@@ -0,0 +1,275 @@
+/*
+ * $Id: ICMPv6.cc,v 1.1.2.1 2007/10/08 13:50:28 amosjeffries Exp $
+ *
+ * DEBUG: section 42    ICMP Pinger program
+ * AUTHOR: Duane Wessels, Amos Jeffries
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+#define SQUID_HELPER 1
+
+#include "squid.h"
+#include "SquidTime.h"
+
+#if USE_ICMP && USE_IPV6
+
+#include "ICMPv6.h"
+
+// ICMPv6 OP-Codes
+// see http://www.iana.org/assignments/icmpv6-parameters
+// NP: LowPktStr is for codes 0-127
+static const char *icmp6LowPktStr[] =
+    {
+        "ICMP 0",			// 0
+        "Destination Unreachable",	// 1 - RFC2463
+        "Packet Too Big", 		// 2 - RFC2463
+        "Time Exceeded",		// 3 - RFC2463
+        "Parameter Problem",		// 4 - RFC2463
+        "ICMP 5",			// 5
+        "ICMP 6",			// 6
+        "ICMP 7",			// 7
+        "ICMP 8",			// 8
+        "ICMP 9",			// 9
+        "ICMP 10"			// 10
+    };
+
+// NP: HighPktStr is for codes 128-255
+static const char *icmp6HighPktStr[] =
+    {
+        "Echo Request",					// 128 - RFC2463
+        "Echo Reply",					// 129 - RFC2463
+        "Multicast Listener Query",			// 130 - RFC2710
+        "Multicast Listener Report",			// 131 - RFC2710
+        "Multicast Listener Done",			// 132 - RFC2710
+        "Router Solicitation",				// 133 - RFC4861
+        "Router Advertisement",				// 134 - RFC4861
+        "Neighbor Solicitation",			// 135 - RFC4861
+        "Neighbor Advertisement",			// 136 - RFC4861
+        "Redirect Message",				// 137 - RFC4861
+        "Router Renumbering",				// 138 - Crawford
+        "ICMP Node Information Query",			// 139 - RFC4620
+        "ICMP Node Information Response",		// 140 - RFC4620
+        "Inverse Neighbor Discovery Solicitation",	// 141 - RFC3122
+        "Inverse Neighbor Discovery Advertisement",	// 142 - RFC3122
+        "Version 2 Multicast Listener Report",		// 143 - RFC3810       
+        "Home Agent Address Discovery Request",		// 144 - RFC3775
+        "Home Agent Address Discovery Reply",		// 145 - RFC3775
+        "Mobile Prefix Solicitation",			// 146 - RFC3775
+        "Mobile Prefix Advertisement",			// 147 - RFC3775
+        "Certification Path Solicitation",		// 148 - RFC3971
+        "Certification Path Advertisement",		// 149 - RFC3971
+        "ICMP Experimental (150)",			// 150 - RFC4065
+        "Multicast Router Advertisement",		// 151 - RFC4286
+        "Multicast Router Solicitation",		// 152 - RFC4286
+        "Multicast Router Termination",			// 153 - [RFC4286]
+        "ICMP 154",
+        "ICMP 155",
+        "ICMP 156",
+        "ICMP 157",
+        "ICMP 158",
+        "ICMP 159",
+        "ICMP 160"
+    };
+
+ICMPv6::ICMPv6() : ICMP()
+{
+    ; // nothing new.
+}
+
+ICMPv6::~ICMPv6()
+{
+    Close();
+}
+
+int
+ICMPv6::Open(void)
+{
+    struct protoent *proto = NULL;
+
+    if ((proto = getprotobyname("icmp")) == 0) {
+        debugs(42, 0, HERE << " unknown protocol: icmp");
+        return -1;
+    }
+
+    icmp_sock = socket(PF_INET6, SOCK_RAW, proto->p_proto);
+
+    if (icmp_sock < 0) {
+        debugs(50, 0, HERE << " icmp_sock: " << xstrerror());
+        return -1;
+    }
+
+    icmp_ident = getpid() & 0xffff;
+    debugs(42, 0, "pinger: ICMPv6 socket opened");
+
+    return icmp_sock;
+}
+
+/**
+ * Generates an RFC 4443 ICMPv6 ECHO Packet and sends into the network.
+ */
+void
+ICMPv6::SendEcho(IPAddress &to, int opcode, const char *payload, int len)
+{
+    LOCAL_ARRAY(char, pkt, MAX_PKT6_SZ);
+    struct icmp6_hdr *icmp = NULL;
+    icmpEchoData *echo = NULL;
+    struct addrinfo *S = NULL;
+    size_t icmp6_pktsize = 0;
+
+    memset(pkt, '\0', MAX_PKT6_SZ);
+    icmp = (struct icmp6_hdr *)pkt;
+
+    /*
+     * cevans - beware signed/unsigned issues in untrusted data from
+     * the network!!
+     */
+    if (len < 0) {
+        len = 0;
+    }
+
+    // Construct ICMPv6 ECHO header
+    icmp->icmp6_type = ICMP6_ECHO_REQUEST;
+    icmp->icmp6_code = 0;
+    icmp->icmp6_cksum = 0;
+    icmp->icmp6_id = icmp_ident;
+    icmp->icmp6_seq = (u_short) icmp_pkts_sent++;
+
+    icmp6_pktsize = sizeof(struct icmp6_hdr);
+
+
+    // Fill ICMPv6 ECHO data content
+    echo = (icmpEchoData *) (pkt + sizeof(icmp6_hdr));
+    echo->opcode = (unsigned char) opcode;
+    echo->tv = current_time;
+
+    icmp6_pktsize += sizeof(struct timeval) + sizeof(char);
+
+    if (payload)
+    {
+        if (len > MAX_PAYLOAD)
+            len = MAX_PAYLOAD;
+
+        xmemcpy(echo->payload, payload, len);
+
+        icmp6_pktsize += len;
+    }
+
+    icmp->icmp6_cksum = CheckSum((u_short *) icmp, icmp6_pktsize);
+
+    to.GetAddrInfo(S);
+    ((sockaddr_in6*)S->ai_addr)->sin6_port = 0;
+
+    assert(icmp6_pktsize <= MAX_PKT6_SZ);
+    sendto(icmp_sock,
+           (const void *) pkt,
+           icmp6_pktsize,
+           0,
+           S->ai_addr,
+           S->ai_addrlen);
+    pingerLog(to, 0, NULL, 0, 0);
+}
+
+void
+ICMPv6::Send(pingerEchoData* unused1, int unused2)
+{
+    assert(false); // shoudl be unused.
+}
+
+/**
+ * Reads an RFC 4443 ICMPv6 ECHO-REPLY Packet from the network.
+ */
+void
+ICMPv6::Recv(void)
+{
+    int n;
+    struct addrinfo *afrom = NULL;
+    int iphdrlen = 20;
+//    struct iphdr *ip = NULL;
+    static char *pkt = NULL;
+    struct icmp6_hdr *icmp6 = NULL;
+    icmpEchoData *echo = NULL;
+    struct timeval now;
+    static pingerReplyData preply;
+
+    if(icmp_sock < 0)
+        return;
+
+    if (pkt == NULL)
+        pkt = (char *)xmalloc(MAX_PKT6_SZ);
+
+    n = recvfrom(icmp_sock,
+                 (void *)pkt,
+                 MAX_PKT6_SZ,
+                 0,
+                 afrom->ai_addr,
+                 &afrom->ai_addrlen);
+
+    preply.from = *afrom;
+
+#if GETTIMEOFDAY_NO_TZP
+
+    gettimeofday(&now);
+
+#else
+
+    gettimeofday(&now, NULL);
+
+#endif
+
+    debugs(42, 9, "pingerRecv: " << n << " bytes from " << preply.from);
+
+// AYJ FIXME : TTL still has to come from the IP header somewhere.
+//	still need to strip and process it properly.
+
+    icmp6 = (struct icmp6_hdr *) (void *) (pkt + iphdrlen);
+
+    if (icmp6->icmp6_type != ICMP6_ECHO_REPLY)
+        return;
+
+    if (icmp6->icmp6_id != icmp_ident)
+        return;
+
+    echo = (icmpEchoData *) (pkt + iphdrlen);
+
+    preply.opcode = echo->opcode;
+
+/*AYJ see above    preply.hops = ipHops(icmpip->ip_ttl); */ preply.hops = 0; // null it for now.
+
+    preply.rtt = tvSubMsec(echo->tv, now);
+
+    preply.psize = n - iphdrlen - (sizeof(icmpEchoData) - MAX_PKT6_SZ);
+
+    /* send results of the lookup back to squid.*/
+    pingerSendtoSquid(&preply);
+
+    pingerLog(preply.from, preply.opcode,
+              ( preply.opcode&0x80 ? icmp6HighPktStr[(preply.opcode&0x7f)] : icmp6LowPktStr[(preply.opcode&0x7f)] ),
+              preply.rtt, preply.hops);
+}
+
+#endif /* USE_ICMP && USE_IPV6 */
--- /dev/null	Fri Oct 12 00:20:28 2007
+++ squid3/src/ICMPv6.h	Fri Oct 12 00:20:28 2007
@@ -0,0 +1,81 @@
+/*
+ * $Id: ICMPv6.h,v 1.1.2.1 2007/10/08 13:50:28 amosjeffries Exp $
+ *
+ * DEBUG: section 37    ICMP Routines
+ * AUTHOR: Duane Wessels, Amos Jeffries
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+#ifndef _INCLUDE_ICMPV6_H
+#define _INCLUDE_ICMPV6_H
+
+#include "config.h"
+
+#if USE_IPV6
+
+#include "ICMP.h"
+#include "IPAddress.h"
+
+#if HAVE_NETINET_ICMP6_H
+#include <netinet/icmp6.h>
+#endif
+
+#ifndef ICMP6_ECHOREQUEST
+#define ICMP6_ECHOREQUEST 128
+#endif
+
+#ifndef ICMP6_ECHOREPLY
+#define ICMP6_ECHOREPLY 129
+#endif
+
+
+/**
+ * Class partially implementing RFC 4443 - ICMPv6 for IP version 6.
+ * Provides ECHO-REQUEST, ECHO-REPLY (secion 4)
+ */
+class ICMPv6 : public ICMP
+{
+public:
+    ICMPv6();
+    virtual ~ICMPv6();
+
+    virtual int Open();
+
+#if USE_ICMP
+    virtual void SendEcho(IPAddress &, int, const char*, int);
+    virtual void Recv(void);
+
+private:
+    virtual void Send(pingerEchoData* unused1, int unused2);
+
+#endif
+};
+
+#endif /* USE_IPV6 */
+
+#endif /* _INCLUDE_ICMPV6_H */
Index: squid3/src/Makefile.am
===================================================================
RCS file: /cvsroot/squid-sf//squid3/src/Makefile.am,v
retrieving revision 1.58.2.23
retrieving revision 1.58.2.24
diff -u -r1.58.2.23 -r1.58.2.24
--- squid3/src/Makefile.am	8 Oct 2007 04:23:29 -0000	1.58.2.23
+++ squid3/src/Makefile.am	8 Oct 2007 13:50:28 -0000	1.58.2.24
@@ -1,7 +1,7 @@
 #
 #  Makefile for the Squid Object Cache server
 #
-#  $Id: Makefile.am,v 1.58.2.23 2007/10/08 04:23:29 amosjeffries Exp $
+#  $Id: Makefile.am,v 1.58.2.24 2007/10/08 13:50:28 amosjeffries Exp $
 #
 #  Uncomment and customize the following to suit your needs:
 #
@@ -712,6 +712,8 @@
 	icmp.cc \
 	ICMPv4.h \
 	ICMPv4.cc \
+	ICMPv6.h \
+	ICMPv6.cc \
 	pinger.cc \
 	debug.cc \
 	time.cc \
Index: squid3/src/pinger.cc
===================================================================
RCS file: /cvsroot/squid-sf//squid3/src/pinger.cc,v
retrieving revision 1.9.8.10
retrieving revision 1.9.8.11
diff -u -r1.9.8.10 -r1.9.8.11
--- squid3/src/pinger.cc	7 Oct 2007 01:34:24 -0000	1.9.8.10
+++ squid3/src/pinger.cc	8 Oct 2007 13:50:28 -0000	1.9.8.11
@@ -1,5 +1,5 @@
 /*
- * $Id: pinger.cc,v 1.9.8.10 2007/10/07 01:34:24 amosjeffries Exp $
+ * $Id: pinger.cc,v 1.9.8.11 2007/10/08 13:50:28 amosjeffries Exp $
  *
  * DEBUG: section 42    ICMP Pinger program
  * AUTHOR: Duane Wessels
@@ -40,6 +40,7 @@
 #if USE_ICMP
 
 #include "ICMPv4.h"
+#include "ICMPv6.h"
 
 /* Native Windows port doesn't have netinet support, so we emulate it.
    At this time, Cygwin lacks icmp support in its include files, so we need
@@ -76,53 +77,8 @@
 
 #endif
 
-#define ICMP_ECHO 8
-#define ICMP_ECHOREPLY 0
-
-typedef struct iphdr
-{
-
-u_int8_t  ip_vhl:
-    4;		/* Length of the header in dwords */
-
-u_int8_t  version:
-    4;	/* Version of IP                  */
-    u_int8_t  tos;		/* Type of service                */
-    u_int16_t total_len;	/* Length of the packet in dwords */
-    u_int16_t ident;		/* unique identifier              */
-    u_int16_t flags;		/* Flags                          */
-    u_int8_t  ip_ttl;		/* Time to live                   */
-    u_int8_t  proto;		/* Protocol number (TCP, UDP etc) */
-    u_int16_t checksum;		/* IP checksum                    */
-    u_int32_t source_ip;
-    u_int32_t dest_ip;
-}
-iphdr;
-
-/* ICMP header */
-typedef struct icmphdr
-{
-    u_int8_t  icmp_type;	/* ICMP packet type                 */
-    u_int8_t  icmp_code;	/* Type sub code                    */
-    u_int16_t icmp_cksum;
-    u_int16_t icmp_id;
-    u_int16_t icmp_seq;
-    u_int32_t timestamp;	/* not part of ICMP, but we need it */
-}
-icmphdr;
-
 #endif	/* _SQUID_MSWIN_ */
 
-#ifndef _SQUID_LINUX_
-#ifndef _SQUID_CYGWIN_
-#ifndef _SQUID_MSWIN_
-#define icmphdr icmp
-#define iphdr ip
-#endif
-#endif
-#endif
-
-
 int icmp_pkts_sent = 0;
 
 static void pingerOpen(void);
@@ -141,6 +97,10 @@
 
 // ICMP Engines are declared global here so they can call each other easily.
 ICMPv4 icmp4;
+#if USE_IPV6
+ICMPv6 icmp6;
+#endif
+
 
 void
 pingerOpen(void)
@@ -191,7 +151,6 @@
         exit(1);
     }
 
-    icmp_sock = icmp4.Open(); // NP: icmp_sock here refers to the global one.
 
 #ifdef _SQUID_MSWIN_
 
@@ -247,6 +206,9 @@
 #endif
 
     icmp4.Close();
+#if USE_IPV6
+    icmp6.Close();
+#endif
 }
 
 void
@@ -288,17 +250,33 @@
         return 0;
     }
 
-    icmp4.SendEcho(pecho.to,
-                   pecho.opcode,
-                   pecho.payload,
-                   pecho.psize);
+#if USE_IPV6
+    if(pecho.to.IsIPv6()) {
+        icmp6.SendEcho(pecho.to,
+                       pecho.opcode,
+                       pecho.payload,
+                       pecho.psize);
+    }
+#endif
+
+    if(pecho.to.IsIPv4()) {
+        icmp4.SendEcho(pecho.to,
+                       pecho.opcode,
+                       pecho.payload,
+                       pecho.psize);
+    }
+
     return n;
 }
 
 void
 pingerSendtoSquid(pingerReplyData * preply)
 {
-    int len = sizeof(pingerReplyData) - MAX_PKT_SZ + preply->psize;
+#if USE_IPV6
+    int len = sizeof(pingerReplyData) - MAX_PKT6_SZ + preply->psize;
+#else
+    int len = sizeof(pingerReplyData) - MAX_PKT4_SZ + preply->psize;
+#endif
 
     if (send(socket_to_squid, preply, len, 0) < 0) {
         debugs(50, 0, "pinger: send: " << xstrerror());
@@ -322,7 +300,31 @@
      * cevans - do this first. It grabs a raw socket. After this we can
      * drop privs
      */
+    int icmp4_worker = -1;
+    int icmp6_worker = -1;
+
+    icmp4_worker = icmp4.Open();
+    if(icmp4_worker < 0) {
+        debugs(42, 0, "pinger: Unable to start ICMP pinger.");
+    }
+
+#if USE_IPV6
+    icmp6_worker = icmp6.Open();
+    if(icmp6_worker <0 ) {
+        debugs(42, 0, "pinger: Unable to start ICMPv6 pinger.");
+    }
+#endif
+
+    // abort if neither worker could open a socket.
+    if(icmp4_worker == -1) {
+#if USE_IPV6
+        if(icmp6_worker == -1)
+#endif
+            exit(1);
+    }
+
     pingerOpen();
+
     setgid(getgid());
     setuid(getuid());
 
@@ -337,9 +339,10 @@
         tv.tv_sec = PINGER_TIMEOUT;
         tv.tv_usec = 0;
         FD_ZERO(&R);
+        FD_SET(icmp4_worker, &R);
+        FD_SET(icmp6_worker, &R);
         FD_SET(socket_from_squid, &R);
-        FD_SET(icmp_sock, &R);
-        x = select(icmp_sock + 1, &R, NULL, NULL, &tv);
+        x = select(socket_from_squid + 1, &R, NULL, NULL, &tv);
         getCurrentTime();
 
         if (x < 0) {
@@ -354,7 +357,12 @@
                 exit(1);
             }
 
-        if (FD_ISSET(icmp_sock, &R))
+#if USE_IPV6
+        if (FD_ISSET(icmp6_worker, &R))
+            icmp6.Recv();
+#endif
+
+        if (FD_ISSET(icmp4_worker, &R))
             icmp4.Recv();
 
         if (PINGER_TIMEOUT + last_check_time < squid_curtime) {
