]> git.ipfire.org Git - thirdparty/squid.git/blame - src/icmp/Icmp4.cc
Renamed squid.h to squid-old.h and config.h to squid.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
f7f3304a 36#include "squid-old.h"
cc192b50 37
38#if USE_ICMP
39
40#include "SquidTime.h"
b826ffb5
AJ
41#include "Icmp4.h"
42#include "IcmpPinger.h"
cc192b50 43#include "Debug.h"
44
26ac0430
AJ
45const char *icmpPktStr[] = {
46 "Echo Reply",
47 "ICMP 1",
48 "ICMP 2",
49 "Destination Unreachable",
50 "Source Quench",
51 "Redirect",
52 "ICMP 6",
53 "ICMP 7",
54 "Echo",
55 "ICMP 9",
56 "ICMP 10",
57 "Time Exceeded",
58 "Parameter Problem",
59 "Timestamp",
60 "Timestamp Reply",
61 "Info Request",
62 "Info Reply",
63 "Out of Range Type"
64};
cc192b50 65
b826ffb5 66Icmp4::Icmp4() : Icmp()
26ac0430
AJ
67{
68 ;
cc192b50 69}
70
b826ffb5 71Icmp4::~Icmp4()
cc192b50 72{
73 Close();
74}
75
76int
b826ffb5 77Icmp4::Open(void)
cc192b50 78{
79 icmp_sock = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
80
81 if (icmp_sock < 0) {
82 debugs(50, 0, HERE << " icmp_sock: " << xstrerror());
83 return -1;
84 }
85
86 icmp_ident = getpid() & 0xffff;
87 debugs(42, 1, "pinger: ICMP socket opened.");
88
89 return icmp_sock;
90}
91
92void
b7ac5457 93Icmp4::SendEcho(Ip::Address &to, int opcode, const char *payload, int len)
cc192b50 94{
95 int x;
96 LOCAL_ARRAY(char, pkt, MAX_PKT4_SZ);
97
98 struct icmphdr *icmp = NULL;
99 icmpEchoData *echo;
100 size_t icmp_pktsize = sizeof(struct icmphdr);
101 struct addrinfo *S = NULL;
102
103 memset(pkt, '\0', MAX_PKT4_SZ);
104
105 icmp = (struct icmphdr *) (void *) pkt;
106
107 /*
108 * cevans - beware signed/unsigned issues in untrusted data from
109 * the network!!
110 */
26ac0430 111 if (len < 0) {
cc192b50 112 len = 0;
113 }
114
115 // Construct ICMP packet header
116 icmp->icmp_type = ICMP_ECHO;
117 icmp->icmp_code = 0;
118 icmp->icmp_cksum = 0;
119 icmp->icmp_id = icmp_ident;
f45dd259 120 icmp->icmp_seq = (unsigned short) icmp_pkts_sent++;
cc192b50 121
122 // Construct ICMP packet data content
123 echo = (icmpEchoData *) (icmp + 1);
124 echo->opcode = (unsigned char) opcode;
c3c6695b 125 memcpy(&echo->tv, &current_time, sizeof(struct timeval));
cc192b50 126
127 icmp_pktsize += sizeof(struct timeval) + sizeof(char);
128
26ac0430 129 if (payload) {
cc192b50 130 if (len > MAX_PAYLOAD)
131 len = MAX_PAYLOAD;
132
41d00cd3 133 memcpy(echo->payload, payload, len);
cc192b50 134
135 icmp_pktsize += len;
136 }
137
f45dd259 138 icmp->icmp_cksum = CheckSum((unsigned short *) icmp, icmp_pktsize);
cc192b50 139
140 to.GetAddrInfo(S);
141 ((sockaddr_in*)S->ai_addr)->sin_port = 0;
142 assert(icmp_pktsize <= MAX_PKT4_SZ);
143
30c48b1a 144 debugs(42, 5, HERE << "Send ICMP packet to " << to << ".");
cc192b50 145
146 x = sendto(icmp_sock,
26ac0430
AJ
147 (const void *) pkt,
148 icmp_pktsize,
149 0,
150 S->ai_addr,
151 S->ai_addrlen);
cc192b50 152
26ac0430 153 if (x < 0) {
cc192b50 154 debugs(42, 1, HERE << "Error sending to ICMP packet to " << to << ". ERR: " << xstrerror());
155 }
156
157 Log(to, ' ', NULL, 0, 0);
158}
159
160void
b826ffb5 161Icmp4::Recv(void)
cc192b50 162{
163 int n;
164 struct addrinfo *from = NULL;
165 int iphdrlen = sizeof(iphdr);
166 struct iphdr *ip = NULL;
167 struct icmphdr *icmp = NULL;
168 static char *pkt = NULL;
169 struct timeval now;
170 icmpEchoData *echo;
171 static pingerReplyData preply;
172
26ac0430 173 if (icmp_sock < 0) {
cc192b50 174 debugs(42, 0, HERE << "No socket! Recv() should not be called.");
175 return;
176 }
177
178 if (pkt == NULL)
179 pkt = (char *)xmalloc(MAX_PKT4_SZ);
180
181 preply.from.InitAddrInfo(from);
182 n = recvfrom(icmp_sock,
183 (void *)pkt,
184 MAX_PKT4_SZ,
185 0,
186 from->ai_addr,
187 &from->ai_addrlen);
188
189 preply.from = *from;
190
191#if GETTIMEOFDAY_NO_TZP
192
193 gettimeofday(&now);
194
195#else
196
197 gettimeofday(&now, NULL);
198
199#endif
200
201 debugs(42, 8, HERE << n << " bytes from " << preply.from);
202
203 ip = (struct iphdr *) (void *) pkt;
204
205#if HAVE_STRUCT_IPHDR_IP_HL
206
207 iphdrlen = ip->ip_hl << 2;
208
209#else /* HAVE_STRUCT_IPHDR_IP_HL */
210#if WORDS_BIGENDIAN
211
212 iphdrlen = (ip->ip_vhl >> 4) << 2;
213
214#else
215
216 iphdrlen = (ip->ip_vhl & 0xF) << 2;
217
218#endif
219#endif /* HAVE_STRUCT_IPHDR_IP_HL */
220
221 icmp = (struct icmphdr *) (void *) (pkt + iphdrlen);
222
223 if (icmp->icmp_type != ICMP_ECHOREPLY)
224 return;
225
226 if (icmp->icmp_id != icmp_ident)
227 return;
228
229 echo = (icmpEchoData *) (void *) (icmp + 1);
230
231 preply.opcode = echo->opcode;
232
233 preply.hops = ipHops(ip->ip_ttl);
234
c3c6695b 235 struct timeval tv;
236 memcpy(&tv, &echo->tv, sizeof(struct timeval));
237 preply.rtt = tvSubMsec(tv, now);
cc192b50 238
239 preply.psize = n - iphdrlen - (sizeof(icmpEchoData) - MAX_PKT4_SZ);
240
241 control.SendResult(preply, (sizeof(pingerReplyData) - MAX_PKT4_SZ + preply.psize) );
242
243 Log(preply.from, icmp->icmp_type, icmpPktStr[icmp->icmp_type], preply.rtt, preply.hops);
244}
245
246#endif /* USE_ICMP */