]> git.ipfire.org Git - thirdparty/squid.git/blame - src/icmp/Icmp4.cc
Removed squid-old.h
[thirdparty/squid.git] / src / icmp / Icmp4.cc
CommitLineData
cc192b50 1/*
262a0e14 2 * $Id$
cc192b50 3 *
4 * DEBUG: section 42 ICMP Pinger program
5 * AUTHOR: Duane Wessels, Amos Jeffries
6 *
7 * SQUID Web Proxy Cache http://www.squid-cache.org/
8 * ----------------------------------------------------------
9 *
10 * Squid is the result of efforts by numerous individuals from
11 * the Internet community; see the CONTRIBUTORS file for full
12 * details. Many organizations have provided support for Squid's
13 * development; see the SPONSORS file for full details. Squid is
14 * Copyrighted (C) 2001 by the Regents of the University of
15 * California; see the COPYRIGHT file for full details. Squid
16 * incorporates software developed and/or copyrighted by other
17 * sources; see the CREDITS file for full details.
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
26ac0430 23 *
cc192b50 24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
26ac0430 28 *
cc192b50 29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
32 *
33 */
34//#define SQUID_HELPER 1
35
582c2af2 36#include "squid.h"
cc192b50 37
38#if USE_ICMP
39
582c2af2 40#include "leakcheck.h"
cc192b50 41#include "SquidTime.h"
b826ffb5
AJ
42#include "Icmp4.h"
43#include "IcmpPinger.h"
cc192b50 44#include "Debug.h"
45
26ac0430
AJ
46const char *icmpPktStr[] = {
47 "Echo Reply",
48 "ICMP 1",
49 "ICMP 2",
50 "Destination Unreachable",
51 "Source Quench",
52 "Redirect",
53 "ICMP 6",
54 "ICMP 7",
55 "Echo",
56 "ICMP 9",
57 "ICMP 10",
58 "Time Exceeded",
59 "Parameter Problem",
60 "Timestamp",
61 "Timestamp Reply",
62 "Info Request",
63 "Info Reply",
64 "Out of Range Type"
65};
cc192b50 66
b826ffb5 67Icmp4::Icmp4() : Icmp()
26ac0430
AJ
68{
69 ;
cc192b50 70}
71
b826ffb5 72Icmp4::~Icmp4()
cc192b50 73{
74 Close();
75}
76
77int
b826ffb5 78Icmp4::Open(void)
cc192b50 79{
80 icmp_sock = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
81
82 if (icmp_sock < 0) {
fa84c01d 83 debugs(50, DBG_CRITICAL, HERE << " icmp_sock: " << xstrerror());
cc192b50 84 return -1;
85 }
86
87 icmp_ident = getpid() & 0xffff;
e0236918 88 debugs(42, DBG_IMPORTANT, "pinger: ICMP socket opened.");
cc192b50 89
90 return icmp_sock;
91}
92
93void
b7ac5457 94Icmp4::SendEcho(Ip::Address &to, int opcode, const char *payload, int len)
cc192b50 95{
96 int x;
97 LOCAL_ARRAY(char, pkt, MAX_PKT4_SZ);
98
99 struct icmphdr *icmp = NULL;
100 icmpEchoData *echo;
101 size_t icmp_pktsize = sizeof(struct icmphdr);
102 struct addrinfo *S = NULL;
103
104 memset(pkt, '\0', MAX_PKT4_SZ);
105
106 icmp = (struct icmphdr *) (void *) pkt;
107
108 /*
109 * cevans - beware signed/unsigned issues in untrusted data from
110 * the network!!
111 */
26ac0430 112 if (len < 0) {
cc192b50 113 len = 0;
114 }
115
116 // Construct ICMP packet header
117 icmp->icmp_type = ICMP_ECHO;
118 icmp->icmp_code = 0;
119 icmp->icmp_cksum = 0;
120 icmp->icmp_id = icmp_ident;
aec55359
FC
121 icmp->icmp_seq = (unsigned short) icmp_pkts_sent;
122 ++icmp_pkts_sent;
cc192b50 123
124 // Construct ICMP packet data content
125 echo = (icmpEchoData *) (icmp + 1);
126 echo->opcode = (unsigned char) opcode;
c3c6695b 127 memcpy(&echo->tv, &current_time, sizeof(struct timeval));
cc192b50 128
129 icmp_pktsize += sizeof(struct timeval) + sizeof(char);
130
26ac0430 131 if (payload) {
cc192b50 132 if (len > MAX_PAYLOAD)
133 len = MAX_PAYLOAD;
134
41d00cd3 135 memcpy(echo->payload, payload, len);
cc192b50 136
137 icmp_pktsize += len;
138 }
139
f45dd259 140 icmp->icmp_cksum = CheckSum((unsigned short *) icmp, icmp_pktsize);
cc192b50 141
142 to.GetAddrInfo(S);
143 ((sockaddr_in*)S->ai_addr)->sin_port = 0;
144 assert(icmp_pktsize <= MAX_PKT4_SZ);
145
30c48b1a 146 debugs(42, 5, HERE << "Send ICMP packet to " << to << ".");
cc192b50 147
148 x = sendto(icmp_sock,
26ac0430
AJ
149 (const void *) pkt,
150 icmp_pktsize,
151 0,
152 S->ai_addr,
153 S->ai_addrlen);
cc192b50 154
26ac0430 155 if (x < 0) {
e0236918 156 debugs(42, DBG_IMPORTANT, HERE << "Error sending to ICMP packet to " << to << ". ERR: " << xstrerror());
cc192b50 157 }
158
159 Log(to, ' ', NULL, 0, 0);
160}
161
162void
b826ffb5 163Icmp4::Recv(void)
cc192b50 164{
165 int n;
166 struct addrinfo *from = NULL;
167 int iphdrlen = sizeof(iphdr);
168 struct iphdr *ip = NULL;
169 struct icmphdr *icmp = NULL;
170 static char *pkt = NULL;
171 struct timeval now;
172 icmpEchoData *echo;
173 static pingerReplyData preply;
174
26ac0430 175 if (icmp_sock < 0) {
fa84c01d 176 debugs(42, DBG_CRITICAL, HERE << "No socket! Recv() should not be called.");
cc192b50 177 return;
178 }
179
180 if (pkt == NULL)
181 pkt = (char *)xmalloc(MAX_PKT4_SZ);
182
183 preply.from.InitAddrInfo(from);
184 n = recvfrom(icmp_sock,
185 (void *)pkt,
186 MAX_PKT4_SZ,
187 0,
188 from->ai_addr,
189 &from->ai_addrlen);
190
191 preply.from = *from;
192
193#if GETTIMEOFDAY_NO_TZP
194
195 gettimeofday(&now);
196
197#else
198
199 gettimeofday(&now, NULL);
200
201#endif
202
203 debugs(42, 8, HERE << n << " bytes from " << preply.from);
204
205 ip = (struct iphdr *) (void *) pkt;
206
207#if HAVE_STRUCT_IPHDR_IP_HL
208
209 iphdrlen = ip->ip_hl << 2;
210
211#else /* HAVE_STRUCT_IPHDR_IP_HL */
212#if WORDS_BIGENDIAN
213
214 iphdrlen = (ip->ip_vhl >> 4) << 2;
215
216#else
217
218 iphdrlen = (ip->ip_vhl & 0xF) << 2;
219
220#endif
221#endif /* HAVE_STRUCT_IPHDR_IP_HL */
222
223 icmp = (struct icmphdr *) (void *) (pkt + iphdrlen);
224
225 if (icmp->icmp_type != ICMP_ECHOREPLY)
226 return;
227
228 if (icmp->icmp_id != icmp_ident)
229 return;
230
231 echo = (icmpEchoData *) (void *) (icmp + 1);
232
233 preply.opcode = echo->opcode;
234
235 preply.hops = ipHops(ip->ip_ttl);
236
c3c6695b 237 struct timeval tv;
238 memcpy(&tv, &echo->tv, sizeof(struct timeval));
239 preply.rtt = tvSubMsec(tv, now);
cc192b50 240
241 preply.psize = n - iphdrlen - (sizeof(icmpEchoData) - MAX_PKT4_SZ);
242
243 control.SendResult(preply, (sizeof(pingerReplyData) - MAX_PKT4_SZ + preply.psize) );
244
245 Log(preply.from, icmp->icmp_type, icmpPktStr[icmp->icmp_type], preply.rtt, preply.hops);
246}
247
248#endif /* USE_ICMP */