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

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors