--------------------- PatchSet 5883 Date: 2007/10/06 15:17:04 Author: amosjeffries Branch: squid3-ipv6 Tag: (none) Log: Migrate the pinger ICMP core code into ICMPv4 class. Members: configure.in:1.63.2.63->1.63.2.64 src/ICMP.h:1.1.2.1->1.1.2.2 src/ICMPv4.cc:1.1->1.1.2.1 src/ICMPv4.h:1.1->1.1.2.1 src/Makefile.am:1.58.2.20->1.58.2.21 src/icmp.cc:1.8.8.14->1.8.8.15 src/pinger.cc:1.9.8.8->1.9.8.9 src/structs.h:1.66.2.31->1.66.2.32 src/typedefs.h:1.36.4.3->1.36.4.4 Index: squid3/configure.in =================================================================== RCS file: /cvsroot/squid-sf//squid3/configure.in,v retrieving revision 1.63.2.63 retrieving revision 1.63.2.64 diff -u -r1.63.2.63 -r1.63.2.64 --- squid3/configure.in 2 Oct 2007 04:54:51 -0000 1.63.2.63 +++ squid3/configure.in 6 Oct 2007 15:17:04 -0000 1.63.2.64 @@ -1,7 +1,7 @@ dnl Configuration input file for Squid dnl -dnl $Id: configure.in,v 1.63.2.63 2007/10/02 04:54:51 amosjeffries Exp $ +dnl $Id: configure.in,v 1.63.2.64 2007/10/06 15:17:04 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.63 $)dnl +AC_REVISION($Revision: 1.63.2.64 $)dnl AC_PREFIX_DEFAULT(/usr/local/squid) AM_MAINTAINER_MODE @@ -1931,7 +1931,10 @@ netdb.h \ netinet/in.h \ netinet/tcp.h \ + netinet/ip.h \ + netinet/ip_icmp.h \ netinet/ip_fil_compat.h \ + netinet/in_systm.h \ openssl/err.h \ openssl/md5.h \ openssl/ssl.h \ Index: squid3/src/ICMP.h =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/Attic/ICMP.h,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -r1.1.2.1 -r1.1.2.2 --- squid3/src/ICMP.h 6 Oct 2007 12:50:49 -0000 1.1.2.1 +++ squid3/src/ICMP.h 6 Oct 2007 15:17:07 -0000 1.1.2.2 @@ -1,5 +1,5 @@ /* - * $Id: ICMP.h,v 1.1.2.1 2007/10/06 12:50:49 amosjeffries Exp $ + * $Id: ICMP.h,v 1.1.2.2 2007/10/06 15:17:07 amosjeffries Exp $ * * DEBUG: section 37 ICMP Routines * AUTHOR: Duane Wessels, Amos Jeffries @@ -38,6 +38,23 @@ #include "config.h" #include "IPAddress.h" +#if ALLOW_SOURCE_PING +#define MAX_PKT_SZ 8192 +#define MAX_PAYLOAD (MAX_PKT_SZ - sizeof(struct icmphdr) - sizeof (char) - sizeof(struct timeval) - 1) +#else +#define MAX_PAYLOAD SQUIDHOSTNAMELEN +#define MAX_PKT_SZ (MAX_PAYLOAD + sizeof(struct timeval) + sizeof (char) + sizeof(struct icmphdr) + 1) +#endif + +struct icmpEchoData +{ + struct timeval tv; + unsigned char opcode; + char payload[MAX_PAYLOAD]; +}; + +extern int icmp_pkts_sent; + /** * Implements the squid interface to access ICMP operations * @@ -52,10 +69,10 @@ { public: ICMP(); - virtual ~ICMP(); + virtual ~ICMP() {}; - // Start pinger helper and initiate control channel - virtual void Open() =0; + /// Start pinger helper and initiate control channel + virtual int Open() =0; /// Shutdown pinger helper and control channel virtual void Close(); @@ -66,14 +83,14 @@ virtual void SendEcho(IPAddress &to, int opcode, const char *payload, int len) =0; /// Handle ICMP responses. - virtual void Recv(int unused1, void *unused2) =0; + virtual void Recv(void) =0; -private: +protected: /// Send ICMP virtual void Send(pingerEchoData * pkt, int len) =0; - int CheckSum(unsigned short *ptr, int size); - int ipHops(int ttl); + inline int CheckSum(unsigned short *ptr, int size); + inline int ipHops(int ttl); /* no use wasting memory */ int icmp_sock; @@ -81,4 +98,74 @@ #endif /* USE_ICMP */ }; + + +// TODO : move these into icmp.cc once the squid-internals have been moved to ICMPSquid engine. +inline +ICMP::ICMP() +{ + icmp_sock = -1; + icmp_ident = 0; +} + +inline void +ICMP::Close() +{ + if(icmp_sock > 0) + close(icmp_sock); + icmp_sock = -1; + icmp_ident = 0; +} + +inline int +ICMP::CheckSum(unsigned short *ptr, int size) +{ + long sum; + unsigned short oddbyte; + unsigned short answer; + sum = 0; + + while (size > 1) { + sum += *ptr++; + size -= 2; + } + + if (size == 1) { + oddbyte = 0; + *((unsigned char *) &oddbyte) = *(unsigned char *) ptr; + sum += oddbyte; + } + + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + answer = (unsigned short) ~sum; + return (answer); +} + +inline int +ICMP::ipHops(int ttl) +{ + if (ttl < 33) + return 33 - ttl; + + if (ttl < 63) + return 63 - ttl; /* 62 = (64+60)/2 */ + + if (ttl < 65) + return 65 - ttl; /* 62 = (64+60)/2 */ + + if (ttl < 129) + return 129 - ttl; + + if (ttl < 193) + return 193 - ttl; + + return 256 - ttl; +} + +// Glue for pinger functions use by child engines +// To be removed as soon as no longer needed. +extern void pingerLog(const IPAddress &addr, const u_int8_t type, const char* pkt_str, const int rtt, const int hops); +extern void pingerSendtoSquid(pingerReplyData * preply); + #endif --- /dev/null Sun Oct 7 00:21:20 2007 +++ squid3/src/ICMPv4.cc Sun Oct 7 00:21:20 2007 @@ -0,0 +1,352 @@ +/* + * $Id: ICMPv4.cc,v 1.1.2.1 2007/10/06 15:17:07 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" +#include "ICMPv4.h" + +#if USE_ICMP + +#if HAVE_NETINET_IN_SYSTM_H +#include +#endif +#if HAVE_NETINET_IN_H +#include +#endif +#if HAVE_NETINET_IP_H +#include +#endif +#if HAVE_NETINET_IP_ICMP_H +#include +#endif + +/* 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 + to use the native Windows port definitions. + */ + +#ifdef _SQUID_WIN32_ + +#include "fde.h" + +#ifdef _SQUID_MSWIN_ + +#include +#include + +#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 + + +// Glue for Linux field names in ICMP packet structure +#if defined (_SQUID_LINUX_) +#ifdef icmp_id +#undef icmp_id +#endif +#ifdef icmp_seq +#undef icmp_seq +#endif +#define icmp_type type +#define icmp_code code +#define icmp_cksum checksum +#define icmp_id un.echo.id +#define icmp_seq un.echo.sequence +#define ip_hl ihl +#define ip_v version +#define ip_tos tos +#define ip_len tot_len +#define ip_id id +#define ip_off frag_off +#define ip_ttl ttl +#define ip_p protocol +#define ip_sum check +#define ip_src saddr +#define ip_dst daddr +#endif + + +const char *icmpPktStr[] = + { + "Echo Reply", + "ICMP 1", + "ICMP 2", + "Destination Unreachable", + "Source Quench", + "Redirect", + "ICMP 6", + "ICMP 7", + "Echo", + "ICMP 9", + "ICMP 10", + "Time Exceeded", + "Parameter Problem", + "Timestamp", + "Timestamp Reply", + "Info Request", + "Info Reply", + "Out of Range Type" + }; + +ICMPv4::ICMPv4() : ICMP() +{ + ; +} + +ICMPv4::~ICMPv4() +{ + Close(); +} + +int +ICMPv4::Open(void) +{ + struct protoent *proto = NULL; + + if ((proto = getprotobyname("icmp")) == 0) { + debugs(42, 0, "pingerOpen: unknown protocol: icmp"); + exit(1); + } + + icmp_sock = socket(PF_INET, SOCK_RAW, proto->p_proto); + + if (icmp_sock < 0) { + debugs(50, 0, "pingerOpen: icmp_sock: " << xstrerror()); + exit(1); + } + + icmp_ident = getpid() & 0xffff; + debugs(42, 0, "pinger: ICMP socket opened"); + + return icmp_sock; +} + +void +ICMPv4::SendEcho(IPAddress &to, int opcode, const char *payload, int len) +{ + LOCAL_ARRAY(char, pkt, MAX_PKT_SZ); + + struct icmphdr *icmp = NULL; + icmpEchoData *echo; + size_t icmp_pktsize = sizeof(struct icmphdr); + struct addrinfo *S = NULL; + + memset(pkt, '\0', MAX_PKT_SZ); + + icmp = (struct icmphdr *) (void *) pkt; + + /* + * cevans - beware signed/unsigned issues in untrusted data from + * the network!! + */ + if (len < 0) + { + len = 0; + } + + // Construct ICMP packet header + icmp->icmp_type = ICMP_ECHO; + icmp->icmp_code = 0; + icmp->icmp_cksum = 0; + icmp->icmp_id = icmp_ident; + icmp->icmp_seq = (u_short) icmp_pkts_sent++; + + // Construct ICMP packet data content + echo = (icmpEchoData *) (icmp + 1); + echo->opcode = (unsigned char) opcode; + echo->tv = current_time; + + icmp_pktsize += sizeof(struct timeval) + sizeof(char); + + if (payload) + { + if (len > MAX_PAYLOAD) + len = MAX_PAYLOAD; + + xmemcpy(echo->payload, payload, len); + + icmp_pktsize += len; + } + + icmp->icmp_cksum = CheckSum((u_short *) icmp, icmp_pktsize); + + to.GetAddrInfo(S); + ((sockaddr_in*)S->ai_addr)->sin_port = 0; + assert(icmp_pktsize <= MAX_PKT_SZ); + sendto(icmp_sock, + (const void *) pkt, + icmp_pktsize, + 0, + S->ai_addr, + S->ai_addrlen); + pingerLog(to, ' ', NULL, 0, 0); +} + +void +ICMPv4::Send(pingerEchoData* unused1, int unused2) +{ + ; // Use SendEcho() instead. +} + +void +ICMPv4::Recv(void) +{ + int n; + struct addrinfo *from = NULL; + int iphdrlen = 20; + + struct iphdr *ip = NULL; + + struct icmphdr *icmp = NULL; + static char *pkt = NULL; + + struct timeval now; + icmpEchoData *echo; + static pingerReplyData preply; + + if (pkt == NULL) + pkt = (char *)xmalloc(MAX_PKT_SZ); + + preply.from.InitAddrInfo(from); + n = recvfrom(icmp_sock, + (void *)pkt, + MAX_PKT_SZ, + 0, + from->ai_addr, + &from->ai_addrlen); + + preply.from = *from; + +#if GETTIMEOFDAY_NO_TZP + + gettimeofday(&now); + +#else + + gettimeofday(&now, NULL); + +#endif + + debugs(42, 9, "pingerRecv: " << n << " bytes from " << preply.from); + + ip = (struct iphdr *) (void *) pkt; + +#if HAVE_STRUCT_IPHDR_IP_HL + + iphdrlen = ip->ip_hl << 2; + +#else /* HAVE_STRUCT_IPHDR_IP_HL */ +#if WORDS_BIGENDIAN + + iphdrlen = (ip->ip_vhl >> 4) << 2; + +#else + + iphdrlen = (ip->ip_vhl & 0xF) << 2; + +#endif +#endif /* HAVE_STRUCT_IPHDR_IP_HL */ + + icmp = (struct icmphdr *) (void *) (pkt + iphdrlen); + + if (icmp->icmp_type != ICMP_ECHOREPLY) + return; + + if (icmp->icmp_id != icmp_ident) + return; + + echo = (icmpEchoData *) (void *) (icmp + 1); + + preply.opcode = echo->opcode; + + preply.hops = ipHops(ip->ip_ttl); + + preply.rtt = tvSubMsec(echo->tv, now); + + preply.psize = n - iphdrlen - (sizeof(icmpEchoData) - MAX_PKT_SZ); + + pingerSendtoSquid(&preply); + + pingerLog(preply.from, icmp->icmp_type, icmpPktStr[icmp->icmp_type], preply.rtt, preply.hops); +} + +#endif /* USE_ICMP */ --- /dev/null Sun Oct 7 00:21:20 2007 +++ squid3/src/ICMPv4.h Sun Oct 7 00:21:20 2007 @@ -0,0 +1,75 @@ +/* + * $Id: ICMPv4.h,v 1.1.2.1 2007/10/06 15:17:07 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_ICMPV4_H +#define _INCLUDE_ICMPV4_H + +#include "config.h" +#include "ICMP.h" +#include "IPAddress.h" + +#if HAVE_NETINET_IN_SYSTM_H +#include +#endif +#if HAVE_NETINET_IN_H +#include +#endif +#if HAVE_NETINET_IP_H +#include +#endif +#if HAVE_NETINET_IP_ICMP_H +#include +#endif + + +class ICMPv4 : public ICMP +{ +public: + ICMPv4(); + virtual ~ICMPv4(); + + 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 +}; + +extern const char *icmpPktStr[]; + +#endif Index: squid3/src/Makefile.am =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/Makefile.am,v retrieving revision 1.58.2.20 retrieving revision 1.58.2.21 diff -u -r1.58.2.20 -r1.58.2.21 --- squid3/src/Makefile.am 21 Sep 2007 12:34:14 -0000 1.58.2.20 +++ squid3/src/Makefile.am 6 Oct 2007 15:17:07 -0000 1.58.2.21 @@ -1,7 +1,7 @@ # # Makefile for the Squid Object Cache server # -# $Id: Makefile.am,v 1.58.2.20 2007/09/21 12:34:14 amosjeffries Exp $ +# $Id: Makefile.am,v 1.58.2.21 2007/10/06 15:17:07 amosjeffries Exp $ # # Uncomment and customize the following to suit your needs: # @@ -705,6 +705,9 @@ unlinkd_SOURCES = unlinkd_daemon.cc SquidNew.cc pinger_SOURCES = \ + ICMP.h \ + ICMPv4.h \ + ICMPv4.cc \ pinger.cc \ debug.cc \ time.cc \ Index: squid3/src/icmp.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/icmp.cc,v retrieving revision 1.8.8.14 retrieving revision 1.8.8.15 diff -u -r1.8.8.14 -r1.8.8.15 --- squid3/src/icmp.cc 6 Oct 2007 12:50:49 -0000 1.8.8.14 +++ squid3/src/icmp.cc 6 Oct 2007 15:17:07 -0000 1.8.8.15 @@ -1,6 +1,5 @@ - /* - * $Id: icmp.cc,v 1.8.8.14 2007/10/06 12:50:49 amosjeffries Exp $ + * $Id: icmp.cc,v 1.8.8.15 2007/10/06 15:17:07 amosjeffries Exp $ * * DEBUG: section 37 ICMP Routines * AUTHOR: Duane Wessels, Amos Jeffries @@ -68,7 +67,7 @@ assert(len <= PINGER_PAYLOAD_SZ); - to.GetInAddr(pecho.to); + pecho.to = to; pecho.opcode = (unsigned char) opcode; @@ -147,7 +146,7 @@ if (icmp_sock < 0) return; - debugs(37, 2, "icmpSend: to " << inet_ntoa(pkt->to) << ", opcode " << + debugs(37, 2, "icmpSend: to " << pkt->to << ", opcode " << (int) pkt->opcode << ", len " << pkt->psize); x = comm_udp_send(icmp_sock, (char *) pkt, len, 0); Index: squid3/src/pinger.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/pinger.cc,v retrieving revision 1.9.8.8 retrieving revision 1.9.8.9 diff -u -r1.9.8.8 -r1.9.8.9 --- squid3/src/pinger.cc 1 May 2007 08:32:31 -0000 1.9.8.8 +++ squid3/src/pinger.cc 6 Oct 2007 15:17:07 -0000 1.9.8.9 @@ -1,6 +1,5 @@ - /* - * $Id: pinger.cc,v 1.9.8.8 2007/05/01 08:32:31 amosjeffries Exp $ + * $Id: pinger.cc,v 1.9.8.9 2007/10/06 15:17:07 amosjeffries Exp $ * * DEBUG: section 42 ICMP Pinger program * AUTHOR: Duane Wessels @@ -40,6 +39,8 @@ #if USE_ICMP +#include "ICMPv4.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 to use the native Windows port definitions. @@ -47,11 +48,6 @@ #ifndef _SQUID_WIN32_ -#include -#include -#include -#include - #define PINGER_TIMEOUT 10 static int socket_from_squid = 0; @@ -72,10 +68,6 @@ #define socket_from_squid socket_to_squid #else /* _SQUID_CYGWIN_ */ -#include -#include -#include -#include #define PINGER_TIMEOUT 10 @@ -105,11 +97,9 @@ u_int32_t source_ip; u_int32_t dest_ip; } - iphdr; /* ICMP header */ - typedef struct icmphdr { u_int8_t icmp_type; /* ICMP packet type */ @@ -119,7 +109,6 @@ u_int16_t icmp_seq; u_int32_t timestamp; /* not part of ICMP, but we need it */ } - icmphdr; #endif /* _SQUID_MSWIN_ */ @@ -133,6 +122,7 @@ #endif #endif + #if defined (_SQUID_LINUX_) #ifdef icmp_id #undef icmp_id @@ -166,64 +156,25 @@ #define MAX_PKT_SZ (MAX_PAYLOAD + sizeof(struct timeval) + sizeof (char) + sizeof(struct icmphdr) + 1) #endif -typedef struct -{ - - struct timeval tv; - unsigned char opcode; - char payload[MAX_PAYLOAD]; -} - -icmpEchoData; - -int icmp_ident = -1; int icmp_pkts_sent = 0; -static const char *icmpPktStr[] = - { - "Echo Reply", - "ICMP 1", - "ICMP 2", - "Destination Unreachable", - "Source Quench", - "Redirect", - "ICMP 6", - "ICMP 7", - "Echo", - "ICMP 9", - "ICMP 10", - "Time Exceeded", - "Parameter Problem", - "Timestamp", - "Timestamp Reply", - "Info Request", - "Info Reply", - "Out of Range Type" - }; - -static int in_cksum(unsigned short *ptr, int size); -static void pingerRecv(void); - -static void pingerLog(struct icmphdr *, struct IN_ADDR, int, int); -static int ipHops(int ttl); -static void pingerSendtoSquid(pingerReplyData * preply); static void pingerOpen(void); static void pingerClose(void); #ifdef _SQUID_MSWIN_ - -int Win32__WSAFDIsSet(int fd, fd_set FAR * set - ) +int +Win32__WSAFDIsSet(int fd, fd_set FAR * set) { fde *F = &fd_table[fd]; SOCKET s = F->win32.handle; - return __WSAFDIsSet(s, set - ); + return __WSAFDIsSet(s, set); } - #endif +// ICMP Engines are declared global here so they can call each other easily. +ICMPv4 icmp4; + void pingerOpen(void) { @@ -273,15 +224,8 @@ exit(1); } - icmp_sock = socket(PF_INET, SOCK_RAW, proto->p_proto); - - if (icmp_sock < 0) { - debugs(50, 0, "pingerOpen: icmp_sock: " << xstrerror()); - exit(1); - } + icmp_sock = icmp4.Open(); // NP: icmp_sock here refers to the global one. - icmp_ident = getpid() & 0xffff; - debugs(42, 0, "pinger: ICMP socket opened"); #ifdef _SQUID_MSWIN_ socket_to_squid = @@ -328,7 +272,6 @@ void pingerClose(void) { - close(icmp_sock); #ifdef _SQUID_MSWIN_ shutdown(socket_to_squid, SD_BOTH); @@ -336,223 +279,21 @@ socket_to_squid = -1; #endif - icmp_sock = -1; - icmp_ident = 0; -} - -static void - -pingerSendEcho(struct IN_ADDR to, int opcode, char *payload, int len) -{ - LOCAL_ARRAY(char, pkt, MAX_PKT_SZ); - - struct icmphdr *icmp = NULL; - icmpEchoData *echo; - - size_t icmp_pktsize = sizeof(struct icmphdr); - - struct sockaddr_in S; - memset(pkt, '\0', MAX_PKT_SZ); - - icmp = (struct icmphdr *) (void *) pkt; - - /* - * cevans - beware signed/unsigned issues in untrusted data from - * the network!! - */ - - if (len < 0) - { - len = 0; - } - - icmp->icmp_type = ICMP_ECHO; - icmp->icmp_code = 0; - icmp->icmp_cksum = 0; - icmp->icmp_id = icmp_ident; - icmp->icmp_seq = (u_short) icmp_pkts_sent++; - echo = (icmpEchoData *) (icmp + 1); - echo->opcode = (unsigned char) opcode; - echo->tv = current_time; - - icmp_pktsize += sizeof(struct timeval) + sizeof(char); - - if (payload) - { - if (len > MAX_PAYLOAD) - len = MAX_PAYLOAD; - - xmemcpy(echo->payload, payload, len); - - icmp_pktsize += len; - } - - icmp->icmp_cksum = in_cksum((u_short *) icmp, icmp_pktsize); - S.sin_family = AF_INET; - /* - * cevans: alert: trusting to-host, was supplied in network packet - */ - S.sin_addr = to; - S.sin_port = 0; - assert(icmp_pktsize <= MAX_PKT_SZ); - sendto(icmp_sock, - (const void *) pkt, - icmp_pktsize, - 0, - - (struct sockaddr *) &S, - - sizeof(struct sockaddr_in)); - pingerLog(icmp, to, 0, 0); -} - -static void -pingerRecv(void) -{ - int n; - socklen_t fromlen; - - struct sockaddr_in from; - int iphdrlen = 20; - - struct iphdr *ip = NULL; - - struct icmphdr *icmp = NULL; - static char *pkt = NULL; - - struct timeval now; - icmpEchoData *echo; - static pingerReplyData preply; - - if (pkt == NULL) - pkt = (char *)xmalloc(MAX_PKT_SZ); - - fromlen = sizeof(from); - - n = recvfrom(icmp_sock, - (void *)pkt, - MAX_PKT_SZ, - 0, - - (struct sockaddr *) &from, - &fromlen); - -#if GETTIMEOFDAY_NO_TZP - - gettimeofday(&now); - -#else - - gettimeofday(&now, NULL); - -#endif - - debugs(42, 9, "pingerRecv: " << n << " bytes from " << - inet_ntoa(from.sin_addr)); - - ip = (struct iphdr *) (void *) pkt; - -#if HAVE_STRUCT_IPHDR_IP_HL - - iphdrlen = ip->ip_hl << 2; - -#else /* HAVE_STRUCT_IPHDR_IP_HL */ -#if WORDS_BIGENDIAN - - iphdrlen = (ip->ip_vhl >> 4) << 2; - -#else - - iphdrlen = (ip->ip_vhl & 0xF) << 2; - -#endif -#endif /* HAVE_STRUCT_IPHDR_IP_HL */ - - icmp = (struct icmphdr *) (void *) (pkt + iphdrlen); - - if (icmp->icmp_type != ICMP_ECHOREPLY) - return; - - if (icmp->icmp_id != icmp_ident) - return; - - echo = (icmpEchoData *) (void *) (icmp + 1); - - preply.from = from.sin_addr; - - preply.opcode = echo->opcode; - - preply.hops = ipHops(ip->ip_ttl); - - preply.rtt = tvSubMsec(echo->tv, now); - - preply.psize = n - iphdrlen - (sizeof(icmpEchoData) - MAX_PKT_SZ); - - pingerSendtoSquid(&preply); - - pingerLog(icmp, from.sin_addr, preply.rtt, preply.hops); -} - - -static int -in_cksum(unsigned short *ptr, int size) -{ - long sum; - unsigned short oddbyte; - unsigned short answer; - sum = 0; - - while (size > 1) { - sum += *ptr++; - size -= 2; - } - - if (size == 1) { - oddbyte = 0; - *((unsigned char *) &oddbyte) = *(unsigned char *) ptr; - sum += oddbyte; - } - - sum = (sum >> 16) + (sum & 0xffff); - sum += (sum >> 16); - answer = (unsigned short) ~sum; - return (answer); + icmp4.Close(); } -static void - -pingerLog(struct icmphdr *icmp, struct IN_ADDR addr, int rtt, int hops) +void +pingerLog(const IPAddress &addr, const u_int8_t type, const char* pkt_str, const int rtt, const int hops) { debugs(42, 2, "pingerLog: " << std::setw(9) << current_time.tv_sec << - "."<< std::setfill('0') << std::setw(6) << - current_time.tv_usec << " "<< std::left << std::setfill(' ')<< - std::setw(16) << inet_ntoa(addr) << " "<< icmp->icmp_type << - " " << std::setw(15) << icmpPktStr[icmp->icmp_type] << " " << rtt << + "." << std::setfill('0') << std::setw(6) << + current_time.tv_usec << " " << std::left << std::setfill(' ') << + std::setw(45) << addr << " " << type << + " " << std::setw(15) << pkt_str << " " << rtt << "ms " << hops << " hops"); } static int -ipHops(int ttl) -{ - if (ttl < 33) - return 33 - ttl; - - if (ttl < 63) - return 63 - ttl; /* 62 = (64+60)/2 */ - - if (ttl < 65) - return 65 - ttl; /* 62 = (64+60)/2 */ - - if (ttl < 129) - return 129 - ttl; - - if (ttl < 193) - return 193 - ttl; - - return 256 - ttl; -} - -static int pingerReadRequest(void) { static pingerEchoData pecho; @@ -580,14 +321,14 @@ return 0; } - pingerSendEcho(pecho.to, + icmp4.SendEcho(pecho.to, pecho.opcode, pecho.payload, pecho.psize); return n; } -static void +void pingerSendtoSquid(pingerReplyData * preply) { int len = sizeof(pingerReplyData) - MAX_PKT_SZ + preply->psize; @@ -647,7 +388,7 @@ } if (FD_ISSET(icmp_sock, &R)) - pingerRecv(); + icmp4.Recv(); if (PINGER_TIMEOUT + last_check_time < squid_curtime) { if (send(socket_to_squid, &tv, 0, 0) < 0) { Index: squid3/src/structs.h =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/structs.h,v retrieving revision 1.66.2.31 retrieving revision 1.66.2.32 diff -u -r1.66.2.31 -r1.66.2.32 --- squid3/src/structs.h 30 Sep 2007 16:13:31 -0000 1.66.2.31 +++ squid3/src/structs.h 6 Oct 2007 15:17:07 -0000 1.66.2.32 @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.66.2.31 2007/09/30 16:13:31 serassio Exp $ + * $Id: structs.h,v 1.66.2.32 2007/10/06 15:17:07 amosjeffries Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -1192,20 +1192,18 @@ #if USE_ICMP /* This is a line-data format struct. DO NOT alter. */ -struct _pingerEchoData +struct pingerEchoData { - - struct in_addr to; + IPAddress to; unsigned char opcode; int psize; char payload[PINGER_PAYLOAD_SZ]; }; /* This is a line-data format struct. DO NOT alter. */ -struct _pingerReplyData +struct pingerReplyData { - - struct in_addr from; + IPAddress from; unsigned char opcode; int rtt; int hops; Index: squid3/src/typedefs.h =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/typedefs.h,v retrieving revision 1.36.4.3 retrieving revision 1.36.4.4 diff -u -r1.36.4.3 -r1.36.4.4 --- squid3/src/typedefs.h 11 Jun 2007 13:51:49 -0000 1.36.4.3 +++ squid3/src/typedefs.h 6 Oct 2007 15:17:07 -0000 1.36.4.4 @@ -1,6 +1,6 @@ /* - * $Id: typedefs.h,v 1.36.4.3 2007/06/11 13:51:49 amosjeffries Exp $ + * $Id: typedefs.h,v 1.36.4.4 2007/10/06 15:17:07 amosjeffries Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -146,10 +146,6 @@ typedef struct _netdbEntry netdbEntry; -typedef struct _pingerEchoData pingerEchoData; - -typedef struct _pingerReplyData pingerReplyData; - typedef struct _icp_common_t icp_common_t; typedef struct _Meta_data Meta_data;