--------------------- 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 +#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) {