* extract out the ICMPv4 related stuff, throw in libpinger
* break apart "assemble and send ICMPv4 packet" and "populate icmpSendEcho
bits"
so to enforce sensible API layering.
http://code.google.com/p/lusca-cache/source/detail?r=14917
Added:
/playpen/LUSCA_HEAD_ipv6/libpinger
/playpen/LUSCA_HEAD_ipv6/libpinger/Makefile.am
/playpen/LUSCA_HEAD_ipv6/libpinger/icmp_v4.c
/playpen/LUSCA_HEAD_ipv6/libpinger/icmp_v4.h
/playpen/LUSCA_HEAD_ipv6/libpinger/icmp_v6.c
/playpen/LUSCA_HEAD_ipv6/libpinger/icmp_v6.h
Modified:
/playpen/LUSCA_HEAD_ipv6/Makefile.am
/playpen/LUSCA_HEAD_ipv6/configure.in
/playpen/LUSCA_HEAD_ipv6/src/Makefile.am
/playpen/LUSCA_HEAD_ipv6/src/pinger.c
=======================================
--- /dev/null
+++ /playpen/LUSCA_HEAD_ipv6/libpinger/Makefile.am Thu Jul 14 04:10:35 2011
@@ -0,0 +1,10 @@
+## Process this file with automake to produce Makefile.in
+
+INCLUDES = -I. -I$(top_builddir)
+
+libpinger_a_SOURCES = \
+ icmp_v4.c \
+ icmp_v6.c
+
+noinst_LIBRARIES = \
+ libpinger.a
=======================================
--- /dev/null
+++ /playpen/LUSCA_HEAD_ipv6/libpinger/icmp_v4.c Thu Jul 14 04:10:35 2011
@@ -0,0 +1,194 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 42 ICMP/Pinger
+ * AUTHOR: Harvest Derived
+ *
+ * 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.
+ *
+ */
+
+#include "../include/config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#if !defined(_SQUID_WIN32_)
+
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+
+#define PINGER_TIMEOUT 10
+
+#else /* _SQUID_WIN32_ */
+
+#ifdef _SQUID_MSWIN_
+
+#if HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+#include <process.h>
+
+#define PINGER_TIMEOUT 5
+
+static SOCKET socket_to_squid = -1;
+#define socket_from_squid socket_to_squid
+
+#else /* _SQUID_MSWIN */
+
+/* Cygwin */
+
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+
+#define PINGER_TIMEOUT 10
+
+static int socket_from_squid = 0;
+static int socket_to_squid = 1;
+
+#endif /* _SQUID_MSWIN_ */
+
+#endif /* _SQUID_WIN32_ */
+
+#include "include/util.h"
+#include "libcore/tools.h"
+#include "libsqdebug/debug.h"
+
+#include "icmp_v4.h"
+
+/* IPv4 ICMP type strings */
+
+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"
+};
+
+int icmp_ident = -1;
+int icmp_pkts_sent = 0;
+
+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);
+}
+
+/*
+ * Assemble an IPv4 ICMP Echo packet.
+ *
+ * This doesn't know about the payload layout; it simply assembles the
+ * packet and fires it off.
+ */
+void
+pingerv4SendEcho(int icmp_sock, struct in_addr to, int opcode, char
*payload,
+ int len)
+{
+ LOCAL_ARRAY(char, pkt, MAX_PKT_SZ);
+ struct icmphdr *icmp = NULL;
+
+ int 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++;
+
+ /* The ICMP payload is the entire 'payload' + 'len' */
+ /* The caller will setup the tmimestamp and icmpEchoData */
+
+ if (payload) {
+ if (len > MAX_PAYLOAD)
+ len = MAX_PAYLOAD;
+ xmemcpy(pkt + sizeof(struct icmphdr), 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,
+ pkt,
+ icmp_pktsize,
+ 0,
+ (struct sockaddr *) &S,
+ sizeof(struct sockaddr_in));
+}
+
=======================================
--- /dev/null
+++ /playpen/LUSCA_HEAD_ipv6/libpinger/icmp_v4.h Thu Jul 14 04:10:35 2011
@@ -0,0 +1,99 @@
+#ifndef __LIBPINGER_ICMP_V4_H__
+#define __LIBPINGER_ICMP_V4_H__
+
+
+
+#if defined(_SQUID_WIN32_)
+
+/*
+ * 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.
+ */
+
+#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_WIN32_ */
+
+/*
+ * Linux short-cuts
+ */
+#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
+
+/*
+ * BSDisms?
+ */
+#ifndef _SQUID_LINUX_
+#ifndef _SQUID_WIN32_
+#define icmphdr icmp
+#define iphdr ip
+#endif
+#endif
+
+#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
+
+extern const char *icmpPktStr[];
+
+extern int icmp_ident;
+extern int icmp_pkts_sent;
+
+extern void pingerv4SendEcho(int sock, struct in_addr to, int opcode,
+ char *payload, int len);
+
+#endif /* __LIBPINGER_ICMP_V4_H__ */
=======================================
--- /playpen/LUSCA_HEAD_ipv6/Makefile.am Tue Aug 31 09:02:21 2010
+++ /playpen/LUSCA_HEAD_ipv6/Makefile.am Thu Jul 14 04:10:35 2011
@@ -4,8 +4,8 @@
#
AUTOMAKE_OPTIONS = dist-bzip2 subdir-objects 1.5
-DIST_SUBDIRS = lib libcore libmem libsqname libcb libiapp libstat libsqftp
libsqurl libhttp libsqdns libsqident libsqinet libhelper libmime libsqdebug
libstmem libasyncio libsqtlv libsqstore snmplib scripts src icons errors
contrib doc helpers tools app test-suite
-SUBDIRS = lib libcore libmem libsqname libcb libiapp libstat libsqftp
libsqurl libhttp libsqdns libsqident libsqinet libhelper libmime libsqdebug
libstmem libasyncio libsqtlv libsqstore @makesnmplib@ scripts src icons
errors doc helpers tools app test-suite
+DIST_SUBDIRS = lib libcore libmem libsqname libcb libiapp libstat libsqftp
libsqurl libhttp libsqdns libsqident libsqinet libhelper libmime libsqdebug
libstmem libasyncio libsqtlv libsqstore libpinger snmplib scripts src icons
errors contrib doc helpers tools app test-suite
+SUBDIRS = lib libcore libmem libsqname libcb libiapp libstat libsqftp
libsqurl libhttp libsqdns libsqident libsqinet libhelper libmime libsqdebug
libstmem libasyncio libsqtlv libsqstore libpinger @makesnmplib@ scripts src
icons errors doc helpers tools app test-suite
DISTCLEANFILES = include/stamp-h include/stamp-h[0-9]*
DEFAULT_PINGER = $(libexecdir)/`echo pinger |
sed '$(transform);s/$$/$(EXEEXT)/'`
=======================================
--- /playpen/LUSCA_HEAD_ipv6/configure.in Tue Aug 31 09:02:21 2010
+++ /playpen/LUSCA_HEAD_ipv6/configure.in Thu Jul 14 04:10:35 2011
@@ -3331,6 +3331,7 @@
app/ufs_rebuild/Makefile \
app/ufs_newfs/Makefile \
app/tcptest/Makefile \
+ libpinger/Makefile \
libsqstore/Makefile \
libsqtlv/Makefile \
libmime/Makefile \
=======================================
--- /playpen/LUSCA_HEAD_ipv6/src/Makefile.am Sat Jul 2 02:29:37 2011
+++ /playpen/LUSCA_HEAD_ipv6/src/Makefile.am Thu Jul 14 04:10:35 2011
@@ -317,7 +317,7 @@
data_DATA = \
mib.txt
-LDADD = -L../lib -L../libcore -L../libsqdebug -L../libmem -L../libsqname
-L../libcb -L../libhelper -L../libmime -L../libstmem -L../libiapp
-L../libsqftp -L../libsqurl -L../libhttp -L../libstat -L../libsqdns
-L../libsqident -L../libsqinet -L../libasyncio -L../libsqtlv
-L../libsqstore -lsqstore -lsqtlv -lasyncio -lsqinet -lsqdns -lsqdebug
-lcore -lmem -lsqname -lcb -lsqident -lhelper -lmime -lstmem -liapp -lsqftp
-lsqurl -lhttp -lstat -lmiscutil @XTRA_LIBS@
+LDADD = -L../lib -L../libcore -L../libsqdebug -L../libmem -L../libsqname
-L../libcb -L../libhelper -L../libmime -L../libstmem -L../libiapp
-L../libsqftp -L../libsqurl -L../libhttp -L../libstat -L../libsqdns
-L../libsqident -L../libsqinet -L../libasyncio -L../libsqtlv
-L../libsqstore -L../libpinger -lpinger -lsqstore -lsqtlv -lasyncio
-lsqinet -lsqdns -lsqdebug -lcore -lmem -lsqname -lcb -lsqident -lhelper
-lmime -lstmem -liapp -lsqftp -lsqurl -lhttp -lstat -lmiscutil @XTRA_LIBS@
EXTRA_DIST = \
cf_gen_defines \
=======================================
--- /playpen/LUSCA_HEAD_ipv6/src/pinger.c Wed Jul 13 02:00:28 2011
+++ /playpen/LUSCA_HEAD_ipv6/src/pinger.c Thu Jul 14 04:10:35 2011
@@ -70,7 +70,9 @@
static SOCKET socket_to_squid = -1;
#define socket_from_squid socket_to_squid
-#else /* _SQUID_CYGWIN_ */
+#else /* _SQUID_MSWIN */
+
+/* Cygwin */
#include <netinet/in_systm.h>
#include <netinet/in.h>
@@ -82,76 +84,12 @@
static int socket_from_squid = 0;
static int socket_to_squid = 1;
-#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_WIN32_
-#define icmphdr icmp
-#define iphdr ip
-#endif
-#endif
-
-#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
-
-#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
+#endif /* _SQUID_WIN32_ */
+
+#include "../libpinger/icmp_v4.h"
+#include "../libpinger/icmp_v6.h"
typedef struct {
struct timeval tv;
@@ -159,34 +97,8 @@
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 void pingerLog(int, struct in_addr, int, int);
static int ipHops(int ttl);
static void pingerSendtoSquid(pingerReplyData * preply);
static void pingerOpen(void);
@@ -299,51 +211,24 @@
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;
- int 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;
- memcpy(&echo->tv, ¤t_time, sizeof(current_time));
- icmp_pktsize += sizeof(struct timeval) + sizeof(char);
+ icmpEchoData echo;
+ int icmp_pktsize;
+
+ /* Assemble the icmpEcho payload */
+ echo.opcode = (unsigned char) opcode;
+ memcpy(&echo.tv, ¤t_time, sizeof(current_time));
+
+ /* size of the IcmpEchoData header */
+ icmp_pktsize = sizeof(struct timeval) + sizeof(char);
+
+ /* If there's a payload, add it */
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,
- pkt,
- icmp_pktsize,
- 0,
- (struct sockaddr *) &S,
- sizeof(struct sockaddr_in));
- pingerLog(icmp, to, 0, 0);
+ memcpy(echo.payload, payload, MIN(len, MAX_PAYLOAD));
+ icmp_pktsize += MIN(len, MAX_PAYLOAD);
+ }
+
+ pingerv4SendEcho(icmp_sock, to, opcode, (char *) &echo, icmp_pktsize);
+ pingerLog(ICMP_ECHO, to, 0, 0);
}
static void
@@ -409,41 +294,18 @@
preply.rtt = tvSubMsec(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);
+ pingerLog(icmp->icmp_type, from.sin_addr, preply.rtt, preply.hops);
}
static void
-pingerLog(struct icmphdr *icmp, struct in_addr addr, int rtt, int hops)
+pingerLog(int icmp_type, struct in_addr addr, int rtt, int hops)
{
debug(42, 2) ("pingerLog: %9d.%06d %-16s %d %-15.15s %dms %d hops\n",
(int) current_time.tv_sec,
(int) current_time.tv_usec,
inet_ntoa(addr),
- (int) icmp->icmp_type,
- icmpPktStr[icmp->icmp_type],
+ (int) icmp_type,
+ icmpPktStr[icmp_type],
rtt,
hops);
}