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