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