]> git.ipfire.org Git - thirdparty/squid.git/blame - src/icmp/IcmpPinger.cc
Boilerplate: update copyright blurbs on src/
[thirdparty/squid.git] / src / icmp / IcmpPinger.cc
CommitLineData
cc192b50 1/*
bbc27441 2 * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
cc192b50 3 *
bbc27441
AJ
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
cc192b50 7 */
8
bbc27441
AJ
9/* DEBUG: section 42 ICMP Pinger program */
10
cc192b50 11#define SQUID_HELPER 1
12
582c2af2 13#include "squid.h"
cc192b50 14
15#if USE_ICMP
16
602d9612 17#include "Debug.h"
b826ffb5
AJ
18#include "Icmp4.h"
19#include "Icmp6.h"
602d9612
A
20#include "IcmpPinger.h"
21#include "SquidTime.h"
cc192b50 22
1a30fdf5 23#include <cerrno>
21d845b1 24
b826ffb5 25IcmpPinger::IcmpPinger() : Icmp()
cc192b50 26{
27 // these start invalid. Setup properly in Open()
28 socket_from_squid = -1;
29 socket_to_squid = -1;
30}
31
b826ffb5 32IcmpPinger::~IcmpPinger()
cc192b50 33{
34 Close();
35}
36
7aa9bb3e 37#if _SQUID_WINDOWS_
ec556193
GS
38void
39Win32SockCleanup(void)
40{
41 WSACleanup();
42 return;
43}
44#endif
45
cc192b50 46int
b826ffb5 47IcmpPinger::Open(void)
cc192b50 48{
7aa9bb3e 49#if _SQUID_WINDOWS_
cc192b50 50
51 WSADATA wsaData;
52 WSAPROTOCOL_INFO wpi;
53 char buf[sizeof(wpi)];
54 int x;
55
56 struct sockaddr_in PS;
57
58 WSAStartup(2, &wsaData);
ec556193 59 atexit(Win32SockCleanup);
cc192b50 60
61 getCurrentTime();
62 _db_init(NULL, "ALL,1");
63 setmode(0, O_BINARY);
64 setmode(1, O_BINARY);
65 x = read(0, buf, sizeof(wpi));
66
67 if (x < (int)sizeof(wpi)) {
68 getCurrentTime();
fa84c01d 69 debugs(42, DBG_CRITICAL, HERE << "read: FD 0: " << xstrerror());
cc192b50 70 write(1, "ERR\n", 4);
71 return -1;
72 }
73
41d00cd3 74 memcpy(&wpi, buf, sizeof(wpi));
cc192b50 75
76 write(1, "OK\n", 3);
77 x = read(0, buf, sizeof(PS));
78
79 if (x < (int)sizeof(PS)) {
80 getCurrentTime();
fa84c01d 81 debugs(42, DBG_CRITICAL, HERE << "read: FD 0: " << xstrerror());
cc192b50 82 write(1, "ERR\n", 4);
83 return -1;
84 }
85
41d00cd3 86 memcpy(&PS, buf, sizeof(PS));
cc192b50 87
88 icmp_sock = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, &wpi, 0, 0);
89
90 if (icmp_sock == -1) {
91 getCurrentTime();
fa84c01d 92 debugs(42, DBG_CRITICAL, HERE << "WSASocket: " << xstrerror());
cc192b50 93 write(1, "ERR\n", 4);
94 return -1;
95 }
96
97 x = connect(icmp_sock, (struct sockaddr *) &PS, sizeof(PS));
98
99 if (SOCKET_ERROR == x) {
100 getCurrentTime();
fa84c01d 101 debugs(42, DBG_CRITICAL, HERE << "connect: " << xstrerror());
cc192b50 102 write(1, "ERR\n", 4);
103 return -1;
104 }
105
106 write(1, "OK\n", 3);
107 memset(buf, 0, sizeof(buf));
108 x = recv(icmp_sock, (void *) buf, sizeof(buf), 0);
109
110 if (x < 3) {
fa84c01d 111 debugs(42, DBG_CRITICAL, HERE << "recv: " << xstrerror());
cc192b50 112 return -1;
113 }
114
115 x = send(icmp_sock, (const void *) buf, strlen(buf), 0);
116
117 if (x < 3 || strncmp("OK\n", buf, 3)) {
fa84c01d 118 debugs(42, DBG_CRITICAL, HERE << "recv: " << xstrerror());
cc192b50 119 return -1;
120 }
121
122 getCurrentTime();
e0236918 123 debugs(42, DBG_IMPORTANT, "pinger: Squid socket opened");
cc192b50 124
125 /* windows uses a socket stream as a dual-direction channel */
126 socket_to_squid = icmp_sock;
127 socket_from_squid = icmp_sock;
128
129 return icmp_sock;
130
7aa9bb3e 131#else /* !_SQUID_WINDOWS_ */
cc192b50 132
133 /* non-windows apps use stdin/out pipes as the squid channel(s) */
134 socket_from_squid = 0; // use STDIN macro ??
135 socket_to_squid = 1; // use STDOUT macro ??
136 return socket_to_squid;
137#endif
138}
139
140void
b826ffb5 141IcmpPinger::Close(void)
cc192b50 142{
7aa9bb3e 143#if _SQUID_WINDOWS_
cc192b50 144
145 shutdown(icmp_sock, SD_BOTH);
146 close(icmp_sock);
147 icmp_sock = -1;
148#endif
149
150 /* also shutdown the helper engines */
151 icmp4.Close();
cc192b50 152 icmp6.Close();
cc192b50 153}
154
155void
b826ffb5 156IcmpPinger::Recv(void)
cc192b50 157{
158 static pingerEchoData pecho;
159 int n;
160 int guess_size;
161
162 memset(&pecho, '\0', sizeof(pecho));
163 n = recv(socket_from_squid, &pecho, sizeof(pecho), 0);
164
165 if (n < 0) {
e0236918 166 debugs(42, DBG_IMPORTANT, "Pinger exiting.");
cc192b50 167 Close();
168 exit(1);
169 }
170
171 if (0 == n) {
172 /* EOF indicator */
fa84c01d 173 debugs(42, DBG_CRITICAL, HERE << "EOF encountered. Pinger exiting.\n");
cc192b50 174 errno = 0;
175 Close();
176 exit(1);
177 }
178
179 guess_size = n - (sizeof(pingerEchoData) - PINGER_PAYLOAD_SZ);
180
181 if (guess_size != pecho.psize) {
182 debugs(42, 2, HERE << "size mismatch, guess=" << guess_size << ", psize=" << pecho.psize);
183 /* don't process this message, but keep running */
184 return;
185 }
186
cc192b50 187 /* pass request for ICMPv6 handing */
4dd643d5 188 if (pecho.to.isIPv6()) {
cc192b50 189 debugs(42, 2, HERE << " Pass " << pecho.to << " off to ICMPv6 module.");
190 icmp6.SendEcho(pecho.to,
191 pecho.opcode,
192 pecho.payload,
193 pecho.psize);
194 }
cc192b50 195
196 /* pass the packet for ICMP handling */
4dd643d5 197 else if (pecho.to.isIPv4()) {
cc192b50 198 debugs(42, 2, HERE << " Pass " << pecho.to << " off to ICMPv4 module.");
199 icmp4.SendEcho(pecho.to,
200 pecho.opcode,
201 pecho.payload,
202 pecho.psize);
26ac0430 203 } else {
e0236918 204 debugs(42, DBG_IMPORTANT, HERE << " IP has unknown Type. " << pecho.to );
cc192b50 205 }
206}
207
208void
b826ffb5 209IcmpPinger::SendResult(pingerReplyData &preply, int len)
cc192b50 210{
211 debugs(42, 2, HERE << "return result to squid. len=" << len);
212
213 if (send(socket_to_squid, &preply, len, 0) < 0) {
fa84c01d 214 debugs(42, DBG_CRITICAL, "pinger: FATAL error on send: " << xstrerror());
cc192b50 215 Close();
216 exit(1);
217 }
218}
219
220#endif /* USE_ICMP */