IcmpPinger.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3 *
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.
7 */
8
9/* DEBUG: section 42 ICMP Pinger program */
10
11#define SQUID_HELPER 1
12
13#include "squid.h"
14
15#if USE_ICMP
16
17#include "debug/Stream.h"
18#include "Icmp4.h"
19#include "Icmp6.h"
20#include "IcmpPinger.h"
21
22#include <cerrno>
23
25{
26 // these start invalid. Setup properly in Open()
28 socket_to_squid = -1;
29}
30
32{
33 Close();
34}
35
36#if _SQUID_WINDOWS_
37void
39{
40 WSACleanup();
41 return;
42}
43#endif
44
45int
47{
48#if _SQUID_WINDOWS_
49
50 WSADATA wsaData;
51 WSAPROTOCOL_INFO wpi;
52 char buf[sizeof(wpi)];
53 int x;
54
55 struct sockaddr_in PS;
56 int xerrno;
57
58 WSAStartup(2, &wsaData);
59 atexit(Win32SockCleanup);
60
62
65
66 setmode(0, O_BINARY);
67 setmode(1, O_BINARY);
68 x = read(0, buf, sizeof(wpi));
69
70 if (x < (int)sizeof(wpi)) {
71 xerrno = errno;
73 debugs(42, DBG_CRITICAL, MYNAME << " read: FD 0: " << xstrerr(xerrno));
74 write(1, "ERR\n", 4);
75 return -1;
76 }
77
78 memcpy(&wpi, buf, sizeof(wpi));
79
80 write(1, "OK\n", 3);
81 x = read(0, buf, sizeof(PS));
82
83 if (x < (int)sizeof(PS)) {
84 xerrno = errno;
86 debugs(42, DBG_CRITICAL, MYNAME << " read: FD 0: " << xstrerr(xerrno));
87 write(1, "ERR\n", 4);
88 return -1;
89 }
90
91 memcpy(&PS, buf, sizeof(PS));
92
93 icmp_sock = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, &wpi, 0, 0);
94
95 if (icmp_sock == -1) {
96 xerrno = errno;
98 debugs(42, DBG_CRITICAL, MYNAME << "WSASocket: " << xstrerr(xerrno));
99 write(1, "ERR\n", 4);
100 return -1;
101 }
102
103 x = connect(icmp_sock, (struct sockaddr *) &PS, sizeof(PS));
104
105 if (SOCKET_ERROR == x) {
106 xerrno = errno;
108 debugs(42, DBG_CRITICAL, MYNAME << "connect: " << xstrerr(xerrno));
109 write(1, "ERR\n", 4);
110 return -1;
111 }
112
113 write(1, "OK\n", 3);
114 memset(buf, 0, sizeof(buf));
115 x = recv(icmp_sock, (void *) buf, sizeof(buf), 0);
116
117 if (x < 3) {
118 xerrno = errno;
119 debugs(42, DBG_CRITICAL, MYNAME << "recv: " << xstrerr(xerrno));
120 return -1;
121 }
122
123 x = send(icmp_sock, (const void *) buf, strlen(buf), 0);
124 xerrno = errno;
125
126 if (x < 3 || strncmp("OK\n", buf, 3)) {
127 debugs(42, DBG_CRITICAL, MYNAME << "recv: " << xstrerr(xerrno));
128 return -1;
129 }
130
132 debugs(42, DBG_IMPORTANT, "Squid socket opened");
133
134 /* windows uses a socket stream as a dual-direction channel */
137
138 return icmp_sock;
139
140#else /* !_SQUID_WINDOWS_ */
141
142 /* non-windows apps use stdin/out pipes as the squid channel(s) */
143 socket_from_squid = 0; // use STDIN macro ??
144 socket_to_squid = 1; // use STDOUT macro ??
145 return socket_to_squid;
146#endif
147}
148
149void
151{
152#if _SQUID_WINDOWS_
153
154 shutdown(icmp_sock, SD_BOTH);
155 close(icmp_sock);
156 icmp_sock = -1;
157#endif
158
159 /* also shutdown the helper engines */
160 icmp4.Close();
161 icmp6.Close();
162}
163
164void
166{
167 static pingerEchoData pecho;
168 int n;
169 int guess_size;
170
171 pecho = pingerEchoData();
172 n = recv(socket_from_squid, &pecho, sizeof(pecho), 0);
173
174 if (n < 0) {
175 debugs(42, DBG_IMPORTANT, "Pinger exiting.");
176 Close();
177 exit(EXIT_FAILURE);
178 }
179
180 if (0 == n) {
181 /* EOF indicator */
182 debugs(42, DBG_CRITICAL, "EOF encountered. Pinger exiting.");
183 errno = 0;
184 Close();
185 exit(EXIT_FAILURE);
186 }
187
188 guess_size = n - (sizeof(pingerEchoData) - PINGER_PAYLOAD_SZ);
189
190 if (guess_size != pecho.psize) {
191 debugs(42, 2, "size mismatch, guess=" << guess_size << ", psize=" << pecho.psize);
192 /* don't process this message, but keep running */
193 return;
194 }
195
196 /* pass request for ICMPv6 handing */
197 if (pecho.to.isIPv6()) {
198 debugs(42, 2, " Pass " << pecho.to << " off to ICMPv6 module.");
199 icmp6.SendEcho(pecho.to,
200 pecho.opcode,
201 pecho.payload,
202 pecho.psize);
203 }
204
205 /* pass the packet for ICMP handling */
206 else if (pecho.to.isIPv4()) {
207 debugs(42, 2, " Pass " << pecho.to << " off to ICMPv4 module.");
208 icmp4.SendEcho(pecho.to,
209 pecho.opcode,
210 pecho.payload,
211 pecho.psize);
212 } else {
213 debugs(42, DBG_IMPORTANT, "ERROR: IP has unknown Type. " << pecho.to );
214 }
215}
216
217void
219{
220 debugs(42, 2, "return result to squid. len=" << len);
221
222 if (send(socket_to_squid, &preply, len, 0) < 0) {
223 int xerrno = errno;
224 debugs(42, DBG_CRITICAL, "FATAL: send failure: " << xstrerr(xerrno));
225 Close();
226 exit(EXIT_FAILURE);
227 }
228}
229
230#endif /* USE_ICMP */
231
Icmp4 icmp4
pinger helper contains one of these as a global object.
Definition: pinger.cc:91
Icmp6 icmp6
pinger helper contains one of these as a global object.
Definition: pinger.cc:92
#define PINGER_PAYLOAD_SZ
Definition: Icmp.h:16
static void Win32SockCleanup(void)
Definition: WinSvc.cc:981
static char * debugOptions
Definition: Stream.h:80
static void BanCacheLogUse()
Definition: debug.cc:1115
void SendEcho(Ip::Address &, int, const char *, int) override
Definition: Icmp4.cc:83
void SendEcho(Ip::Address &, int, const char *, int) override
Definition: Icmp6.cc:118
~IcmpPinger() override
Definition: IcmpPinger.cc:31
void SendResult(pingerReplyData &preply, int len)
Send ICMP results back to squid.
Definition: IcmpPinger.cc:218
void Recv(void) override
Handle ICMP requests from squid, passing to helpers.
Definition: IcmpPinger.cc:165
int socket_to_squid
Definition: IcmpPinger.h:47
void Close() override
Shutdown pinger helper and control channel.
Definition: IcmpPinger.cc:150
int socket_from_squid
Definition: IcmpPinger.h:46
int Open() override
Start and initiate control channel to squid.
Definition: IcmpPinger.cc:46
Definition: Icmp.h:68
virtual void Close()
Shutdown pinger helper and control channel.
Definition: Icmp.cc:25
int icmp_sock
Definition: Icmp.h:121
bool isIPv4() const
Definition: Address.cc:158
bool isIPv6() const
Definition: Address.cc:164
#define MYNAME
Definition: Stream.h:236
#define DBG_IMPORTANT
Definition: Stream.h:38
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:194
#define DBG_CRITICAL
Definition: Stream.h:37
#define O_BINARY
Definition: defines.h:136
#define xstrdup
int psize
Definition: Icmp.h:30
Ip::Address to
Definition: Icmp.h:28
unsigned char opcode
Definition: Icmp.h:29
char payload[PINGER_PAYLOAD_SZ]
Definition: Icmp.h:31
time_t getCurrentTime() STUB_RETVAL(0) int tvSubUsec(struct timeval
const char * xstrerr(int error)
Definition: xstrerror.cc:83

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors