]> The Tcpdump Group git mirrors - libpcap/blob - rpcapd/rpcapd.c
rpcap: fix sock_open() issues.
[libpcap] / rpcapd / rpcapd.c
1 /*
2 * Copyright (c) 2002 - 2003
3 * NetGroup, Politecnico di Torino (Italy)
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the Politecnico di Torino nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 */
32
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
36
37 #include "ftmacros.h"
38 #include "diag-control.h"
39
40 #include <errno.h> // for the errno variable
41 #include <string.h> // for strtok, etc
42 #include <stdlib.h> // for malloc(), free(), ...
43 #include <stdio.h> // for fprintf(), stderr, FILE etc
44 #include <pcap.h> // for PCAP_ERRBUF_SIZE
45 #include <signal.h> // for signal()
46
47 #include "fmtutils.h"
48 #include "sockutils.h" // for socket calls
49 #include "varattrs.h" // for _U_
50 #include "portability.h"
51 #include "rpcapd.h"
52 #include "config_params.h" // configuration file parameters
53 #include "fileconf.h" // for the configuration file management
54 #include "rpcap-protocol.h"
55 #include "daemon.h" // the true main() method of this daemon
56 #include "log.h"
57
58 #ifdef HAVE_OPENSSL
59 #include "sslutils.h"
60 #endif
61
62 #ifdef _WIN32
63 #include <process.h> // for thread stuff
64 #include "win32-svc.h" // for Win32 service stuff
65 #include "getopt.h" // for getopt()-for-Windows
66 #else
67 #include <fcntl.h> // for open()
68 #include <unistd.h> // for exit()
69 #include <sys/wait.h> // waitpid()
70 #endif
71
72 //
73 // Element in list of sockets on which we're listening for connections.
74 //
75 struct listen_sock {
76 struct listen_sock *next;
77 SOCKET sock;
78 };
79
80 // Global variables
81 char hostlist[MAX_HOST_LIST + 1]; //!< Keeps the list of the hosts that are allowed to connect to this server
82 struct active_pars activelist[MAX_ACTIVE_LIST]; //!< Keeps the list of the hosts (host, port) on which I want to connect to (active mode)
83 int nullAuthAllowed; //!< '1' if we permit NULL authentication, '0' otherwise
84 static struct listen_sock *listen_socks; //!< sockets on which we listen
85 char loadfile[MAX_LINE + 1]; //!< Name of the file from which we have to load the configuration
86 static int passivemode = 1; //!< '1' if we want to run in passive mode as well
87 static struct addrinfo mainhints; //!< temporary struct to keep settings needed to open the new socket
88 static char address[MAX_LINE + 1]; //!< keeps the network address (either numeric or literal) to bind to
89 static char port[MAX_LINE + 1]; //!< keeps the network port to bind to
90 #ifdef _WIN32
91 static HANDLE state_change_event; //!< event to signal that a state change should take place
92 #endif
93 static volatile sig_atomic_t shutdown_server; //!< '1' if the server is to shut down
94 static volatile sig_atomic_t reread_config; //!< '1' if the server is to re-read its configuration
95 static int uses_ssl; //!< '1' to use TLS over the data socket
96
97 extern char *optarg; // for getopt()
98
99 // Function definition
100 #ifdef _WIN32
101 static unsigned __stdcall main_active(void *ptr);
102 static BOOL WINAPI main_ctrl_event(DWORD);
103 #else
104 static void *main_active(void *ptr);
105 static void main_terminate(int sign);
106 static void main_reread_config(int sign);
107 #endif
108 static void accept_connections(void);
109 static void accept_connection(SOCKET listen_sock);
110 #ifndef _WIN32
111 static void main_reap_children(int sign);
112 #endif
113 #ifdef _WIN32
114 static unsigned __stdcall main_passive_serviceloop_thread(void *ptr);
115 #endif
116
117 #define RPCAP_ACTIVE_WAIT 30 /* Waiting time between two attempts to open a connection, in active mode (default: 30 sec) */
118
119 /*!
120 \brief Prints the usage screen if it is launched in console mode.
121 */
122 static void printusage(FILE * f)
123 {
124 const char *usagetext =
125 "USAGE:"
126 " " PROGRAM_NAME " [-b <address>] [-p <port>] [-4] [-l <host_list>] [-a <host,port>]\n"
127 " [-n] [-v] [-d] "
128 #ifndef _WIN32
129 "[-i] "
130 #endif
131 "[-D] [-s <config_file>] [-f <config_file>]\n\n"
132 " -b <address> the address to bind to (either numeric or literal).\n"
133 " Default: binds to all local IPv4 and IPv6 addresses\n\n"
134 " -p <port> the port to bind to.\n"
135 " Default: binds to port " RPCAP_DEFAULT_NETPORT "\n\n"
136 " -4 use only IPv4.\n"
137 " Default: use both IPv4 and IPv6 waiting sockets\n\n"
138 " -l <host_list> a file that contains a list of hosts that are allowed\n"
139 " to connect to this server (if more than one, list them one\n"
140 " per line).\n"
141 " We suggest to use literal names (instead of numeric ones)\n"
142 " in order to avoid problems with different address families.\n\n"
143 " -n permit NULL authentication (usually used with '-l')\n\n"
144 " -a <host,port> run in active mode when connecting to 'host' on port 'port'\n"
145 " In case 'port' is omitted, the default port (" RPCAP_DEFAULT_NETPORT_ACTIVE ") is used\n\n"
146 " -v run in active mode only (default: if '-a' is specified, it\n"
147 " accepts passive connections as well)\n\n"
148 " -d run in daemon mode (UNIX only) or as a service (Win32 only)\n"
149 " Warning (Win32): this switch is provided automatically when\n"
150 " the service is started from the control panel\n\n"
151 #ifndef _WIN32
152 " -i run in inetd mode (UNIX only)\n\n"
153 #endif
154 " -D log debugging messages\n\n"
155 #ifdef HAVE_OPENSSL
156 " -S encrypt all communication with SSL (implements rpcaps://)\n"
157 " -C enable compression\n"
158 " -K <pem_file> uses the SSL private key in this file (default: key.pem)\n"
159 " -X <pem_file> uses the certificate from this file (default: cert.pem)\n"
160 #endif
161 " -s <config_file> save the current configuration to file\n\n"
162 " -f <config_file> load the current configuration from file; all switches\n"
163 " specified from the command line are ignored\n\n"
164 " -h print this help screen\n\n";
165
166 (void)fprintf(f, "RPCAPD, a remote packet capture daemon.\n"
167 "Compiled with %s\n", pcap_lib_version());
168 #if defined(HAVE_OPENSSL) && defined(SSLEAY_VERSION)
169 (void)fprintf(f, "Compiled with %s\n", SSLeay_version(SSLEAY_VERSION));
170 #endif
171 (void)fprintf(f, "\n%s", usagetext);
172 }
173
174
175
176 //! Program main
177 int main(int argc, char *argv[])
178 {
179 char savefile[MAX_LINE + 1]; // name of the file on which we have to save the configuration
180 int log_to_systemlog = 0; // Non-zero if we should log to the "system log" rather than the standard error
181 int isdaemon = 0; // Non-zero if the user wants to run this program as a daemon
182 #ifndef _WIN32
183 int isrunbyinetd = 0; // Non-zero if this is being run by inetd or something inetd-like
184 #endif
185 int log_debug_messages = 0; // Non-zero if the user wants debug messages logged
186 int retval; // keeps the returning value from several functions
187 char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
188 #ifndef _WIN32
189 struct sigaction action;
190 #endif
191 #ifdef HAVE_OPENSSL
192 int enable_compression = 0;
193 #endif
194
195 savefile[0] = 0;
196 loadfile[0] = 0;
197 hostlist[0] = 0;
198
199 // Initialize errbuf
200 memset(errbuf, 0, sizeof(errbuf));
201
202 pcap_strlcpy(address, RPCAP_DEFAULT_NETADDR, sizeof (address));
203 pcap_strlcpy(port, RPCAP_DEFAULT_NETPORT, sizeof (port));
204
205 // Prepare to open a new server socket
206 memset(&mainhints, 0, sizeof(struct addrinfo));
207
208 mainhints.ai_family = PF_UNSPEC;
209 mainhints.ai_flags = AI_PASSIVE; // Ready to a bind() socket
210 mainhints.ai_socktype = SOCK_STREAM;
211
212 // Getting the proper command line options
213 # ifdef HAVE_OPENSSL
214 # define SSL_CLOPTS "SK:X:C"
215 # else
216 # define SSL_CLOPTS ""
217 # endif
218
219 # define CLOPTS "b:dDhip:4l:na:s:f:v" SSL_CLOPTS
220
221 while ((retval = getopt(argc, argv, CLOPTS)) != -1)
222 {
223 switch (retval)
224 {
225 case 'D':
226 log_debug_messages = 1;
227 rpcapd_log_set(log_to_systemlog, log_debug_messages);
228 break;
229 case 'b':
230 pcap_strlcpy(address, optarg, sizeof (address));
231 break;
232 case 'p':
233 pcap_strlcpy(port, optarg, sizeof (port));
234 break;
235 case '4':
236 mainhints.ai_family = PF_INET; // IPv4 server only
237 break;
238 case 'd':
239 isdaemon = 1;
240 log_to_systemlog = 1;
241 rpcapd_log_set(log_to_systemlog, log_debug_messages);
242 break;
243 case 'i':
244 #ifdef _WIN32
245 printusage(stderr);
246 exit(1);
247 #else
248 isrunbyinetd = 1;
249 log_to_systemlog = 1;
250 rpcapd_log_set(log_to_systemlog, log_debug_messages);
251 #endif
252 break;
253 case 'n':
254 nullAuthAllowed = 1;
255 break;
256 case 'v':
257 passivemode = 0;
258 break;
259 case 'l':
260 {
261 pcap_strlcpy(hostlist, optarg, sizeof(hostlist));
262 break;
263 }
264 case 'a':
265 {
266 char *tmpaddress, *tmpport;
267 char *lasts;
268 int i = 0;
269
270 tmpaddress = pcap_strtok_r(optarg, RPCAP_HOSTLIST_SEP, &lasts);
271
272 while ((tmpaddress != NULL) && (i < MAX_ACTIVE_LIST))
273 {
274 tmpport = pcap_strtok_r(NULL, RPCAP_HOSTLIST_SEP, &lasts);
275
276 pcap_strlcpy(activelist[i].address, tmpaddress, sizeof (activelist[i].address));
277
278 if ((tmpport == NULL) || (strcmp(tmpport, "DEFAULT") == 0)) // the user choose a custom port
279 pcap_strlcpy(activelist[i].port, RPCAP_DEFAULT_NETPORT_ACTIVE, sizeof (activelist[i].port));
280 else
281 pcap_strlcpy(activelist[i].port, tmpport, sizeof (activelist[i].port));
282
283 tmpaddress = pcap_strtok_r(NULL, RPCAP_HOSTLIST_SEP, &lasts);
284
285 i++;
286 }
287
288 if (i > MAX_ACTIVE_LIST)
289 rpcapd_log(LOGPRIO_ERROR, "Only MAX_ACTIVE_LIST active connections are currently supported.");
290
291 // I don't initialize the remaining part of the structure, since
292 // it is already zeroed (it is a global var)
293 break;
294 }
295 case 'f':
296 pcap_strlcpy(loadfile, optarg, sizeof (loadfile));
297 break;
298 case 's':
299 pcap_strlcpy(savefile, optarg, sizeof (savefile));
300 break;
301 #ifdef HAVE_OPENSSL
302 case 'S':
303 uses_ssl = 1;
304 break;
305 case 'C':
306 enable_compression = 1;
307 break;
308 case 'K':
309 ssl_set_keyfile(optarg);
310 break;
311 case 'X':
312 ssl_set_certfile(optarg);
313 break;
314 #endif
315 case 'h':
316 printusage(stdout);
317 exit(0);
318 /*NOTREACHED*/
319 default:
320 exit(1);
321 /*NOTREACHED*/
322 }
323 }
324
325 #ifndef _WIN32
326 if (isdaemon && isrunbyinetd)
327 {
328 rpcapd_log(LOGPRIO_ERROR, "rpcapd: -d and -i can't be used together");
329 exit(1);
330 }
331 #endif
332
333 //
334 // We want UTF-8 error messages.
335 //
336 if (pcap_init(PCAP_CHAR_ENC_UTF_8, errbuf) == -1)
337 {
338 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
339 exit(-1);
340 }
341 pcap_fmt_set_encoding(PCAP_CHAR_ENC_UTF_8);
342
343 if (sock_init(errbuf, PCAP_ERRBUF_SIZE) == -1)
344 {
345 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
346 exit(-1);
347 }
348
349 if (savefile[0] && fileconf_save(savefile))
350 rpcapd_log(LOGPRIO_DEBUG, "Error when saving the configuration to file");
351
352 // If the file does not exist, it keeps the settings provided by the command line
353 if (loadfile[0])
354 fileconf_read();
355
356 #ifdef _WIN32
357 //
358 // Create a handle to signal the main loop to tell it to do
359 // something.
360 //
361 state_change_event = CreateEvent(NULL, FALSE, FALSE, NULL);
362 if (state_change_event == NULL)
363 {
364 sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
365 "Can't create state change event");
366 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
367 exit(2);
368 }
369
370 //
371 // Catch control signals.
372 //
373 if (!SetConsoleCtrlHandler(main_ctrl_event, TRUE))
374 {
375 sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
376 "Can't set control handler");
377 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
378 exit(2);
379 }
380 #else
381 memset(&action, 0, sizeof (action));
382 action.sa_handler = main_terminate;
383 action.sa_flags = 0;
384 sigemptyset(&action.sa_mask);
385 sigaction(SIGTERM, &action, NULL);
386 memset(&action, 0, sizeof (action));
387 action.sa_handler = main_reap_children;
388 action.sa_flags = 0;
389 sigemptyset(&action.sa_mask);
390 sigaction(SIGCHLD, &action, NULL);
391 // Ignore SIGPIPE - we'll get EPIPE when trying to write to a closed
392 // connection, we don't want to get killed by a signal in that case
393 signal(SIGPIPE, SIG_IGN);
394 #endif
395
396 # ifdef HAVE_OPENSSL
397 if (uses_ssl) {
398 if (ssl_init_once(1, enable_compression, errbuf, PCAP_ERRBUF_SIZE) < 0)
399 {
400 rpcapd_log(LOGPRIO_ERROR, "Can't initialize SSL: %s",
401 errbuf);
402 exit(2);
403 }
404 }
405 # endif
406
407 #ifndef _WIN32
408 if (isrunbyinetd)
409 {
410 //
411 // -i was specified, indicating that this is being run
412 // by inetd or something that can run network daemons
413 // as if it were inetd (xinetd, launchd, systemd, etc.).
414 //
415 // We assume that the program that launched us just
416 // duplicated a single socket for the connection
417 // to our standard input, output, and error, so we
418 // can just use the standard input as our control
419 // socket.
420 //
421 int sockctrl;
422 int devnull_fd;
423
424 //
425 // Duplicate the standard input as the control socket.
426 //
427 sockctrl = dup(0);
428 if (sockctrl == -1)
429 {
430 sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
431 "Can't dup standard input");
432 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
433 exit(2);
434 }
435
436 //
437 // Try to set the standard input, output, and error
438 // to /dev/null.
439 //
440 devnull_fd = open("/dev/null", O_RDWR);
441 if (devnull_fd != -1)
442 {
443 //
444 // If this fails, just drive on.
445 //
446 (void)dup2(devnull_fd, 0);
447 (void)dup2(devnull_fd, 1);
448 (void)dup2(devnull_fd, 2);
449 close(devnull_fd);
450 }
451
452 //
453 // Handle this client.
454 // This is passive mode, so we don't care whether we were
455 // told by the client to close.
456 //
457 char *hostlist_copy = strdup(hostlist);
458 if (hostlist_copy == NULL)
459 {
460 rpcapd_log(LOGPRIO_ERROR, "Out of memory copying the host/port list");
461 exit(0);
462 }
463 (void)daemon_serviceloop(sockctrl, 0, hostlist_copy,
464 nullAuthAllowed, uses_ssl);
465
466 //
467 // Nothing more to do.
468 //
469 exit(0);
470 }
471 #endif
472
473 if (isdaemon)
474 {
475 //
476 // This is being run as a daemon.
477 // On UN*X, it might be manually run, or run from an
478 // rc file.
479 //
480 #ifndef _WIN32
481 int pid;
482
483 //
484 // Daemonize ourselves.
485 //
486 // Unix Network Programming, pg 336
487 //
488 if ((pid = fork()) != 0)
489 exit(0); // Parent terminates
490
491 // First child continues
492 // Set daemon mode
493 setsid();
494
495 // generated under unix with 'kill -HUP', needed to reload the configuration
496 memset(&action, 0, sizeof (action));
497 action.sa_handler = main_reread_config;
498 action.sa_flags = 0;
499 sigemptyset(&action.sa_mask);
500 sigaction(SIGHUP, &action, NULL);
501
502 if ((pid = fork()) != 0)
503 exit(0); // First child terminates
504
505 // LINUX WARNING: the current linux implementation of pthreads requires a management thread
506 // to handle some hidden stuff. So, as soon as you create the first thread, two threads are
507 // created. Fom this point on, the number of threads active are always one more compared
508 // to the number you're expecting
509
510 // Second child continues
511 // umask(0);
512 // chdir("/");
513 #else
514 //
515 // This is being run as a service on Windows.
516 //
517 // If this call succeeds, it is blocking on Win32
518 //
519 if (!svc_start())
520 rpcapd_log(LOGPRIO_DEBUG, "Unable to start the service");
521
522 // When the previous call returns, the entire application has to be stopped.
523 exit(0);
524 #endif
525 }
526 else // Console mode
527 {
528 #ifndef _WIN32
529 // Enable the catching of Ctrl+C
530 memset(&action, 0, sizeof (action));
531 action.sa_handler = main_terminate;
532 action.sa_flags = 0;
533 sigemptyset(&action.sa_mask);
534 sigaction(SIGINT, &action, NULL);
535
536 // generated under unix with 'kill -HUP', needed to reload the configuration
537 // We do not have this kind of signal in Win32
538 memset(&action, 0, sizeof (action));
539 action.sa_handler = main_reread_config;
540 action.sa_flags = 0;
541 sigemptyset(&action.sa_mask);
542 sigaction(SIGHUP, &action, NULL);
543 #endif
544
545 printf("Press CTRL + C to stop the server...\n");
546 }
547
548 // If we're a Win32 service, we have already called this function in the service_main
549 main_startup();
550
551 // The code should never arrive here (since the main_startup is blocking)
552 // however this avoids a compiler warning
553 exit(0);
554 }
555
556 void main_startup(void)
557 {
558 char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
559 struct addrinfo *addrinfo; // keeps the addrinfo chain; required to open a new socket
560 int i;
561 #ifdef _WIN32
562 HANDLE threadId; // handle for the subthread
563 #else
564 pid_t pid;
565 #endif
566
567 i = 0;
568 addrinfo = NULL;
569 memset(errbuf, 0, sizeof(errbuf));
570
571 // Starts all the active threads
572 while ((i < MAX_ACTIVE_LIST) && (activelist[i].address[0] != 0))
573 {
574 activelist[i].ai_family = mainhints.ai_family;
575
576 #ifdef _WIN32
577 threadId = (HANDLE)_beginthreadex(NULL, 0, main_active,
578 (void *)&activelist[i], 0, NULL);
579 if (threadId == 0)
580 {
581 rpcapd_log(LOGPRIO_DEBUG, "Error creating the active child threads");
582 continue;
583 }
584 CloseHandle(threadId);
585 #else
586 if ((pid = fork()) == 0) // I am the child
587 {
588 main_active((void *) &activelist[i]);
589 exit(0);
590 }
591 #endif
592 i++;
593 }
594
595 /*
596 * The code that manages the active connections is not blocking;
597 * the code that manages the passive connection is blocking.
598 * So, if the user does not want to run in passive mode, we have
599 * to block the main thread here, otherwise the program ends and
600 * all threads are stopped.
601 *
602 * WARNING: this means that in case we have only active mode,
603 * the program does not terminate even if all the child thread
604 * terminates. The user has always to press Ctrl+C (or send a
605 * SIGTERM) to terminate the program.
606 */
607 if (passivemode)
608 {
609 struct addrinfo *tempaddrinfo;
610
611 //
612 // Get a list of sockets on which to listen.
613 //
614 if (sock_initaddress((address[0]) ? address : NULL, port, &mainhints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
615 {
616 rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf);
617 return;
618 }
619
620 for (tempaddrinfo = addrinfo; tempaddrinfo;
621 tempaddrinfo = tempaddrinfo->ai_next)
622 {
623 SOCKET sock;
624 struct listen_sock *sock_info;
625
626 if ((sock = sock_open(NULL, tempaddrinfo, SOCKOPEN_SERVER, SOCKET_MAXCONN, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
627 {
628 switch (tempaddrinfo->ai_family)
629 {
630 case AF_INET:
631 {
632 struct sockaddr_in *in;
633 char addrbuf[INET_ADDRSTRLEN];
634
635 in = (struct sockaddr_in *)tempaddrinfo->ai_addr;
636 rpcapd_log(LOGPRIO_WARNING, "Can't listen on socket for %s:%u: %s",
637 inet_ntop(AF_INET, &in->sin_addr,
638 addrbuf, sizeof (addrbuf)),
639 ntohs(in->sin_port),
640 errbuf);
641 break;
642 }
643
644 case AF_INET6:
645 {
646 struct sockaddr_in6 *in6;
647 char addrbuf[INET6_ADDRSTRLEN];
648
649 in6 = (struct sockaddr_in6 *)tempaddrinfo->ai_addr;
650 rpcapd_log(LOGPRIO_WARNING, "Can't listen on socket for %s:%u: %s",
651 inet_ntop(AF_INET6, &in6->sin6_addr,
652 addrbuf, sizeof (addrbuf)),
653 ntohs(in6->sin6_port),
654 errbuf);
655 break;
656 }
657
658 default:
659 rpcapd_log(LOGPRIO_WARNING, "Can't listen on socket for address family %u: %s",
660 tempaddrinfo->ai_family,
661 errbuf);
662 break;
663 }
664 continue;
665 }
666
667 sock_info = (struct listen_sock *) malloc(sizeof (struct listen_sock));
668 if (sock_info == NULL)
669 {
670 rpcapd_log(LOGPRIO_ERROR, "Can't allocate structure for listen socket");
671 exit(2);
672 }
673 sock_info->sock = sock;
674 sock_info->next = listen_socks;
675 listen_socks = sock_info;
676 }
677
678 freeaddrinfo(addrinfo);
679
680 if (listen_socks == NULL)
681 {
682 rpcapd_log(LOGPRIO_ERROR, "Can't listen on any address");
683 exit(2);
684 }
685
686 //
687 // Now listen on all of them, waiting for connections.
688 //
689 accept_connections();
690 }
691
692 //
693 // We're done; exit.
694 //
695 rpcapd_log(LOGPRIO_DEBUG, PROGRAM_NAME " is closing.\n");
696
697 #ifndef _WIN32
698 //
699 // Sends a KILL signal to all the processes in this process's
700 // process group; i.e., it kills all the child processes
701 // we've created.
702 //
703 // XXX - that also includes us, so we will be killed as well;
704 // that may cause a message to be printed or logged.
705 //
706 kill(0, SIGKILL);
707 #endif
708
709 //
710 // Just leave. We shouldn't need to clean up sockets or
711 // anything else, and if we try to do so, we'll could end
712 // up closing sockets, or shutting Winsock down, out from
713 // under service loops, causing all sorts of noisy error
714 // messages.
715 //
716 // We shouldn't need to worry about cleaning up any resources
717 // such as handles, sockets, threads, etc. - exit() should
718 // terminate the process, causing all those resources to be
719 // cleaned up (including the threads; Microsoft claims in the
720 // ExitProcess() documentation that, if ExitProcess() is called,
721 // "If a thread is waiting on a kernel object, it will not be
722 // terminated until the wait has completed.", but claims in the
723 // _beginthread()/_beginthreadex() documentation that "All threads
724 // are terminated if any thread calls abort, exit, _exit, or
725 // ExitProcess." - the latter appears to be the case, even for
726 // threads waiting on the event for a pcap_t).
727 //
728 exit(0);
729 }
730
731 #ifdef _WIN32
732 static void
733 send_state_change_event(void)
734 {
735 char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
736
737 if (!SetEvent(state_change_event))
738 {
739 sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
740 "SetEvent on shutdown event failed");
741 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
742 }
743 }
744
745 void
746 send_shutdown_notification(void)
747 {
748 //
749 // Indicate that the server should shut down.
750 //
751 shutdown_server = 1;
752
753 //
754 // Send a state change event, to wake up WSAWaitForMultipleEvents().
755 //
756 send_state_change_event();
757 }
758
759 void
760 send_reread_configuration_notification(void)
761 {
762 //
763 // Indicate that the server should re-read its configuration file.
764 //
765 reread_config = 1;
766
767 //
768 // Send a state change event, to wake up WSAWaitForMultipleEvents().
769 //
770 send_state_change_event();
771 }
772
773 static BOOL WINAPI main_ctrl_event(DWORD ctrltype)
774 {
775 //
776 // ctrltype is one of:
777 //
778 // CTRL_C_EVENT - we got a ^C; this is like SIGINT
779 // CTRL_BREAK_EVENT - we got Ctrl+Break
780 // CTRL_CLOSE_EVENT - the console was closed; this is like SIGHUP
781 // CTRL_LOGOFF_EVENT - a user is logging off; this is received
782 // only by services
783 // CTRL_SHUTDOWN_EVENT - the systemis shutting down; this is
784 // received only by services
785 //
786 // For now, we treat all but CTRL_LOGOFF_EVENT as indications
787 // that we should shut down.
788 //
789 switch (ctrltype)
790 {
791 case CTRL_C_EVENT:
792 case CTRL_BREAK_EVENT:
793 case CTRL_CLOSE_EVENT:
794 case CTRL_SHUTDOWN_EVENT:
795 //
796 // Set a shutdown notification.
797 //
798 send_shutdown_notification();
799 break;
800
801 default:
802 break;
803 }
804
805 //
806 // We handled this.
807 //
808 return TRUE;
809 }
810 #else
811 static void main_terminate(int sign _U_)
812 {
813 //
814 // Note that the server should shut down.
815 // select() should get an EINTR error when we return,
816 // so it will wake up and know it needs to check the flag.
817 //
818 shutdown_server = 1;
819 }
820
821 static void main_reread_config(int sign _U_)
822 {
823 //
824 // Note that the server should re-read its configuration file.
825 // select() should get an EINTR error when we return,
826 // so it will wake up and know it needs to check the flag.
827 //
828 reread_config = 1;
829 }
830
831 static void main_reap_children(int sign _U_)
832 {
833 pid_t pid;
834 int exitstat;
835
836 // Reap all child processes that have exited.
837 // For reference, Stevens, pg 128
838
839 while ((pid = waitpid(-1, &exitstat, WNOHANG)) > 0)
840 rpcapd_log(LOGPRIO_DEBUG, "Child terminated");
841
842 return;
843 }
844 #endif
845
846 //
847 // Loop waiting for incoming connections and accepting them.
848 //
849 static void
850 accept_connections(void)
851 {
852 #ifdef _WIN32
853 struct listen_sock *sock_info;
854 DWORD num_events;
855 WSAEVENT *events;
856 int i;
857 char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
858
859 //
860 // How big does the set of events need to be?
861 // One for the shutdown event, plus one for every socket on which
862 // we'll be listening.
863 //
864 num_events = 1; // shutdown event
865 for (sock_info = listen_socks; sock_info;
866 sock_info = sock_info->next)
867 {
868 if (num_events == WSA_MAXIMUM_WAIT_EVENTS)
869 {
870 //
871 // WSAWaitForMultipleEvents() doesn't support
872 // more than WSA_MAXIMUM_WAIT_EVENTS events
873 // on which to wait.
874 //
875 rpcapd_log(LOGPRIO_ERROR, "Too many sockets on which to listen");
876 exit(2);
877 }
878 num_events++;
879 }
880
881 //
882 // Allocate the array of events.
883 //
884 events = (WSAEVENT *) malloc(num_events * sizeof (WSAEVENT));
885 if (events == NULL)
886 {
887 rpcapd_log(LOGPRIO_ERROR, "Can't allocate array of events which to listen");
888 exit(2);
889 }
890
891 //
892 // Fill it in.
893 //
894 events[0] = state_change_event; // state change event first
895 for (sock_info = listen_socks, i = 1; sock_info;
896 sock_info = sock_info->next, i++)
897 {
898 WSAEVENT event;
899
900 //
901 // Create an event that is signaled if there's a connection
902 // to accept on the socket in question.
903 //
904 event = WSACreateEvent();
905 if (event == WSA_INVALID_EVENT)
906 {
907 sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
908 "Can't create socket event");
909 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
910 exit(2);
911 }
912 if (WSAEventSelect(sock_info->sock, event, FD_ACCEPT) == SOCKET_ERROR)
913 {
914 sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
915 "Can't setup socket event");
916 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
917 exit(2);
918 }
919 events[i] = event;
920 }
921
922 for (;;)
923 {
924 //
925 // Wait for incoming connections.
926 //
927 DWORD ret;
928
929 ret = WSAWaitForMultipleEvents(num_events, events, FALSE,
930 WSA_INFINITE, FALSE);
931 if (ret == WSA_WAIT_FAILED)
932 {
933 sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
934 "WSAWaitForMultipleEvents failed");
935 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
936 exit(2);
937 }
938
939 if (ret == WSA_WAIT_EVENT_0)
940 {
941 //
942 // The state change event was set.
943 //
944 if (shutdown_server)
945 {
946 //
947 // Time to quit. Exit the loop.
948 //
949 break;
950 }
951 if (reread_config)
952 {
953 //
954 // We should re-read the configuration
955 // file.
956 //
957 reread_config = 0; // clear the indicator
958 fileconf_read();
959 }
960 }
961
962 //
963 // Check each socket.
964 //
965 for (sock_info = listen_socks, i = 1; sock_info;
966 sock_info = sock_info->next, i++)
967 {
968 WSANETWORKEVENTS network_events;
969
970 if (WSAEnumNetworkEvents(sock_info->sock,
971 events[i], &network_events) == SOCKET_ERROR)
972 {
973 sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
974 "WSAEnumNetworkEvents failed");
975 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
976 exit(2);
977 }
978 if (network_events.lNetworkEvents & FD_ACCEPT)
979 {
980 //
981 // Did an error occur?
982 //
983 if (network_events.iErrorCode[FD_ACCEPT_BIT] != 0)
984 {
985 //
986 // Yes - report it and keep going.
987 //
988 sock_fmterrmsg(errbuf,
989 PCAP_ERRBUF_SIZE,
990 network_events.iErrorCode[FD_ACCEPT_BIT],
991 "Socket error");
992 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
993 continue;
994 }
995
996 //
997 // Accept the connection.
998 //
999 accept_connection(sock_info->sock);
1000 }
1001 }
1002 }
1003 #else
1004 struct listen_sock *sock_info;
1005 int num_sock_fds;
1006
1007 //
1008 // How big does the bitset of sockets on which to select() have
1009 // to be?
1010 //
1011 num_sock_fds = 0;
1012 for (sock_info = listen_socks; sock_info; sock_info = sock_info->next)
1013 {
1014 if (sock_info->sock + 1 > num_sock_fds)
1015 {
1016 if ((unsigned int)(sock_info->sock + 1) >
1017 (unsigned int)FD_SETSIZE)
1018 {
1019 rpcapd_log(LOGPRIO_ERROR, "Socket FD is too bit for an fd_set");
1020 exit(2);
1021 }
1022 num_sock_fds = sock_info->sock + 1;
1023 }
1024 }
1025
1026 for (;;)
1027 {
1028 fd_set sock_fds;
1029 int ret;
1030
1031 //
1032 // Set up an fd_set for all the sockets on which we're
1033 // listening.
1034 //
1035 // This set is modified by select(), so we have to
1036 // construct it anew each time.
1037 //
1038 FD_ZERO(&sock_fds);
1039 for (sock_info = listen_socks; sock_info;
1040 sock_info = sock_info->next)
1041 {
1042 FD_SET(sock_info->sock, &sock_fds);
1043 }
1044
1045 //
1046 // Wait for incoming connections.
1047 //
1048 ret = select(num_sock_fds, &sock_fds, NULL, NULL, NULL);
1049 if (ret == -1)
1050 {
1051 if (errno == EINTR)
1052 {
1053 //
1054 // If this is a "terminate the
1055 // server" signal, exit the loop,
1056 // otherwise just keep trying.
1057 //
1058 if (shutdown_server)
1059 {
1060 //
1061 // Time to quit. Exit the loop.
1062 //
1063 break;
1064 }
1065 if (reread_config)
1066 {
1067 //
1068 // We should re-read the configuration
1069 // file.
1070 //
1071 reread_config = 0; // clear the indicator
1072 fileconf_read();
1073 }
1074
1075 //
1076 // Go back and wait again.
1077 //
1078 continue;
1079 }
1080 else
1081 {
1082 rpcapd_log(LOGPRIO_ERROR, "select failed: %s",
1083 strerror(errno));
1084 exit(2);
1085 }
1086 }
1087
1088 //
1089 // Check each socket.
1090 //
1091 for (sock_info = listen_socks; sock_info;
1092 sock_info = sock_info->next)
1093 {
1094 if (FD_ISSET(sock_info->sock, &sock_fds))
1095 {
1096 //
1097 // Accept the connection.
1098 //
1099 accept_connection(sock_info->sock);
1100 }
1101 }
1102 }
1103 #endif
1104
1105 //
1106 // Close all the listen sockets.
1107 //
1108 for (sock_info = listen_socks; sock_info; sock_info = sock_info->next)
1109 {
1110 closesocket(sock_info->sock);
1111 }
1112 sock_cleanup();
1113 }
1114
1115 #ifdef _WIN32
1116 //
1117 // A structure to hold the parameters to the daemon service loop
1118 // thread on Windows.
1119 //
1120 // (On UN*X, there is no need for this explicit copy since the
1121 // fork "inherits" the parent stack.)
1122 //
1123 struct params_copy {
1124 SOCKET sockctrl;
1125 char *hostlist;
1126 };
1127 #endif
1128
1129 //
1130 // Accept a connection and start a worker thread, on Windows, or a
1131 // worker process, on UN*X, to handle the connection.
1132 //
1133 static void
1134 accept_connection(SOCKET listen_sock)
1135 {
1136 char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
1137 SOCKET sockctrl; // keeps the socket ID for this control connection
1138 struct sockaddr_storage from; // generic sockaddr_storage variable
1139 socklen_t fromlen; // keeps the length of the sockaddr_storage variable
1140
1141 #ifdef _WIN32
1142 HANDLE threadId; // handle for the subthread
1143 u_long off = 0;
1144 struct params_copy *params_copy = NULL;
1145 #else
1146 pid_t pid;
1147 #endif
1148
1149 // Initialize errbuf
1150 memset(errbuf, 0, sizeof(errbuf));
1151
1152 for (;;)
1153 {
1154 // Accept the connection
1155 fromlen = sizeof(struct sockaddr_storage);
1156
1157 sockctrl = accept(listen_sock, (struct sockaddr *) &from, &fromlen);
1158
1159 if (sockctrl != INVALID_SOCKET)
1160 {
1161 // Success.
1162 break;
1163 }
1164
1165 // The accept() call can return this error when a signal is caught
1166 // In this case, we have simply to ignore this error code
1167 // Stevens, pg 124
1168 #ifdef _WIN32
1169 if (WSAGetLastError() == WSAEINTR)
1170 #else
1171 if (errno == EINTR)
1172 #endif
1173 continue;
1174
1175 // Don't check for errors here, since the error can be due to the fact that the thread
1176 // has been killed
1177 sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE, "accept() failed");
1178 rpcapd_log(LOGPRIO_ERROR, "Accept of control connection from client failed: %s",
1179 errbuf);
1180 return;
1181 }
1182
1183 #ifdef _WIN32
1184 //
1185 // Put the socket back into blocking mode; doing WSAEventSelect()
1186 // on the listen socket makes that socket non-blocking, and it
1187 // appears that sockets returned from an accept() on that socket
1188 // are also non-blocking.
1189 //
1190 // First, we have to un-WSAEventSelect() this socket, and then
1191 // we can turn non-blocking mode off.
1192 //
1193 // If this fails, we aren't guaranteed that, for example, any
1194 // of the error message will be sent - if it can't be put in
1195 // the socket queue, the send will just fail.
1196 //
1197 // So we just log the message and close the connection.
1198 //
1199 if (WSAEventSelect(sockctrl, NULL, 0) == SOCKET_ERROR)
1200 {
1201 sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
1202 "WSAEventSelect() failed");
1203 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
1204 sock_close(sockctrl, NULL, 0);
1205 return;
1206 }
1207 if (ioctlsocket(sockctrl, FIONBIO, &off) == SOCKET_ERROR)
1208 {
1209 sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
1210 "ioctlsocket(FIONBIO) failed");
1211 rpcapd_log(LOGPRIO_ERROR, "%s", errbuf);
1212 sock_close(sockctrl, NULL, 0);
1213 return;
1214 }
1215
1216 //
1217 // Make a copy of the host list to pass to the new thread, so that
1218 // if we update it in the main thread, it won't catch us in the
1219 // middle of updating it.
1220 //
1221 // daemon_serviceloop() will free it once it's done with it.
1222 //
1223 char *hostlist_copy = strdup(hostlist);
1224 if (hostlist_copy == NULL)
1225 {
1226 rpcapd_log(LOGPRIO_ERROR, "Out of memory copying the host/port list");
1227 sock_close(sockctrl, NULL, 0);
1228 return;
1229 }
1230
1231 //
1232 // Allocate a location to hold the values of sockctrl.
1233 // It will be freed in the newly-created thread once it's
1234 // finished with it.
1235 //
1236 params_copy = malloc(sizeof(*params_copy));
1237 if (params_copy == NULL)
1238 {
1239 rpcapd_log(LOGPRIO_ERROR, "Out of memory allocating the parameter copy structure");
1240 free(hostlist_copy);
1241 sock_close(sockctrl, NULL, 0);
1242 return;
1243 }
1244 params_copy->sockctrl = sockctrl;
1245 params_copy->hostlist = hostlist_copy;
1246
1247 threadId = (HANDLE)_beginthreadex(NULL, 0,
1248 main_passive_serviceloop_thread, (void *) params_copy, 0, NULL);
1249 if (threadId == 0)
1250 {
1251 rpcapd_log(LOGPRIO_ERROR, "Error creating the child thread");
1252 free(params_copy);
1253 free(hostlist_copy);
1254 sock_close(sockctrl, NULL, 0);
1255 return;
1256 }
1257 CloseHandle(threadId);
1258 #else /* _WIN32 */
1259 pid = fork();
1260 if (pid == -1)
1261 {
1262 rpcapd_log(LOGPRIO_ERROR, "Error creating the child process: %s",
1263 strerror(errno));
1264 sock_close(sockctrl, NULL, 0);
1265 return;
1266 }
1267 if (pid == 0)
1268 {
1269 //
1270 // Child process.
1271 //
1272 // Close the socket on which we're listening (must
1273 // be open only in the parent).
1274 //
1275 closesocket(listen_sock);
1276
1277 #if 0
1278 //
1279 // Modify thread params so that it can be killed at any time
1280 // XXX - is this necessary? This is the main and, currently,
1281 // only thread in the child process, and nobody tries to
1282 // cancel us, although *we* may cancel the thread that's
1283 // handling the capture loop.
1284 //
1285 if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL))
1286 goto end;
1287 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL))
1288 goto end;
1289 #endif
1290
1291 //
1292 // Run the service loop.
1293 // This is passive mode, so we don't care whether we were
1294 // told by the client to close.
1295 //
1296 char *hostlist_copy = strdup(hostlist);
1297 if (hostlist_copy == NULL)
1298 {
1299 rpcapd_log(LOGPRIO_ERROR, "Out of memory copying the host/port list");
1300 exit(0);
1301 }
1302 (void)daemon_serviceloop(sockctrl, 0, hostlist_copy,
1303 nullAuthAllowed, uses_ssl);
1304
1305 exit(0);
1306 }
1307
1308 // I am the parent
1309 // Close the socket for this session (must be open only in the child)
1310 closesocket(sockctrl);
1311 #endif /* _WIN32 */
1312 }
1313
1314 /*!
1315 \brief 'true' main of the program in case the active mode is turned on.
1316
1317 This function loops forever trying to connect to the remote host, until the
1318 daemon is turned down.
1319
1320 \param ptr: it keeps the 'activepars' parameters. It is a 'void *'
1321 just because the thread APIs want this format.
1322 */
1323 #ifdef _WIN32
1324 static unsigned __stdcall
1325 #else
1326 static void *
1327 #endif
1328 main_active(void *ptr)
1329 {
1330 char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
1331 SOCKET sockctrl; // keeps the socket ID for this control connection
1332 struct addrinfo hints; // temporary struct to keep settings needed to open the new socket
1333 struct addrinfo *addrinfo; // keeps the addrinfo chain; required to open a new socket
1334 struct active_pars *activepars;
1335
1336 activepars = (struct active_pars *) ptr;
1337
1338 // Prepare to open a new server socket
1339 memset(&hints, 0, sizeof(struct addrinfo));
1340 // WARNING Currently it supports only ONE socket family among IPv4 and IPv6
1341 hints.ai_family = AF_INET; // PF_UNSPEC to have both IPv4 and IPv6 server
1342 hints.ai_socktype = SOCK_STREAM;
1343 hints.ai_family = activepars->ai_family;
1344
1345 rpcapd_log(LOGPRIO_DEBUG, "Connecting to host %s, port %s, using protocol %s",
1346 activepars->address, activepars->port, (hints.ai_family == AF_INET) ? "IPv4":
1347 (hints.ai_family == AF_INET6) ? "IPv6" : "Unspecified");
1348
1349 // Initialize errbuf
1350 memset(errbuf, 0, sizeof(errbuf));
1351
1352 // Do the work
1353 if (sock_initaddress(activepars->address, activepars->port, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
1354 {
1355 rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf);
1356 return 0;
1357 }
1358
1359 for (;;)
1360 {
1361 int activeclose;
1362
1363 if ((sockctrl = sock_open(activepars->address, addrinfo, SOCKOPEN_CLIENT, 0, errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
1364 {
1365 rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf);
1366
1367 DIAG_OFF_FORMAT_TRUNCATION
1368 snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error connecting to host %s, port %s, using protocol %s",
1369 activepars->address, activepars->port, (hints.ai_family == AF_INET) ? "IPv4":
1370 (hints.ai_family == AF_INET6) ? "IPv6" : "Unspecified");
1371 DIAG_ON_FORMAT_TRUNCATION
1372
1373 rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf);
1374
1375 sleep_secs(RPCAP_ACTIVE_WAIT);
1376
1377 continue;
1378 }
1379
1380 char *hostlist_copy = strdup(hostlist);
1381 if (hostlist_copy == NULL)
1382 {
1383 rpcapd_log(LOGPRIO_ERROR, "Out of memory copying the host/port list");
1384 activeclose = 0;
1385 sock_close(sockctrl, NULL, 0);
1386 }
1387 else
1388 {
1389 //
1390 // daemon_serviceloop() will free the copy.
1391 //
1392 activeclose = daemon_serviceloop(sockctrl, 1,
1393 hostlist_copy, nullAuthAllowed, uses_ssl);
1394 }
1395
1396 // If the connection is closed by the user explicitly, don't try to connect to it again
1397 // just exit the program
1398 if (activeclose == 1)
1399 break;
1400 }
1401
1402 freeaddrinfo(addrinfo);
1403 return 0;
1404 }
1405
1406 #ifdef _WIN32
1407 //
1408 // Main routine of a passive-mode service thread.
1409 //
1410 unsigned __stdcall main_passive_serviceloop_thread(void *ptr)
1411 {
1412 struct params_copy params = *(struct params_copy *)ptr;
1413 free(ptr);
1414
1415 //
1416 // Handle this client.
1417 // This is passive mode, so we don't care whether we were
1418 // told by the client to close.
1419 //
1420 (void)daemon_serviceloop(params.sockctrl, 0, params.hostlist,
1421 nullAuthAllowed, uses_ssl);
1422
1423 return 0;
1424 }
1425 #endif