2 * Copyright (c) 2002 - 2003
3 * NetGroup, Politecnico di Torino (Italy)
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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.
36 #include "diag-control.h"
38 #include <errno.h> // for the errno variable
39 #include <string.h> // for strtok, etc
40 #include <stdlib.h> // for malloc(), free(), ...
41 #include <stdio.h> // for fprintf(), stderr, FILE etc
42 #include <pcap.h> // for PCAP_ERRBUF_SIZE
43 #include <signal.h> // for signal()
46 #include "sockutils.h" // for socket calls
47 #include "varattrs.h" // for _U_
48 #include "portability.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
61 #include <process.h> // for thread stuff
62 #include "win32-svc.h" // for Win32 service stuff
63 #include "getopt.h" // for getopt()-for-Windows
65 #include <fcntl.h> // for open()
66 #include <unistd.h> // for exit()
67 #include <sys/wait.h> // waitpid()
71 // Element in list of sockets on which we're listening for connections.
74 struct listen_sock
*next
;
79 char hostlist
[MAX_HOST_LIST
+ 1]; //!< Keeps the list of the hosts that are allowed to connect to this server
80 struct active_pars activelist
[MAX_ACTIVE_LIST
]; //!< Keeps the list of the hosts (host, port) on which I want to connect to (active mode)
81 int nullAuthAllowed
; //!< '1' if we permit NULL authentication, '0' otherwise
82 static struct listen_sock
*listen_socks
; //!< sockets on which we listen
83 char loadfile
[MAX_LINE
+ 1]; //!< Name of the file from which we have to load the configuration
84 static int passivemode
= 1; //!< '1' if we want to run in passive mode as well
85 static struct addrinfo mainhints
; //!< temporary struct to keep settings needed to open the new socket
86 static char address
[MAX_LINE
+ 1]; //!< keeps the network address (either numeric or literal) to bind to
87 static char port
[MAX_LINE
+ 1]; //!< keeps the network port to bind to
88 static char data_port
[MAX_LINE
+ 1]; //!< keeps the network port to use to transfer data
90 static HANDLE state_change_event
; //!< event to signal that a state change should take place
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 TCP
96 extern char *optarg
; // for getopt()
98 // Function definition
100 static unsigned __stdcall
main_active(void *ptr
);
101 static BOOL WINAPI
main_ctrl_event(DWORD
);
103 static void *main_active(void *ptr
);
104 static void main_terminate(int sign
);
105 static void main_reread_config(int sign
);
107 static void accept_connections(void);
108 static void accept_connection(PCAP_SOCKET listen_sock
);
110 static void main_reap_children(int sign
);
113 static unsigned __stdcall
main_passive_serviceloop_thread(void *ptr
);
116 #define RPCAP_ACTIVE_WAIT 30 /* Waiting time between two attempts to open a connection, in active mode (default: 30 sec) */
119 \brief Prints the usage screen if it is launched in console mode.
121 static void printusage(FILE * f
)
123 const char *usagetext
=
125 " " PROGRAM_NAME
" [-b <address>] [-p <port>] [-t <data_port>] [-4] [-l <host_list>]\n"
126 " [-a <host,port>] [-n] [-v] [-d] "
130 "[-D] [-s <config_file>]\n"
132 " [-S] [-C] [-K <ssl_keyfile>] [-X <ssl_certfile>]\n"
134 " [-f <config_file>]\n\n"
135 " -b <address> the address to bind to (either numeric or literal).\n"
136 " Default: binds to all local IPv4 and IPv6 addresses\n\n"
137 " -p <port> the port to bind to.\n"
138 " Default: binds to port " RPCAP_DEFAULT_NETPORT
"\n\n"
139 " -t <data_port>: the port to use to transfer data.\n"
140 " Default: an unused port is chosen by the operating system\n\n"
141 " -4 use only IPv4.\n"
142 " Default: use both IPv4 and IPv6 waiting sockets\n\n"
143 " -l <host_list> a file that contains a list of hosts that are allowed\n"
144 " to connect to this server (if more than one, list them one\n"
146 " We suggest to use literal names (instead of numeric ones)\n"
147 " in order to avoid problems with different address families.\n\n"
148 " -n permit NULL authentication (usually used with '-l')\n\n"
149 " -a <host,port> run in active mode when connecting to 'host' on port 'port'\n"
150 " In case 'port' is omitted, the default port (" RPCAP_DEFAULT_NETPORT_ACTIVE
") is used\n\n"
151 " -v run in active mode only (default: if '-a' is specified, it\n"
152 " accepts passive connections as well)\n\n"
153 " -d run in daemon mode (UNIX only) or as a service (Win32 only)\n"
154 " Warning (Win32): this switch is provided automatically when\n"
155 " the service is started from the control panel\n\n"
157 " -i run in inetd mode (UNIX only)\n\n"
159 " -D log debugging messages\n\n"
161 " -S encrypt all communication with SSL (implements rpcaps://)\n"
162 " -C enable compression\n"
163 " -K <ssl_keyfile> use the SSL private key in this file (default: key.pem)\n"
164 " -X <ssl_certfile> use the certificate from this file (default: cert.pem)\n"
166 " -s <config_file> save the current configuration to file\n\n"
167 " -f <config_file> load the current configuration from file; all switches\n"
168 " specified from the command line are ignored\n\n"
169 " -h print this help screen\n\n";
171 (void)fprintf(f
, "RPCAPD, a remote packet capture daemon.\n"
172 "Compiled with %s\n", pcap_lib_version());
173 #if defined(HAVE_OPENSSL) && defined(SSLEAY_VERSION)
174 (void)fprintf(f
, "Compiled with %s\n", SSLeay_version(SSLEAY_VERSION
));
176 (void)fprintf(f
, "\n%s", usagetext
);
182 int main(int argc
, char *argv
[])
184 char savefile
[MAX_LINE
+ 1]; // name of the file on which we have to save the configuration
185 int log_to_systemlog
= 0; // Non-zero if we should log to the "system log" rather than the standard error
186 int isdaemon
= 0; // Non-zero if the user wants to run this program as a daemon
188 int isrunbyinetd
= 0; // Non-zero if this is being run by inetd or something inetd-like
190 int log_debug_messages
= 0; // Non-zero if the user wants debug messages logged
191 int retval
; // keeps the returning value from several functions
192 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
194 struct sigaction action
;
197 int enable_compression
= 0;
205 memset(errbuf
, 0, sizeof(errbuf
));
207 pcapint_strlcpy(address
, RPCAP_DEFAULT_NETADDR
, sizeof (address
));
208 pcapint_strlcpy(port
, RPCAP_DEFAULT_NETPORT
, sizeof (port
));
210 // Prepare to open a new server socket
211 memset(&mainhints
, 0, sizeof(struct addrinfo
));
213 mainhints
.ai_family
= PF_UNSPEC
;
214 mainhints
.ai_flags
= AI_PASSIVE
; // Ready to a bind() socket
215 mainhints
.ai_socktype
= SOCK_STREAM
;
217 // Getting the proper command line options
219 # define SSL_CLOPTS "SK:X:C"
221 # define SSL_CLOPTS ""
224 # define CLOPTS "b:dDhip:4l:na:s:f:t:v" SSL_CLOPTS
226 while ((retval
= getopt(argc
, argv
, CLOPTS
)) != -1)
231 log_debug_messages
= 1;
232 rpcapd_log_set(log_to_systemlog
, log_debug_messages
);
235 pcapint_strlcpy(address
, optarg
, sizeof (address
));
238 pcapint_strlcpy(port
, optarg
, sizeof (port
));
241 pcapint_strlcpy(data_port
, optarg
, sizeof (data_port
));
244 mainhints
.ai_family
= PF_INET
; // IPv4 server only
248 log_to_systemlog
= 1;
249 rpcapd_log_set(log_to_systemlog
, log_debug_messages
);
257 log_to_systemlog
= 1;
258 rpcapd_log_set(log_to_systemlog
, log_debug_messages
);
269 pcapint_strlcpy(hostlist
, optarg
, sizeof(hostlist
));
274 char *tmpaddress
, *tmpport
;
278 tmpaddress
= pcapint_strtok_r(optarg
, RPCAP_HOSTLIST_SEP
, &lasts
);
280 while ((tmpaddress
!= NULL
) && (i
< MAX_ACTIVE_LIST
))
282 tmpport
= pcapint_strtok_r(NULL
, RPCAP_HOSTLIST_SEP
, &lasts
);
284 pcapint_strlcpy(activelist
[i
].address
, tmpaddress
, sizeof (activelist
[i
].address
));
286 if ((tmpport
== NULL
) || (strcmp(tmpport
, "DEFAULT") == 0)) // the user choose a custom port
287 pcapint_strlcpy(activelist
[i
].port
, RPCAP_DEFAULT_NETPORT_ACTIVE
, sizeof (activelist
[i
].port
));
289 pcapint_strlcpy(activelist
[i
].port
, tmpport
, sizeof (activelist
[i
].port
));
291 tmpaddress
= pcapint_strtok_r(NULL
, RPCAP_HOSTLIST_SEP
, &lasts
);
296 if (i
> MAX_ACTIVE_LIST
)
297 rpcapd_log(LOGPRIO_ERROR
, "Only MAX_ACTIVE_LIST active connections are currently supported.");
299 // I don't initialize the remaining part of the structure, since
300 // it is already zeroed (it is a global var)
304 pcapint_strlcpy(loadfile
, optarg
, sizeof (loadfile
));
307 pcapint_strlcpy(savefile
, optarg
, sizeof (savefile
));
314 enable_compression
= 1;
317 ssl_set_keyfile(optarg
);
320 ssl_set_certfile(optarg
);
334 if (isdaemon
&& isrunbyinetd
)
336 rpcapd_log(LOGPRIO_ERROR
, "rpcapd: -d and -i can't be used together");
342 // We want UTF-8 error messages.
344 if (pcap_init(PCAP_CHAR_ENC_UTF_8
, errbuf
) == -1)
346 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
349 pcapint_fmt_set_encoding(PCAP_CHAR_ENC_UTF_8
);
351 if (sock_init(errbuf
, PCAP_ERRBUF_SIZE
) == -1)
353 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
357 if (savefile
[0] && fileconf_save(savefile
))
358 rpcapd_log(LOGPRIO_DEBUG
, "Error when saving the configuration to file");
360 // If the file does not exist, it keeps the settings provided by the command line
366 // Create a handle to signal the main loop to tell it to do
369 state_change_event
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
370 if (state_change_event
== NULL
)
372 sock_geterrmsg(errbuf
, PCAP_ERRBUF_SIZE
,
373 "Can't create state change event");
374 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
379 // Catch control signals.
381 if (!SetConsoleCtrlHandler(main_ctrl_event
, TRUE
))
383 sock_geterrmsg(errbuf
, PCAP_ERRBUF_SIZE
,
384 "Can't set control handler");
385 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
389 memset(&action
, 0, sizeof (action
));
390 action
.sa_handler
= main_terminate
;
392 sigemptyset(&action
.sa_mask
);
393 sigaction(SIGTERM
, &action
, NULL
);
394 memset(&action
, 0, sizeof (action
));
395 action
.sa_handler
= main_reap_children
;
397 sigemptyset(&action
.sa_mask
);
398 sigaction(SIGCHLD
, &action
, NULL
);
399 // Ignore SIGPIPE - we'll get EPIPE when trying to write to a closed
400 // connection, we don't want to get killed by a signal in that case
402 DIAG_OFF_STRICT_PROTOTYPES
403 #endif /* __illumos__ */
404 signal(SIGPIPE
, SIG_IGN
);
406 DIAG_ON_STRICT_PROTOTYPES
407 #endif /* __illumos__ */
412 if (ssl_init_once(1, enable_compression
, errbuf
, PCAP_ERRBUF_SIZE
) < 0)
414 rpcapd_log(LOGPRIO_ERROR
, "Can't initialize SSL: %s",
425 // -i was specified, indicating that this is being run
426 // by inetd or something that can run network daemons
427 // as if it were inetd (xinetd, launchd, systemd, etc.).
429 // We assume that the program that launched us just
430 // duplicated a single socket for the connection
431 // to our standard input, output, and error, so we
432 // can just use the standard input as our control
439 // Duplicate the standard input as the control socket.
444 sock_geterrmsg(errbuf
, PCAP_ERRBUF_SIZE
,
445 "Can't dup standard input");
446 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
451 // Try to set the standard input, output, and error
454 devnull_fd
= open("/dev/null", O_RDWR
);
455 if (devnull_fd
!= -1)
458 // If this fails, just drive on.
460 (void)dup2(devnull_fd
, 0);
461 (void)dup2(devnull_fd
, 1);
462 (void)dup2(devnull_fd
, 2);
467 // Handle this client.
468 // This is passive mode, so we don't care whether we were
469 // told by the client to close.
471 char *hostlist_copy
= strdup(hostlist
);
472 if (hostlist_copy
== NULL
)
474 rpcapd_log(LOGPRIO_ERROR
, "Out of memory copying the host/port list");
477 (void)daemon_serviceloop(sockctrl
, 0, hostlist_copy
,
478 nullAuthAllowed
, data_port
, uses_ssl
);
481 // Nothing more to do.
490 // This is being run as a daemon.
491 // On UN*X, it might be manually run, or run from an
498 // Daemonize ourselves.
500 // Unix Network Programming, pg 336
502 if ((pid
= fork()) != 0)
503 exit(0); // Parent terminates
505 // First child continues
509 // generated under unix with 'kill -HUP', needed to reload the configuration
510 memset(&action
, 0, sizeof (action
));
511 action
.sa_handler
= main_reread_config
;
513 sigemptyset(&action
.sa_mask
);
514 sigaction(SIGHUP
, &action
, NULL
);
516 if ((pid
= fork()) != 0)
517 exit(0); // First child terminates
519 // LINUX WARNING: the current linux implementation of pthreads requires a management thread
520 // to handle some hidden stuff. So, as soon as you create the first thread, two threads are
521 // created. From this point on, the number of threads active are always one more compared
522 // to the number you're expecting
524 // Second child continues
529 // This is being run as a service on Windows.
531 // If this call succeeds, it is blocking on Win32
534 rpcapd_log(LOGPRIO_DEBUG
, "Unable to start the service");
536 // When the previous call returns, the entire application has to be stopped.
543 // Enable the catching of Ctrl+C
544 memset(&action
, 0, sizeof (action
));
545 action
.sa_handler
= main_terminate
;
547 sigemptyset(&action
.sa_mask
);
548 sigaction(SIGINT
, &action
, NULL
);
550 // generated under unix with 'kill -HUP', needed to reload the configuration
551 // We do not have this kind of signal in Win32
552 memset(&action
, 0, sizeof (action
));
553 action
.sa_handler
= main_reread_config
;
555 sigemptyset(&action
.sa_mask
);
556 sigaction(SIGHUP
, &action
, NULL
);
559 printf("Press CTRL + C to stop the server...\n");
562 // If we're a Win32 service, we have already called this function in the service_main
565 // The code should never arrive here (since the main_startup is blocking)
566 // however this avoids a compiler warning
570 void main_startup(void)
572 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
573 struct addrinfo
*addrinfo
; // keeps the addrinfo chain; required to open a new socket
576 HANDLE threadId
; // handle for the subthread
583 memset(errbuf
, 0, sizeof(errbuf
));
585 // Starts all the active threads
586 while ((i
< MAX_ACTIVE_LIST
) && (activelist
[i
].address
[0] != 0))
588 activelist
[i
].ai_family
= mainhints
.ai_family
;
591 threadId
= (HANDLE
)_beginthreadex(NULL
, 0, main_active
,
592 (void *)&activelist
[i
], 0, NULL
);
595 rpcapd_log(LOGPRIO_DEBUG
, "Error creating the active child threads");
598 CloseHandle(threadId
);
600 if ((pid
= fork()) == 0) // I am the child
602 main_active((void *) &activelist
[i
]);
610 * The code that manages the active connections is not blocking;
611 * the code that manages the passive connection is blocking.
612 * So, if the user does not want to run in passive mode, we have
613 * to block the main thread here, otherwise the program ends and
614 * all threads are stopped.
616 * WARNING: this means that in case we have only active mode,
617 * the program does not terminate even if all the child thread
618 * terminates. The user has always to press Ctrl+C (or send a
619 * SIGTERM) to terminate the program.
623 struct addrinfo
*tempaddrinfo
;
626 // Get a list of sockets on which to listen.
628 addrinfo
= sock_initaddress((address
[0]) ? address
: NULL
,
629 port
, &mainhints
, errbuf
, PCAP_ERRBUF_SIZE
);
630 if (addrinfo
== NULL
)
632 rpcapd_log(LOGPRIO_DEBUG
, "%s", errbuf
);
636 for (tempaddrinfo
= addrinfo
; tempaddrinfo
;
637 tempaddrinfo
= tempaddrinfo
->ai_next
)
640 struct listen_sock
*sock_info
;
642 if ((sock
= sock_open(NULL
, tempaddrinfo
, SOCKOPEN_SERVER
, SOCKET_MAXCONN
, errbuf
, PCAP_ERRBUF_SIZE
)) == INVALID_SOCKET
)
644 switch (tempaddrinfo
->ai_family
)
648 struct sockaddr_in
*in
;
649 char addrbuf
[INET_ADDRSTRLEN
];
651 in
= (struct sockaddr_in
*)tempaddrinfo
->ai_addr
;
652 rpcapd_log(LOGPRIO_WARNING
, "Can't listen on socket for %s:%u: %s",
653 inet_ntop(AF_INET
, &in
->sin_addr
,
654 addrbuf
, sizeof (addrbuf
)),
662 struct sockaddr_in6
*in6
;
663 char addrbuf
[INET6_ADDRSTRLEN
];
665 in6
= (struct sockaddr_in6
*)tempaddrinfo
->ai_addr
;
666 rpcapd_log(LOGPRIO_WARNING
, "Can't listen on socket for %s:%u: %s",
667 inet_ntop(AF_INET6
, &in6
->sin6_addr
,
668 addrbuf
, sizeof (addrbuf
)),
669 ntohs(in6
->sin6_port
),
675 rpcapd_log(LOGPRIO_WARNING
, "Can't listen on socket for address family %u: %s",
676 tempaddrinfo
->ai_family
,
683 sock_info
= (struct listen_sock
*) malloc(sizeof (struct listen_sock
));
684 if (sock_info
== NULL
)
686 rpcapd_log(LOGPRIO_ERROR
, "Can't allocate structure for listen socket");
689 sock_info
->sock
= sock
;
690 sock_info
->next
= listen_socks
;
691 listen_socks
= sock_info
;
694 freeaddrinfo(addrinfo
);
696 if (listen_socks
== NULL
)
698 rpcapd_log(LOGPRIO_ERROR
, "Can't listen on any address");
703 // Now listen on all of them, waiting for connections.
705 accept_connections();
711 rpcapd_log(LOGPRIO_DEBUG
, PROGRAM_NAME
" is closing.\n");
715 // Sends a KILL signal to all the processes in this process's
716 // process group; i.e., it kills all the child processes
719 // XXX - that also includes us, so we will be killed as well;
720 // that may cause a message to be printed or logged.
726 // Just leave. We shouldn't need to clean up sockets or
727 // anything else, and if we try to do so, we'll could end
728 // up closing sockets, or shutting Winsock down, out from
729 // under service loops, causing all sorts of noisy error
732 // We shouldn't need to worry about cleaning up any resources
733 // such as handles, sockets, threads, etc. - exit() should
734 // terminate the process, causing all those resources to be
735 // cleaned up (including the threads; Microsoft claims in the
736 // ExitProcess() documentation that, if ExitProcess() is called,
737 // "If a thread is waiting on a kernel object, it will not be
738 // terminated until the wait has completed.", but claims in the
739 // _beginthread()/_beginthreadex() documentation that "All threads
740 // are terminated if any thread calls abort, exit, _exit, or
741 // ExitProcess." - the latter appears to be the case, even for
742 // threads waiting on the event for a pcap_t).
749 send_state_change_event(void)
751 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
753 if (!SetEvent(state_change_event
))
755 sock_geterrmsg(errbuf
, PCAP_ERRBUF_SIZE
,
756 "SetEvent on shutdown event failed");
757 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
762 send_shutdown_notification(void)
765 // Indicate that the server should shut down.
770 // Send a state change event, to wake up WSAWaitForMultipleEvents().
772 send_state_change_event();
776 send_reread_configuration_notification(void)
779 // Indicate that the server should re-read its configuration file.
784 // Send a state change event, to wake up WSAWaitForMultipleEvents().
786 send_state_change_event();
789 static BOOL WINAPI
main_ctrl_event(DWORD ctrltype
)
792 // ctrltype is one of:
794 // CTRL_C_EVENT - we got a ^C; this is like SIGINT
795 // CTRL_BREAK_EVENT - we got Ctrl+Break
796 // CTRL_CLOSE_EVENT - the console was closed; this is like SIGHUP
797 // CTRL_LOGOFF_EVENT - a user is logging off; this is received
799 // CTRL_SHUTDOWN_EVENT - the system is shutting down; this is
800 // received only by services
802 // For now, we treat all but CTRL_LOGOFF_EVENT as indications
803 // that we should shut down.
808 case CTRL_BREAK_EVENT
:
809 case CTRL_CLOSE_EVENT
:
810 case CTRL_SHUTDOWN_EVENT
:
812 // Set a shutdown notification.
814 send_shutdown_notification();
827 static void main_terminate(int sign _U_
)
830 // Note that the server should shut down.
831 // select() should get an EINTR error when we return,
832 // so it will wake up and know it needs to check the flag.
837 static void main_reread_config(int sign _U_
)
840 // Note that the server should re-read its configuration file.
841 // select() should get an EINTR error when we return,
842 // so it will wake up and know it needs to check the flag.
847 static void main_reap_children(int sign _U_
)
852 // Reap all child processes that have exited.
853 // For reference, Stevens, pg 128
855 while ((pid
= waitpid(-1, &exitstat
, WNOHANG
)) > 0)
856 rpcapd_log(LOGPRIO_DEBUG
, "Child terminated");
863 // Loop waiting for incoming connections and accepting them.
866 accept_connections(void)
869 struct listen_sock
*sock_info
;
873 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
876 // How big does the set of events need to be?
877 // One for the shutdown event, plus one for every socket on which
878 // we'll be listening.
880 num_events
= 1; // shutdown event
881 for (sock_info
= listen_socks
; sock_info
;
882 sock_info
= sock_info
->next
)
884 if (num_events
== WSA_MAXIMUM_WAIT_EVENTS
)
887 // WSAWaitForMultipleEvents() doesn't support
888 // more than WSA_MAXIMUM_WAIT_EVENTS events
891 rpcapd_log(LOGPRIO_ERROR
, "Too many sockets on which to listen");
898 // Allocate the array of events.
900 events
= (WSAEVENT
*) malloc(num_events
* sizeof (WSAEVENT
));
903 rpcapd_log(LOGPRIO_ERROR
, "Can't allocate array of events which to listen");
910 events
[0] = state_change_event
; // state change event first
911 for (sock_info
= listen_socks
, i
= 1; sock_info
;
912 sock_info
= sock_info
->next
, i
++)
917 // Create an event that is signaled if there's a connection
918 // to accept on the socket in question.
920 event
= WSACreateEvent();
921 if (event
== WSA_INVALID_EVENT
)
923 sock_geterrmsg(errbuf
, PCAP_ERRBUF_SIZE
,
924 "Can't create socket event");
925 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
928 if (WSAEventSelect(sock_info
->sock
, event
, FD_ACCEPT
) == SOCKET_ERROR
)
930 sock_geterrmsg(errbuf
, PCAP_ERRBUF_SIZE
,
931 "Can't setup socket event");
932 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
941 // Wait for incoming connections.
945 ret
= WSAWaitForMultipleEvents(num_events
, events
, FALSE
,
946 WSA_INFINITE
, FALSE
);
947 if (ret
== WSA_WAIT_FAILED
)
949 sock_geterrmsg(errbuf
, PCAP_ERRBUF_SIZE
,
950 "WSAWaitForMultipleEvents failed");
951 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
955 if (ret
== WSA_WAIT_EVENT_0
)
958 // The state change event was set.
963 // Time to quit. Exit the loop.
970 // We should re-read the configuration
973 reread_config
= 0; // clear the indicator
979 // Check each socket.
981 for (sock_info
= listen_socks
, i
= 1; sock_info
;
982 sock_info
= sock_info
->next
, i
++)
984 WSANETWORKEVENTS network_events
;
986 if (WSAEnumNetworkEvents(sock_info
->sock
,
987 events
[i
], &network_events
) == SOCKET_ERROR
)
989 sock_geterrmsg(errbuf
, PCAP_ERRBUF_SIZE
,
990 "WSAEnumNetworkEvents failed");
991 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
994 if (network_events
.lNetworkEvents
& FD_ACCEPT
)
997 // Did an error occur?
999 if (network_events
.iErrorCode
[FD_ACCEPT_BIT
] != 0)
1002 // Yes - report it and keep going.
1004 sock_fmterrmsg(errbuf
,
1006 network_events
.iErrorCode
[FD_ACCEPT_BIT
],
1008 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
1013 // Accept the connection.
1015 accept_connection(sock_info
->sock
);
1020 struct listen_sock
*sock_info
;
1024 // How big does the bitset of sockets on which to select() have
1028 for (sock_info
= listen_socks
; sock_info
; sock_info
= sock_info
->next
)
1030 if (sock_info
->sock
+ 1 > num_sock_fds
)
1032 if ((unsigned int)(sock_info
->sock
+ 1) >
1033 (unsigned int)FD_SETSIZE
)
1035 rpcapd_log(LOGPRIO_ERROR
, "Socket FD is too bit for an fd_set");
1038 num_sock_fds
= sock_info
->sock
+ 1;
1048 // Set up an fd_set for all the sockets on which we're
1051 // This set is modified by select(), so we have to
1052 // construct it anew each time.
1055 for (sock_info
= listen_socks
; sock_info
;
1056 sock_info
= sock_info
->next
)
1058 FD_SET(sock_info
->sock
, &sock_fds
);
1062 // Wait for incoming connections.
1064 ret
= select(num_sock_fds
, &sock_fds
, NULL
, NULL
, NULL
);
1070 // If this is a "terminate the
1071 // server" signal, exit the loop,
1072 // otherwise just keep trying.
1074 if (shutdown_server
)
1077 // Time to quit. Exit the loop.
1084 // We should re-read the configuration
1087 reread_config
= 0; // clear the indicator
1092 // Go back and wait again.
1098 rpcapd_log(LOGPRIO_ERROR
, "select failed: %s",
1105 // Check each socket.
1107 for (sock_info
= listen_socks
; sock_info
;
1108 sock_info
= sock_info
->next
)
1110 if (FD_ISSET(sock_info
->sock
, &sock_fds
))
1113 // Accept the connection.
1115 accept_connection(sock_info
->sock
);
1122 // Close all the listen sockets.
1124 for (sock_info
= listen_socks
; sock_info
; sock_info
= sock_info
->next
)
1126 closesocket(sock_info
->sock
);
1133 // A structure to hold the parameters to the daemon service loop
1134 // thread on Windows.
1136 // (On UN*X, there is no need for this explicit copy since the
1137 // fork "inherits" the parent stack.)
1139 struct params_copy
{
1140 PCAP_SOCKET sockctrl
;
1146 // Accept a connection and start a worker thread, on Windows, or a
1147 // worker process, on UN*X, to handle the connection.
1150 accept_connection(PCAP_SOCKET listen_sock
)
1152 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
1153 PCAP_SOCKET sockctrl
; // keeps the socket ID for this control connection
1154 struct sockaddr_storage from
; // generic sockaddr_storage variable
1155 socklen_t fromlen
; // keeps the length of the sockaddr_storage variable
1158 HANDLE threadId
; // handle for the subthread
1160 struct params_copy
*params_copy
= NULL
;
1165 // Initialize errbuf
1166 memset(errbuf
, 0, sizeof(errbuf
));
1170 // Accept the connection
1171 fromlen
= sizeof(struct sockaddr_storage
);
1173 sockctrl
= accept(listen_sock
, (struct sockaddr
*) &from
, &fromlen
);
1175 if (sockctrl
!= INVALID_SOCKET
)
1181 // The accept() call can return this error when a signal is caught
1182 // In this case, we have simply to ignore this error code
1185 if (WSAGetLastError() == WSAEINTR
)
1191 // Don't check for errors here, since the error can be due to the fact that the thread
1193 sock_geterrmsg(errbuf
, PCAP_ERRBUF_SIZE
, "accept() failed");
1194 rpcapd_log(LOGPRIO_ERROR
, "Accept of control connection from client failed: %s",
1201 // Put the socket back into blocking mode; doing WSAEventSelect()
1202 // on the listen socket makes that socket non-blocking, and it
1203 // appears that sockets returned from an accept() on that socket
1204 // are also non-blocking.
1206 // First, we have to un-WSAEventSelect() this socket, and then
1207 // we can turn non-blocking mode off.
1209 // If this fails, we aren't guaranteed that, for example, any
1210 // of the error message will be sent - if it can't be put in
1211 // the socket queue, the send will just fail.
1213 // So we just log the message and close the connection.
1215 if (WSAEventSelect(sockctrl
, NULL
, 0) == SOCKET_ERROR
)
1217 sock_geterrmsg(errbuf
, PCAP_ERRBUF_SIZE
,
1218 "WSAEventSelect() failed");
1219 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
1220 sock_close(sockctrl
, NULL
, 0);
1223 if (ioctlsocket(sockctrl
, FIONBIO
, &off
) == SOCKET_ERROR
)
1225 sock_geterrmsg(errbuf
, PCAP_ERRBUF_SIZE
,
1226 "ioctlsocket(FIONBIO) failed");
1227 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
1228 sock_close(sockctrl
, NULL
, 0);
1233 // Make a copy of the host list to pass to the new thread, so that
1234 // if we update it in the main thread, it won't catch us in the
1235 // middle of updating it.
1237 // daemon_serviceloop() will free it once it's done with it.
1239 char *hostlist_copy
= strdup(hostlist
);
1240 if (hostlist_copy
== NULL
)
1242 rpcapd_log(LOGPRIO_ERROR
, "Out of memory copying the host/port list");
1243 sock_close(sockctrl
, NULL
, 0);
1248 // Allocate a location to hold the values of sockctrl.
1249 // It will be freed in the newly-created thread once it's
1250 // finished with it.
1252 params_copy
= malloc(sizeof(*params_copy
));
1253 if (params_copy
== NULL
)
1255 rpcapd_log(LOGPRIO_ERROR
, "Out of memory allocating the parameter copy structure");
1256 free(hostlist_copy
);
1257 sock_close(sockctrl
, NULL
, 0);
1260 params_copy
->sockctrl
= sockctrl
;
1261 params_copy
->hostlist
= hostlist_copy
;
1263 threadId
= (HANDLE
)_beginthreadex(NULL
, 0,
1264 main_passive_serviceloop_thread
, (void *) params_copy
, 0, NULL
);
1267 rpcapd_log(LOGPRIO_ERROR
, "Error creating the child thread");
1269 free(hostlist_copy
);
1270 sock_close(sockctrl
, NULL
, 0);
1273 CloseHandle(threadId
);
1278 rpcapd_log(LOGPRIO_ERROR
, "Error creating the child process: %s",
1280 sock_close(sockctrl
, NULL
, 0);
1288 // Close the socket on which we're listening (must
1289 // be open only in the parent).
1291 closesocket(listen_sock
);
1295 // Modify thread params so that it can be killed at any time
1296 // XXX - is this necessary? This is the main and, currently,
1297 // only thread in the child process, and nobody tries to
1298 // cancel us, although *we* may cancel the thread that's
1299 // handling the capture loop.
1301 if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE
, NULL
))
1303 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS
, NULL
))
1308 // Run the service loop.
1309 // This is passive mode, so we don't care whether we were
1310 // told by the client to close.
1312 char *hostlist_copy
= strdup(hostlist
);
1313 if (hostlist_copy
== NULL
)
1315 rpcapd_log(LOGPRIO_ERROR
, "Out of memory copying the host/port list");
1318 (void)daemon_serviceloop(sockctrl
, 0, hostlist_copy
,
1319 nullAuthAllowed
, data_port
, uses_ssl
);
1325 // Close the socket for this session (must be open only in the child)
1326 closesocket(sockctrl
);
1331 \brief 'true' main of the program in case the active mode is turned on.
1333 This function loops forever trying to connect to the remote host, until the
1334 daemon is turned down.
1336 \param ptr: it keeps the 'activepars' parameters. It is a 'void *'
1337 just because the thread APIs want this format.
1340 static unsigned __stdcall
1344 main_active(void *ptr
)
1346 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
1347 PCAP_SOCKET sockctrl
; // keeps the socket ID for this control connection
1348 struct addrinfo hints
; // temporary struct to keep settings needed to open the new socket
1349 struct addrinfo
*addrinfo
; // keeps the addrinfo chain; required to open a new socket
1350 struct active_pars
*activepars
;
1352 activepars
= (struct active_pars
*) ptr
;
1354 // Prepare to open a new server socket
1355 memset(&hints
, 0, sizeof(struct addrinfo
));
1356 // WARNING Currently it supports only ONE socket family among IPv4 and IPv6
1357 hints
.ai_family
= AF_INET
; // PF_UNSPEC to have both IPv4 and IPv6 server
1358 hints
.ai_socktype
= SOCK_STREAM
;
1359 hints
.ai_family
= activepars
->ai_family
;
1361 rpcapd_log(LOGPRIO_DEBUG
, "Connecting to host %s, port %s, using protocol %s",
1362 activepars
->address
, activepars
->port
, (hints
.ai_family
== AF_INET
) ? "IPv4":
1363 (hints
.ai_family
== AF_INET6
) ? "IPv6" : "Unspecified");
1365 // Initialize errbuf
1366 memset(errbuf
, 0, sizeof(errbuf
));
1369 addrinfo
= sock_initaddress(activepars
->address
, activepars
->port
,
1370 &hints
, errbuf
, PCAP_ERRBUF_SIZE
);
1371 if (addrinfo
== NULL
)
1373 rpcapd_log(LOGPRIO_DEBUG
, "%s", errbuf
);
1381 if ((sockctrl
= sock_open(activepars
->address
, addrinfo
, SOCKOPEN_CLIENT
, 0, errbuf
, PCAP_ERRBUF_SIZE
)) == INVALID_SOCKET
)
1383 rpcapd_log(LOGPRIO_DEBUG
, "%s", errbuf
);
1385 DIAG_OFF_FORMAT_TRUNCATION
1386 snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Error connecting to host %s, port %s, using protocol %s",
1387 activepars
->address
, activepars
->port
, (hints
.ai_family
== AF_INET
) ? "IPv4":
1388 (hints
.ai_family
== AF_INET6
) ? "IPv6" : "Unspecified");
1389 DIAG_ON_FORMAT_TRUNCATION
1391 rpcapd_log(LOGPRIO_DEBUG
, "%s", errbuf
);
1393 sleep_secs(RPCAP_ACTIVE_WAIT
);
1398 char *hostlist_copy
= strdup(hostlist
);
1399 if (hostlist_copy
== NULL
)
1401 rpcapd_log(LOGPRIO_ERROR
, "Out of memory copying the host/port list");
1403 sock_close(sockctrl
, NULL
, 0);
1408 // daemon_serviceloop() will free the copy.
1410 activeclose
= daemon_serviceloop(sockctrl
, 1,
1411 hostlist_copy
, nullAuthAllowed
, data_port
,
1415 // If the connection is closed by the user explicitly, don't try to connect to it again
1416 // just exit the program
1417 if (activeclose
== 1)
1421 freeaddrinfo(addrinfo
);
1427 // Main routine of a passive-mode service thread.
1429 unsigned __stdcall
main_passive_serviceloop_thread(void *ptr
)
1431 struct params_copy params
= *(struct params_copy
*)ptr
;
1435 // Handle this client.
1436 // This is passive mode, so we don't care whether we were
1437 // told by the client to close.
1439 (void)daemon_serviceloop(params
.sockctrl
, 0, params
.hostlist
,
1440 nullAuthAllowed
, data_port
, uses_ssl
);