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