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.
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()
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
89 static HANDLE state_change_event
; //!< event to signal that a state change should take place
91 static volatile sig_atomic_t shutdown_server
; //!< '1' if the server is to shut down
92 static volatile sig_atomic_t reread_config
; //!< '1' if the server is to re-read its configuration
93 static int uses_ssl
; //!< '1' to use TLS over the data socket
95 extern char *optarg
; // for getopt()
97 // Function definition
99 static unsigned __stdcall
main_active(void *ptr
);
100 static BOOL WINAPI
main_ctrl_event(DWORD
);
102 static void *main_active(void *ptr
);
103 static void main_terminate(int sign
);
104 static void main_reread_config(int sign
);
106 static void accept_connections(void);
107 static void accept_connection(SOCKET listen_sock
);
109 static void main_reap_children(int sign
);
112 static unsigned __stdcall
main_passive_serviceloop_thread(void *ptr
);
115 #define RPCAP_ACTIVE_WAIT 30 /* Waiting time between two attempts to open a connection, in active mode (default: 30 sec) */
118 \brief Prints the usage screen if it is launched in console mode.
120 static void printusage(void)
122 const char *usagetext
=
124 " " PROGRAM_NAME
" [-b <address>] [-p <port>] [-4] [-l <host_list>] [-a <host,port>]\n"
129 "[-s <config_file>] [-f <config_file>]\n\n"
130 " -b <address> the address to bind to (either numeric or literal).\n"
131 " Default: binds to all local IPv4 and IPv6 addresses\n\n"
132 " -p <port> the port to bind to.\n"
133 " Default: binds to port " RPCAP_DEFAULT_NETPORT
"\n\n"
134 " -4 use only IPv4.\n"
135 " Default: use both IPv4 and IPv6 waiting sockets\n\n"
136 " -l <host_list> a file that contains a list of hosts that are allowed\n"
137 " to connect to this server (if more than one, list them one\n"
139 " We suggest to use literal names (instead of numeric ones)\n"
140 " in order to avoid problems with different address families.\n\n"
141 " -n permit NULL authentication (usually used with '-l')\n\n"
142 " -a <host,port> run in active mode when connecting to 'host' on port 'port'\n"
143 " In case 'port' is omitted, the default port (" RPCAP_DEFAULT_NETPORT_ACTIVE
") is used\n\n"
144 " -v run in active mode only (default: if '-a' is specified, it\n"
145 " accepts passive connections as well)\n\n"
146 " -d run in daemon mode (UNIX only) or as a service (Win32 only)\n"
147 " Warning (Win32): this switch is provided automatically when\n"
148 " the service is started from the control panel\n\n"
150 " -i run in inetd mode (UNIX only)\n\n"
153 " -S encrypt all communication with SSL (implements rpcaps://)\n"
154 " -C enable compression\n"
155 " -K <pem_file> uses the SSL private key in this file (default: key.pem)\n"
156 " -X <pem_file> uses the certificate from this file (default: cert.pem)\n"
158 " -s <config_file> save the current configuration to file\n\n"
159 " -f <config_file> load the current configuration from file; all switches\n"
160 " specified from the command line are ignored\n\n"
161 " -h print this help screen\n\n";
163 (void)fprintf(stderr
, "RPCAPD, a remote packet capture daemon.\n"
164 "Compiled with %s\n\n", pcap_lib_version());
165 printf("%s", usagetext
);
171 int main(int argc
, char *argv
[])
173 char savefile
[MAX_LINE
+ 1]; // name of the file on which we have to save the configuration
174 int log_to_systemlog
= 1; // Non-zero if we should log to the "system log" rather than the standard error
175 int isdaemon
= 0; // Non-zero if the user wants to run this program as a daemon
177 int isrunbyinetd
= 0; // Non-zero if this is being run by inetd or something inetd-like
179 int log_debug_messages
= 0; // Non-zero if the user wants debug messages logged
180 int retval
; // keeps the returning value from several functions
181 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
183 struct sigaction action
;
186 int enable_compression
= 0;
194 memset(errbuf
, 0, sizeof(errbuf
));
196 strncpy(address
, RPCAP_DEFAULT_NETADDR
, MAX_LINE
);
197 strncpy(port
, RPCAP_DEFAULT_NETPORT
, MAX_LINE
);
199 // Prepare to open a new server socket
200 memset(&mainhints
, 0, sizeof(struct addrinfo
));
202 mainhints
.ai_family
= PF_UNSPEC
;
203 mainhints
.ai_flags
= AI_PASSIVE
; // Ready to a bind() socket
204 mainhints
.ai_socktype
= SOCK_STREAM
;
206 // Getting the proper command line options
208 # define SSL_CLOPTS "SK:X:C"
210 # define SSL_CLOPTS ""
213 # define CLOPTS "b:dDhip:4l:na:s:f:v" SSL_CLOPTS
215 while ((retval
= getopt(argc
, argv
, CLOPTS
)) != -1)
220 log_debug_messages
= 1;
221 rpcapd_log_set(log_to_systemlog
, log_debug_messages
);
224 strncpy(address
, optarg
, MAX_LINE
);
227 strncpy(port
, optarg
, MAX_LINE
);
230 mainhints
.ai_family
= PF_INET
; // IPv4 server only
234 log_to_systemlog
= 1;
235 rpcapd_log_set(log_to_systemlog
, log_debug_messages
);
243 log_to_systemlog
= 1;
244 rpcapd_log_set(log_to_systemlog
, log_debug_messages
);
255 strncpy(hostlist
, optarg
, sizeof(hostlist
));
260 char *tmpaddress
, *tmpport
;
264 tmpaddress
= pcap_strtok_r(optarg
, RPCAP_HOSTLIST_SEP
, &lasts
);
266 while ((tmpaddress
!= NULL
) && (i
< MAX_ACTIVE_LIST
))
268 tmpport
= pcap_strtok_r(NULL
, RPCAP_HOSTLIST_SEP
, &lasts
);
270 pcap_strlcpy(activelist
[i
].address
, tmpaddress
, MAX_LINE
);
272 if ((tmpport
== NULL
) || (strcmp(tmpport
, "DEFAULT") == 0)) // the user choose a custom port
273 pcap_strlcpy(activelist
[i
].port
, RPCAP_DEFAULT_NETPORT_ACTIVE
, MAX_LINE
);
275 pcap_strlcpy(activelist
[i
].port
, tmpport
, MAX_LINE
);
277 tmpaddress
= pcap_strtok_r(NULL
, RPCAP_HOSTLIST_SEP
, &lasts
);
282 if (i
> MAX_ACTIVE_LIST
)
283 rpcapd_log(LOGPRIO_ERROR
, "Only MAX_ACTIVE_LIST active connections are currently supported.");
285 // I don't initialize the remaining part of the structure, since
286 // it is already zeroed (it is a global var)
290 pcap_strlcpy(loadfile
, optarg
, MAX_LINE
);
293 pcap_strlcpy(savefile
, optarg
, MAX_LINE
);
300 enable_compression
= 1;
303 snprintf(ssl_keyfile
, sizeof ssl_keyfile
, "%s", optarg
);
306 snprintf(ssl_certfile
, sizeof ssl_certfile
, "%s", optarg
);
320 if (isdaemon
&& isrunbyinetd
)
322 rpcapd_log(LOGPRIO_ERROR
, "rpcapd: -d and -i can't be used together");
327 if (sock_init(errbuf
, PCAP_ERRBUF_SIZE
) == -1)
329 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
333 if (savefile
[0] && fileconf_save(savefile
))
334 rpcapd_log(LOGPRIO_DEBUG
, "Error when saving the configuration to file");
336 // If the file does not exist, it keeps the settings provided by the command line
342 // Create a handle to signal the main loop to tell it to do
345 state_change_event
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
346 if (state_change_event
== NULL
)
348 sock_geterror(NULL
, errbuf
, PCAP_ERRBUF_SIZE
);
349 rpcapd_log(LOGPRIO_ERROR
, "Can't create state change event: %s",
355 // Catch control signals.
357 if (!SetConsoleCtrlHandler(main_ctrl_event
, TRUE
))
359 sock_geterror(NULL
, errbuf
, PCAP_ERRBUF_SIZE
);
360 rpcapd_log(LOGPRIO_ERROR
, "Can't set control handler: %s",
365 memset(&action
, 0, sizeof (action
));
366 action
.sa_handler
= main_terminate
;
368 sigemptyset(&action
.sa_mask
);
369 sigaction(SIGTERM
, &action
, NULL
);
370 memset(&action
, 0, sizeof (action
));
371 action
.sa_handler
= main_reap_children
;
373 sigemptyset(&action
.sa_mask
);
374 sigaction(SIGCHLD
, &action
, NULL
);
375 // Ignore SIGPIPE - we'll get EPIPE when trying to write to a closed
376 // connection, we don't want to get killed by a signal in that case
377 signal(SIGPIPE
, SIG_IGN
);
382 if (ssl_init_once(1, enable_compression
, errbuf
, PCAP_ERRBUF_SIZE
) < 0)
384 rpcapd_log(LOGPRIO_ERROR
, "Can't initialize SSL: %s",
395 // -i was specified, indicating that this is being run
396 // by inetd or something that can run network daemons
397 // as if it were inetd (xinetd, launchd, systemd, etc.).
399 // Our standard input is the input side of a connection,
400 // and our standard output is the output side of a
403 int sockctrl_in
, sockctrl_out
;
407 // Duplicate the standard input and output, making them
408 // the input and output side of the control connection.
410 sockctrl_in
= dup(0);
411 if (sockctrl_in
== -1)
413 sock_geterror(NULL
, errbuf
, PCAP_ERRBUF_SIZE
);
414 rpcapd_log(LOGPRIO_ERROR
, "Can't dup standard input: %s",
418 sockctrl_out
= dup(1);
419 if (sockctrl_out
== -1)
421 sock_geterror(NULL
, errbuf
, PCAP_ERRBUF_SIZE
);
422 rpcapd_log(LOGPRIO_ERROR
, "Can't dup standard output: %s",
428 // Try to set the standard input and output to /dev/null.
430 devnull_fd
= open("/dev/null", O_RDWR
);
431 if (devnull_fd
!= -1)
434 // If this fails, just drive on.
436 (void)dup2(devnull_fd
, 0);
437 (void)dup2(devnull_fd
, 1);
445 ssl
= ssl_promotion_rw(1, sockctrl_in
, sockctrl_out
, errbuf
, PCAP_ERRBUF_SIZE
);
448 rpcapd_log(LOGPRIO_ERROR
, "TLS handshake on control connection failed: %s",
455 // Handle this client.
456 // This is passive mode, so we don't care whether we were
457 // told by the client to close.
459 (void)daemon_serviceloop(sockctrl_in
, sockctrl_out
, ssl
, 0,
460 nullAuthAllowed
, uses_ssl
);
463 // Nothing more to do.
472 // This is being run as a daemon.
473 // On UN*X, it might be manually run, or run from an
480 // Daemonize ourselves.
482 // Unix Network Programming, pg 336
484 if ((pid
= fork()) != 0)
485 exit(0); // Parent terminates
487 // First child continues
491 // generated under unix with 'kill -HUP', needed to reload the configuration
492 memset(&action
, 0, sizeof (action
));
493 action
.sa_handler
= main_reread_config
;
495 sigemptyset(&action
.sa_mask
);
496 sigaction(SIGHUP
, &action
, NULL
);
498 if ((pid
= fork()) != 0)
499 exit(0); // First child terminates
501 // LINUX WARNING: the current linux implementation of pthreads requires a management thread
502 // to handle some hidden stuff. So, as soon as you create the first thread, two threads are
503 // created. Fom this point on, the number of threads active are always one more compared
504 // to the number you're expecting
506 // Second child continues
511 // This is being run as a service on Windows.
513 // If this call succeeds, it is blocking on Win32
515 if (svc_start() != 1)
516 rpcapd_log(LOGPRIO_DEBUG
, "Unable to start the service");
518 // When the previous call returns, the entire application has to be stopped.
525 // Enable the catching of Ctrl+C
526 memset(&action
, 0, sizeof (action
));
527 action
.sa_handler
= main_terminate
;
529 sigemptyset(&action
.sa_mask
);
530 sigaction(SIGINT
, &action
, NULL
);
532 // generated under unix with 'kill -HUP', needed to reload the configuration
533 // We do not have this kind of signal in Win32
534 memset(&action
, 0, sizeof (action
));
535 action
.sa_handler
= main_reread_config
;
537 sigemptyset(&action
.sa_mask
);
538 sigaction(SIGHUP
, &action
, NULL
);
541 printf("Press CTRL + C to stop the server...\n");
544 // If we're a Win32 service, we have already called this function in the service_main
547 // The code should never arrive here (since the main_startup is blocking)
548 // however this avoids a compiler warning
552 void main_startup(void)
554 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
555 struct addrinfo
*addrinfo
; // keeps the addrinfo chain; required to open a new socket
558 HANDLE threadId
; // handle for the subthread
565 memset(errbuf
, 0, sizeof(errbuf
));
567 // Starts all the active threads
568 while ((i
< MAX_ACTIVE_LIST
) && (activelist
[i
].address
[0] != 0))
570 activelist
[i
].ai_family
= mainhints
.ai_family
;
573 threadId
= (HANDLE
)_beginthreadex(NULL
, 0, main_active
,
574 (void *)&activelist
[i
], 0, NULL
);
577 rpcapd_log(LOGPRIO_DEBUG
, "Error creating the active child threads");
580 CloseHandle(threadId
);
582 if ((pid
= fork()) == 0) // I am the child
584 main_active((void *) &activelist
[i
]);
592 * The code that manages the active connections is not blocking;
593 * the code that manages the passive connection is blocking.
594 * So, if the user does not want to run in passive mode, we have
595 * to block the main thread here, otherwise the program ends and
596 * all threads are stopped.
598 * WARNING: this means that in case we have only active mode,
599 * the program does not terminate even if all the child thread
600 * terminates. The user has always to press Ctrl+C (or send a
601 * SIGTERM) to terminate the program.
605 struct addrinfo
*tempaddrinfo
;
608 // Get a list of sockets on which to listen.
610 if (sock_initaddress((address
[0]) ? address
: NULL
, port
, &mainhints
, &addrinfo
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
612 rpcapd_log(LOGPRIO_DEBUG
, "%s", errbuf
);
616 for (tempaddrinfo
= addrinfo
; tempaddrinfo
;
617 tempaddrinfo
= tempaddrinfo
->ai_next
)
620 struct listen_sock
*sock_info
;
622 if ((sock
= sock_open(tempaddrinfo
, SOCKOPEN_SERVER
, SOCKET_MAXCONN
, errbuf
, PCAP_ERRBUF_SIZE
)) == INVALID_SOCKET
)
624 switch (tempaddrinfo
->ai_family
)
628 struct sockaddr_in
*in
;
629 char addrbuf
[INET_ADDRSTRLEN
];
631 in
= (struct sockaddr_in
*)tempaddrinfo
->ai_addr
;
632 rpcapd_log(LOGPRIO_WARNING
, "Can't listen on socket for %s:%u: %s",
633 inet_ntop(AF_INET
, &in
->sin_addr
,
634 addrbuf
, sizeof (addrbuf
)),
642 struct sockaddr_in6
*in6
;
643 char addrbuf
[INET6_ADDRSTRLEN
];
645 in6
= (struct sockaddr_in6
*)tempaddrinfo
->ai_addr
;
646 rpcapd_log(LOGPRIO_WARNING
, "Can't listen on socket for %s:%u: %s",
647 inet_ntop(AF_INET6
, &in6
->sin6_addr
,
648 addrbuf
, sizeof (addrbuf
)),
649 ntohs(in6
->sin6_port
),
655 rpcapd_log(LOGPRIO_WARNING
, "Can't listen on socket for address family %u: %s",
656 tempaddrinfo
->ai_family
,
663 sock_info
= (struct listen_sock
*) malloc(sizeof (struct listen_sock
));
664 if (sock_info
== NULL
)
666 rpcapd_log(LOGPRIO_ERROR
, "Can't allocate structure for listen socket");
669 sock_info
->sock
= sock
;
670 sock_info
->next
= listen_socks
;
671 listen_socks
= sock_info
;
674 freeaddrinfo(addrinfo
);
676 if (listen_socks
== NULL
)
678 rpcapd_log(LOGPRIO_ERROR
, "Can't listen on any address");
683 // Now listen on all of them, waiting for connections.
685 accept_connections();
691 rpcapd_log(LOGPRIO_DEBUG
, PROGRAM_NAME
" is closing.\n");
695 // Sends a KILL signal to all the processes in this process's
696 // process group; i.e., it kills all the child processes
699 // XXX - that also includes us, so we will be killed as well;
700 // that may cause a message to be printed or logged.
706 // Just leave. We shouldn't need to clean up sockets or
707 // anything else, and if we try to do so, we'll could end
708 // up closing sockets, or shutting Winsock down, out from
709 // under service loops, causing all sorts of noisy error
712 // We shouldn't need to worry about cleaning up any resources
713 // such as handles, sockets, threads, etc. - exit() should
714 // terminate the process, causing all those resources to be
715 // cleaned up (including the threads; Microsoft claims in the
716 // ExitProcess() documentation that, if ExitProcess() is called,
717 // "If a thread is waiting on a kernel object, it will not be
718 // terminated until the wait has completed.", but claims in the
719 // _beginthread()/_beginthreadex() documentation that "All threads
720 // are terminated if any thread calls abort, exit, _exit, or
721 // ExitProcess." - the latter appears to be the case, even for
722 // threads waiting on the event for a pcap_t).
729 send_state_change_event(void)
731 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
733 if (!SetEvent(state_change_event
))
735 sock_geterror(NULL
, errbuf
, PCAP_ERRBUF_SIZE
);
736 rpcapd_log(LOGPRIO_ERROR
, "SetEvent on shutdown event failed: %s", errbuf
);
741 send_shutdown_notification(void)
744 // Indicate that the server should shut down.
749 // Send a state change event, to wake up WSAWaitForMultipleEvents().
751 send_state_change_event();
755 send_reread_configuration_notification(void)
758 // Indicate that the server should re-read its configuration file.
763 // Send a state change event, to wake up WSAWaitForMultipleEvents().
765 send_state_change_event();
768 static BOOL WINAPI
main_ctrl_event(DWORD ctrltype
)
771 // ctrltype is one of:
773 // CTRL_C_EVENT - we got a ^C; this is like SIGINT
774 // CTRL_BREAK_EVENT - we got Ctrl+Break
775 // CTRL_CLOSE_EVENT - the console was closed; this is like SIGHUP
776 // CTRL_LOGOFF_EVENT - a user is logging off; this is received
778 // CTRL_SHUTDOWN_EVENT - the systemis shutting down; this is
779 // received only by services
781 // For now, we treat all but CTRL_LOGOFF_EVENT as indications
782 // that we should shut down.
787 case CTRL_BREAK_EVENT
:
788 case CTRL_CLOSE_EVENT
:
789 case CTRL_SHUTDOWN_EVENT
:
791 // Set a shutdown notification.
793 send_shutdown_notification();
806 static void main_terminate(int sign _U_
)
809 // Note that the server should shut down.
810 // select() should get an EINTR error when we return,
811 // so it will wake up and know it needs to check the flag.
816 static void main_reread_config(int sign _U_
)
819 // Note that the server should re-read its configuration file.
820 // select() should get an EINTR error when we return,
821 // so it will wake up and know it needs to check the flag.
826 static void main_reap_children(int sign _U_
)
831 // Reap all child processes that have exited.
832 // For reference, Stevens, pg 128
834 while ((pid
= waitpid(-1, &exitstat
, WNOHANG
)) > 0)
835 rpcapd_log(LOGPRIO_DEBUG
, "Child terminated");
842 // Loop waiting for incoming connections and accepting them.
845 accept_connections(void)
848 struct listen_sock
*sock_info
;
852 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
855 // How big does the set of events need to be?
856 // One for the shutdown event, plus one for every socket on which
857 // we'll be listening.
859 num_events
= 1; // shutdown event
860 for (sock_info
= listen_socks
; sock_info
;
861 sock_info
= sock_info
->next
)
863 if (num_events
== WSA_MAXIMUM_WAIT_EVENTS
)
866 // WSAWaitForMultipleEvents() doesn't support
867 // more than WSA_MAXIMUM_WAIT_EVENTS events
870 rpcapd_log(LOGPRIO_ERROR
, "Too many sockets on which to listen");
877 // Allocate the array of events.
879 events
= (WSAEVENT
*) malloc(num_events
* sizeof (WSAEVENT
));
882 rpcapd_log(LOGPRIO_ERROR
, "Can't allocate array of events which to listen");
889 events
[0] = state_change_event
; // state change event first
890 for (sock_info
= listen_socks
, i
= 1; sock_info
;
891 sock_info
= sock_info
->next
, i
++)
896 // Create an event that is signaled if there's a connection
897 // to accept on the socket in question.
899 event
= WSACreateEvent();
900 if (event
== WSA_INVALID_EVENT
)
902 sock_geterror(NULL
, errbuf
, PCAP_ERRBUF_SIZE
);
903 rpcapd_log(LOGPRIO_ERROR
, "Can't create socket event: %s", errbuf
);
906 if (WSAEventSelect(sock_info
->sock
, event
, FD_ACCEPT
) == SOCKET_ERROR
)
908 sock_geterror(NULL
, errbuf
, PCAP_ERRBUF_SIZE
);
909 rpcapd_log(LOGPRIO_ERROR
, "Can't setup socket event: %s", errbuf
);
918 // Wait for incoming connections.
922 ret
= WSAWaitForMultipleEvents(num_events
, events
, FALSE
,
923 WSA_INFINITE
, FALSE
);
924 if (ret
== WSA_WAIT_FAILED
)
926 sock_geterror(NULL
, errbuf
, PCAP_ERRBUF_SIZE
);
927 rpcapd_log(LOGPRIO_ERROR
, "WSAWaitForMultipleEvents failed: %s", errbuf
);
931 if (ret
== WSA_WAIT_EVENT_0
)
934 // The state change event was set.
939 // Time to quit. Exit the loop.
946 // We should re-read the configuration
949 reread_config
= 0; // clear the indicator
955 // Check each socket.
957 for (sock_info
= listen_socks
, i
= 1; sock_info
;
958 sock_info
= sock_info
->next
, i
++)
960 WSANETWORKEVENTS network_events
;
962 if (WSAEnumNetworkEvents(sock_info
->sock
,
963 events
[i
], &network_events
) == SOCKET_ERROR
)
965 sock_geterror(NULL
, errbuf
, PCAP_ERRBUF_SIZE
);
966 rpcapd_log(LOGPRIO_ERROR
, "WSAEnumNetworkEvents failed: %s", errbuf
);
969 if (network_events
.lNetworkEvents
& FD_ACCEPT
)
972 // Did an error occur?
974 if (network_events
.iErrorCode
[FD_ACCEPT_BIT
] != 0)
977 // Yes - report it and keep going.
980 network_events
.iErrorCode
[FD_ACCEPT_BIT
],
983 rpcapd_log(LOGPRIO_ERROR
, "Socket error: %s", errbuf
);
988 // Accept the connection.
990 accept_connection(sock_info
->sock
);
995 struct listen_sock
*sock_info
;
999 // How big does the bitset of sockets on which to select() have
1003 for (sock_info
= listen_socks
; sock_info
; sock_info
= sock_info
->next
)
1005 if (sock_info
->sock
+ 1 > num_sock_fds
)
1007 if ((unsigned int)(sock_info
->sock
+ 1) >
1008 (unsigned int)FD_SETSIZE
)
1010 rpcapd_log(LOGPRIO_ERROR
, "Socket FD is too bit for an fd_set");
1013 num_sock_fds
= sock_info
->sock
+ 1;
1023 // Set up an fd_set for all the sockets on which we're
1026 // This set is modified by select(), so we have to
1027 // construct it anew each time.
1030 for (sock_info
= listen_socks
; sock_info
;
1031 sock_info
= sock_info
->next
)
1033 FD_SET(sock_info
->sock
, &sock_fds
);
1037 // Wait for incoming connections.
1039 ret
= select(num_sock_fds
, &sock_fds
, NULL
, NULL
, NULL
);
1045 // If this is a "terminate the
1046 // server" signal, exit the loop,
1047 // otherwise just keep trying.
1049 if (shutdown_server
)
1052 // Time to quit. Exit the loop.
1059 // We should re-read the configuration
1062 reread_config
= 0; // clear the indicator
1067 // Go back and wait again.
1073 rpcapd_log(LOGPRIO_ERROR
, "select failed: %s",
1080 // Check each socket.
1082 for (sock_info
= listen_socks
; sock_info
;
1083 sock_info
= sock_info
->next
)
1085 if (FD_ISSET(sock_info
->sock
, &sock_fds
))
1088 // Accept the connection.
1090 accept_connection(sock_info
->sock
);
1097 // Close all the listen sockets.
1099 for (sock_info
= listen_socks
; sock_info
; sock_info
= sock_info
->next
)
1101 closesocket(sock_info
->sock
);
1108 // A structure to hold the parameter to the windows thread
1109 // (on unix there is no need for this explicit copy since the
1110 // fork "inherits" the parent stack)
1114 # ifdef HAVE_OPENSSL
1123 // Accept a connection and start a worker thread, on Windows, or a
1124 // worker process, on UN*X, to handle the connection.
1127 accept_connection(SOCKET listen_sock
)
1129 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
1130 SOCKET sockctrl
; // keeps the socket ID for this control connection
1131 struct sockaddr_storage from
; // generic sockaddr_storage variable
1132 socklen_t fromlen
; // keeps the length of the sockaddr_storage variable
1137 HANDLE threadId
; // handle for the subthread
1139 struct sock_copy
*sock_copy
= NULL
;
1144 // Initialize errbuf
1145 memset(errbuf
, 0, sizeof(errbuf
));
1149 // Accept the connection
1150 fromlen
= sizeof(struct sockaddr_storage
);
1152 sockctrl
= accept(listen_sock
, (struct sockaddr
*) &from
, &fromlen
);
1154 if (sockctrl
!= INVALID_SOCKET
)
1160 // The accept() call can return this error when a signal is catched
1161 // In this case, we have simply to ignore this error code
1164 if (WSAGetLastError() == WSAEINTR
)
1170 // Don't check for errors here, since the error can be due to the fact that the thread
1172 sock_geterror("accept(): ", errbuf
, PCAP_ERRBUF_SIZE
);
1173 rpcapd_log(LOGPRIO_ERROR
, "Accept of control connection from client failed: %s",
1179 /* We have to upgrade to TLS as soon as possible so that the whole protocol
1180 * goes through the encrypted tunnel, including early error messages. */
1183 ssl
= ssl_promotion(1, sockctrl
, errbuf
, PCAP_ERRBUF_SIZE
);
1186 rpcapd_log(LOGPRIO_ERROR
, "TLS handshake on control connection failed: %s",
1194 // We have a connection.
1195 // Check whether the connecting host is among the ones allowed.
1197 if (sock_check_hostlist(hostlist
, RPCAP_HOSTLIST_SEP
, &from
, errbuf
, PCAP_ERRBUF_SIZE
) < 0)
1199 rpcap_senderror(sockctrl
, ssl
, 0, PCAP_ERR_HOSTNOAUTH
, errbuf
, NULL
);
1205 // Put the socket back into blocking mode; doing WSAEventSelect()
1206 // on the listen socket makes that socket non-blocking, and it
1207 // appears that sockets returned from an accept() on that socket
1208 // are also non-blocking.
1210 // First, we have to un-WSAEventSelect() this socket, and then
1211 // we can turn non-blocking mode off.
1213 // If this fails, we aren't guaranteed that, for example, any
1214 // of the error message will be sent - if it can't be put in
1215 // the socket queue, the send will just fail.
1217 // So we just log the message and close the connection.
1219 if (WSAEventSelect(sockctrl
, NULL
, 0) == SOCKET_ERROR
)
1221 sock_geterror("WSAEventSelect: ", errbuf
, PCAP_ERRBUF_SIZE
);
1222 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
1223 sock_close(sockctrl
, NULL
, 0);
1226 if (ioctlsocket(sockctrl
, FIONBIO
, &off
) == SOCKET_ERROR
)
1228 sock_geterror("ioctlsocket(FIONBIO): ", errbuf
, PCAP_ERRBUF_SIZE
);
1229 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
1230 sock_close(sockctrl
, NULL
, 0);
1235 // Allocate a location to hold the value of sockctrl.
1236 // It will be freed in the newly-created thread once it's
1237 // finished with it.
1238 // I guess we *could* just cast sockctrl to a void *, but that's
1241 sock_copy
= malloc(sizeof(*sock_copy
));
1242 if (sock_copy
== NULL
)
1244 pcap_fmt_errmsg_for_errno(errbuf
, PCAP_ERRBUF_SIZE
,
1245 errno
, "malloc() failed");
1246 rpcap_senderror(sockctrl
, ssl
, 0, PCAP_ERR_OPEN
, errbuf
, NULL
);
1249 sock_copy
->sockctrl
= sockctrl
;
1250 sock_copy
->ssl
= NULL
;
1252 threadId
= (HANDLE
)_beginthreadex(NULL
, 0,
1253 main_passive_serviceloop_thread
, (void *) sock_copy
, 0, NULL
);
1256 pcap_snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Error creating the child thread");
1257 rpcap_senderror(sockctrl
, ssl
, 0, PCAP_ERR_OPEN
, errbuf
, NULL
);
1260 CloseHandle(threadId
);
1265 pcap_snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Error creating the child process");
1266 rpcap_senderror(sockctrl
, ssl
, 0, PCAP_ERR_OPEN
, errbuf
, NULL
);
1274 // Close the socket on which we're listening (must
1275 // be open only in the parent).
1277 closesocket(listen_sock
);
1281 // Modify thread params so that it can be killed at any time
1282 // XXX - is this necessary? This is the main and, currently,
1283 // only thread in the child process, and nobody tries to
1284 // cancel us, although *we* may cancel the thread that's
1285 // handling the capture loop.
1287 if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE
, NULL
))
1289 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS
, NULL
))
1294 // Run the service loop.
1295 // This is passive mode, so we don't care whether we were
1296 // told by the client to close.
1298 (void)daemon_serviceloop(sockctrl
, sockctrl
, ssl
, 0,
1299 nullAuthAllowed
, uses_ssl
);
1307 // Close the socket for this session (must be open only in the child)
1315 closesocket(sockctrl
);
1321 if (sock_copy
) free(sock_copy
);
1324 if (ssl
) SSL_free(ssl
); // Have to be done before closing soskctrl
1326 sock_close(sockctrl
, NULL
, 0);
1330 \brief 'true' main of the program in case the active mode is turned on.
1332 This function loops forever trying to connect to the remote host, until the
1333 daemon is turned down.
1335 \param ptr: it keeps the 'activepars' parameters. It is a 'void *'
1336 just because the thread APIs want this format.
1339 static unsigned __stdcall
1343 main_active(void *ptr
)
1345 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
1346 SOCKET sockctrl
; // keeps the socket ID for this control connection
1347 struct addrinfo hints
; // temporary struct to keep settings needed to open the new socket
1348 struct addrinfo
*addrinfo
; // keeps the addrinfo chain; required to open a new socket
1349 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 if (sock_initaddress(activepars
->address
, activepars
->port
, &hints
, &addrinfo
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
1371 rpcapd_log(LOGPRIO_DEBUG
, "%s", errbuf
);
1379 if ((sockctrl
= sock_open(addrinfo
, SOCKOPEN_CLIENT
, 0, errbuf
, PCAP_ERRBUF_SIZE
)) == INVALID_SOCKET
)
1381 rpcapd_log(LOGPRIO_DEBUG
, "%s", errbuf
);
1383 pcap_snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Error connecting to host %s, port %s, using protocol %s",
1384 activepars
->address
, activepars
->port
, (hints
.ai_family
== AF_INET
) ? "IPv4":
1385 (hints
.ai_family
== AF_INET6
) ? "IPv6" : "Unspecified");
1387 rpcapd_log(LOGPRIO_DEBUG
, "%s", errbuf
);
1389 sleep_secs(RPCAP_ACTIVE_WAIT
);
1395 /* Even in active mode the other other end has to initiate the TLS handshake
1396 * as we still are the server as far as TLS is concerned: */
1399 ssl
= ssl_promotion(1, sockctrl
, errbuf
, PCAP_ERRBUF_SIZE
);
1402 rpcapd_log(LOGPRIO_ERROR
, "TLS handshake on control connection failed: %s",
1404 sock_close(sockctrl
, NULL
, 0);
1410 activeclose
= daemon_serviceloop(sockctrl
, sockctrl
, ssl
, 1,
1411 nullAuthAllowed
, uses_ssl
);
1414 if (ssl
) SSL_free(ssl
);
1416 sock_close(sockctrl
, NULL
, 0);
1418 // If the connection is closed by the user explicitely, don't try to connect to it again
1419 // just exit the program
1420 if (activeclose
== 1)
1424 freeaddrinfo(addrinfo
);
1430 // Main routine of a passive-mode service thread.
1432 unsigned __stdcall
main_passive_serviceloop_thread(void *ptr
)
1434 struct sock_copy sock
= *(struct sock_copy
*)ptr
;
1438 // Handle this client.
1439 // This is passive mode, so we don't care whether we were
1440 // told by the client to close.
1442 (void)daemon_serviceloop(sock
.sockctrl
, sock
.sockctrl
, sock
.ssl
, 0,
1443 nullAuthAllowed
, uses_ssl
);
1445 sock_close(sock
.sockctrl
, NULL
, 0);