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.
38 #include "diag-control.h"
40 #include <errno.h> // for the errno variable
41 #include <string.h> // for strtok, etc
42 #include <stdlib.h> // for malloc(), free(), ...
43 #include <stdio.h> // for fprintf(), stderr, FILE etc
44 #include <pcap.h> // for PCAP_ERRBUF_SIZE
45 #include <signal.h> // for signal()
48 #include "sockutils.h" // for socket calls
49 #include "varattrs.h" // for _U_
50 #include "portability.h"
52 #include "config_params.h" // configuration file parameters
53 #include "fileconf.h" // for the configuration file management
54 #include "rpcap-protocol.h"
55 #include "daemon.h" // the true main() method of this daemon
63 #include <process.h> // for thread stuff
64 #include "win32-svc.h" // for Win32 service stuff
65 #include "getopt.h" // for getopt()-for-Windows
67 #include <fcntl.h> // for open()
68 #include <unistd.h> // for exit()
69 #include <sys/wait.h> // waitpid()
73 // Element in list of sockets on which we're listening for connections.
76 struct listen_sock
*next
;
81 char hostlist
[MAX_HOST_LIST
+ 1]; //!< Keeps the list of the hosts that are allowed to connect to this server
82 struct active_pars activelist
[MAX_ACTIVE_LIST
]; //!< Keeps the list of the hosts (host, port) on which I want to connect to (active mode)
83 int nullAuthAllowed
; //!< '1' if we permit NULL authentication, '0' otherwise
84 static struct listen_sock
*listen_socks
; //!< sockets on which we listen
85 char loadfile
[MAX_LINE
+ 1]; //!< Name of the file from which we have to load the configuration
86 static int passivemode
= 1; //!< '1' if we want to run in passive mode as well
87 static struct addrinfo mainhints
; //!< temporary struct to keep settings needed to open the new socket
88 static char address
[MAX_LINE
+ 1]; //!< keeps the network address (either numeric or literal) to bind to
89 static char port
[MAX_LINE
+ 1]; //!< keeps the network port to bind to
91 static HANDLE state_change_event
; //!< event to signal that a state change should take place
93 static volatile sig_atomic_t shutdown_server
; //!< '1' if the server is to shut down
94 static volatile sig_atomic_t reread_config
; //!< '1' if the server is to re-read its configuration
95 static int uses_ssl
; //!< '1' to use TLS over the data socket
97 extern char *optarg
; // for getopt()
99 // Function definition
101 static unsigned __stdcall
main_active(void *ptr
);
102 static BOOL WINAPI
main_ctrl_event(DWORD
);
104 static void *main_active(void *ptr
);
105 static void main_terminate(int sign
);
106 static void main_reread_config(int sign
);
108 static void accept_connections(void);
109 static void accept_connection(SOCKET listen_sock
);
111 static void main_reap_children(int sign
);
114 static unsigned __stdcall
main_passive_serviceloop_thread(void *ptr
);
117 #define RPCAP_ACTIVE_WAIT 30 /* Waiting time between two attempts to open a connection, in active mode (default: 30 sec) */
120 \brief Prints the usage screen if it is launched in console mode.
122 static void printusage(FILE * f
)
124 const char *usagetext
=
126 " " PROGRAM_NAME
" [-b <address>] [-p <port>] [-4] [-l <host_list>] [-a <host,port>]\n"
131 "[-D] [-s <config_file>] [-f <config_file>]\n\n"
132 " -b <address> the address to bind to (either numeric or literal).\n"
133 " Default: binds to all local IPv4 and IPv6 addresses\n\n"
134 " -p <port> the port to bind to.\n"
135 " Default: binds to port " RPCAP_DEFAULT_NETPORT
"\n\n"
136 " -4 use only IPv4.\n"
137 " Default: use both IPv4 and IPv6 waiting sockets\n\n"
138 " -l <host_list> a file that contains a list of hosts that are allowed\n"
139 " to connect to this server (if more than one, list them one\n"
141 " We suggest to use literal names (instead of numeric ones)\n"
142 " in order to avoid problems with different address families.\n\n"
143 " -n permit NULL authentication (usually used with '-l')\n\n"
144 " -a <host,port> run in active mode when connecting to 'host' on port 'port'\n"
145 " In case 'port' is omitted, the default port (" RPCAP_DEFAULT_NETPORT_ACTIVE
") is used\n\n"
146 " -v run in active mode only (default: if '-a' is specified, it\n"
147 " accepts passive connections as well)\n\n"
148 " -d run in daemon mode (UNIX only) or as a service (Win32 only)\n"
149 " Warning (Win32): this switch is provided automatically when\n"
150 " the service is started from the control panel\n\n"
152 " -i run in inetd mode (UNIX only)\n\n"
154 " -D log debugging messages\n\n"
156 " -S encrypt all communication with SSL (implements rpcaps://)\n"
157 " -C enable compression\n"
158 " -K <pem_file> uses the SSL private key in this file (default: key.pem)\n"
159 " -X <pem_file> uses the certificate from this file (default: cert.pem)\n"
161 " -s <config_file> save the current configuration to file\n\n"
162 " -f <config_file> load the current configuration from file; all switches\n"
163 " specified from the command line are ignored\n\n"
164 " -h print this help screen\n\n";
166 (void)fprintf(f
, "RPCAPD, a remote packet capture daemon.\n"
167 "Compiled with %s\n", pcap_lib_version());
168 #if defined(HAVE_OPENSSL) && defined(SSLEAY_VERSION)
169 (void)fprintf(f
, "Compiled with %s\n", SSLeay_version(SSLEAY_VERSION
));
171 (void)fprintf(f
, "\n%s", usagetext
);
177 int main(int argc
, char *argv
[])
179 char savefile
[MAX_LINE
+ 1]; // name of the file on which we have to save the configuration
180 int log_to_systemlog
= 0; // Non-zero if we should log to the "system log" rather than the standard error
181 int isdaemon
= 0; // Non-zero if the user wants to run this program as a daemon
183 int isrunbyinetd
= 0; // Non-zero if this is being run by inetd or something inetd-like
185 int log_debug_messages
= 0; // Non-zero if the user wants debug messages logged
186 int retval
; // keeps the returning value from several functions
187 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
189 struct sigaction action
;
192 int enable_compression
= 0;
200 memset(errbuf
, 0, sizeof(errbuf
));
202 pcap_strlcpy(address
, RPCAP_DEFAULT_NETADDR
, sizeof (address
));
203 pcap_strlcpy(port
, RPCAP_DEFAULT_NETPORT
, sizeof (port
));
205 // Prepare to open a new server socket
206 memset(&mainhints
, 0, sizeof(struct addrinfo
));
208 mainhints
.ai_family
= PF_UNSPEC
;
209 mainhints
.ai_flags
= AI_PASSIVE
; // Ready to a bind() socket
210 mainhints
.ai_socktype
= SOCK_STREAM
;
212 // Getting the proper command line options
214 # define SSL_CLOPTS "SK:X:C"
216 # define SSL_CLOPTS ""
219 # define CLOPTS "b:dDhip:4l:na:s:f:v" SSL_CLOPTS
221 while ((retval
= getopt(argc
, argv
, CLOPTS
)) != -1)
226 log_debug_messages
= 1;
227 rpcapd_log_set(log_to_systemlog
, log_debug_messages
);
230 pcap_strlcpy(address
, optarg
, sizeof (address
));
233 pcap_strlcpy(port
, optarg
, sizeof (port
));
236 mainhints
.ai_family
= PF_INET
; // IPv4 server only
240 log_to_systemlog
= 1;
241 rpcapd_log_set(log_to_systemlog
, log_debug_messages
);
249 log_to_systemlog
= 1;
250 rpcapd_log_set(log_to_systemlog
, log_debug_messages
);
261 pcap_strlcpy(hostlist
, optarg
, sizeof(hostlist
));
266 char *tmpaddress
, *tmpport
;
270 tmpaddress
= pcap_strtok_r(optarg
, RPCAP_HOSTLIST_SEP
, &lasts
);
272 while ((tmpaddress
!= NULL
) && (i
< MAX_ACTIVE_LIST
))
274 tmpport
= pcap_strtok_r(NULL
, RPCAP_HOSTLIST_SEP
, &lasts
);
276 pcap_strlcpy(activelist
[i
].address
, tmpaddress
, sizeof (activelist
[i
].address
));
278 if ((tmpport
== NULL
) || (strcmp(tmpport
, "DEFAULT") == 0)) // the user choose a custom port
279 pcap_strlcpy(activelist
[i
].port
, RPCAP_DEFAULT_NETPORT_ACTIVE
, sizeof (activelist
[i
].port
));
281 pcap_strlcpy(activelist
[i
].port
, tmpport
, sizeof (activelist
[i
].port
));
283 tmpaddress
= pcap_strtok_r(NULL
, RPCAP_HOSTLIST_SEP
, &lasts
);
288 if (i
> MAX_ACTIVE_LIST
)
289 rpcapd_log(LOGPRIO_ERROR
, "Only MAX_ACTIVE_LIST active connections are currently supported.");
291 // I don't initialize the remaining part of the structure, since
292 // it is already zeroed (it is a global var)
296 pcap_strlcpy(loadfile
, optarg
, sizeof (loadfile
));
299 pcap_strlcpy(savefile
, optarg
, sizeof (savefile
));
306 enable_compression
= 1;
309 ssl_set_keyfile(optarg
);
312 ssl_set_certfile(optarg
);
326 if (isdaemon
&& isrunbyinetd
)
328 rpcapd_log(LOGPRIO_ERROR
, "rpcapd: -d and -i can't be used together");
334 // We want UTF-8 error messages.
336 if (pcap_init(PCAP_CHAR_ENC_UTF_8
, errbuf
) == -1)
338 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
341 pcap_fmt_set_encoding(PCAP_CHAR_ENC_UTF_8
);
343 if (sock_init(errbuf
, PCAP_ERRBUF_SIZE
) == -1)
345 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
349 if (savefile
[0] && fileconf_save(savefile
))
350 rpcapd_log(LOGPRIO_DEBUG
, "Error when saving the configuration to file");
352 // If the file does not exist, it keeps the settings provided by the command line
358 // Create a handle to signal the main loop to tell it to do
361 state_change_event
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
362 if (state_change_event
== NULL
)
364 sock_geterrmsg(errbuf
, PCAP_ERRBUF_SIZE
,
365 "Can't create state change event");
366 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
371 // Catch control signals.
373 if (!SetConsoleCtrlHandler(main_ctrl_event
, TRUE
))
375 sock_geterrmsg(errbuf
, PCAP_ERRBUF_SIZE
,
376 "Can't set control handler");
377 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
381 memset(&action
, 0, sizeof (action
));
382 action
.sa_handler
= main_terminate
;
384 sigemptyset(&action
.sa_mask
);
385 sigaction(SIGTERM
, &action
, NULL
);
386 memset(&action
, 0, sizeof (action
));
387 action
.sa_handler
= main_reap_children
;
389 sigemptyset(&action
.sa_mask
);
390 sigaction(SIGCHLD
, &action
, NULL
);
391 // Ignore SIGPIPE - we'll get EPIPE when trying to write to a closed
392 // connection, we don't want to get killed by a signal in that case
393 signal(SIGPIPE
, SIG_IGN
);
398 if (ssl_init_once(1, enable_compression
, errbuf
, PCAP_ERRBUF_SIZE
) < 0)
400 rpcapd_log(LOGPRIO_ERROR
, "Can't initialize SSL: %s",
411 // -i was specified, indicating that this is being run
412 // by inetd or something that can run network daemons
413 // as if it were inetd (xinetd, launchd, systemd, etc.).
415 // We assume that the program that launched us just
416 // duplicated a single socket for the connection
417 // to our standard input, output, and error, so we
418 // can just use the standard input as our control
425 // Duplicate the standard input as the control socket.
430 sock_geterrmsg(errbuf
, PCAP_ERRBUF_SIZE
,
431 "Can't dup standard input");
432 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
437 // Try to set the standard input, output, and error
440 devnull_fd
= open("/dev/null", O_RDWR
);
441 if (devnull_fd
!= -1)
444 // If this fails, just drive on.
446 (void)dup2(devnull_fd
, 0);
447 (void)dup2(devnull_fd
, 1);
448 (void)dup2(devnull_fd
, 2);
453 // Handle this client.
454 // This is passive mode, so we don't care whether we were
455 // told by the client to close.
457 char *hostlist_copy
= strdup(hostlist
);
458 if (hostlist_copy
== NULL
)
460 rpcapd_log(LOGPRIO_ERROR
, "Out of memory copying the host/port list");
463 (void)daemon_serviceloop(sockctrl
, 0, hostlist_copy
,
464 nullAuthAllowed
, uses_ssl
);
467 // Nothing more to do.
476 // This is being run as a daemon.
477 // On UN*X, it might be manually run, or run from an
484 // Daemonize ourselves.
486 // Unix Network Programming, pg 336
488 if ((pid
= fork()) != 0)
489 exit(0); // Parent terminates
491 // First child continues
495 // generated under unix with 'kill -HUP', needed to reload the configuration
496 memset(&action
, 0, sizeof (action
));
497 action
.sa_handler
= main_reread_config
;
499 sigemptyset(&action
.sa_mask
);
500 sigaction(SIGHUP
, &action
, NULL
);
502 if ((pid
= fork()) != 0)
503 exit(0); // First child terminates
505 // LINUX WARNING: the current linux implementation of pthreads requires a management thread
506 // to handle some hidden stuff. So, as soon as you create the first thread, two threads are
507 // created. Fom this point on, the number of threads active are always one more compared
508 // to the number you're expecting
510 // Second child continues
515 // This is being run as a service on Windows.
517 // If this call succeeds, it is blocking on Win32
520 rpcapd_log(LOGPRIO_DEBUG
, "Unable to start the service");
522 // When the previous call returns, the entire application has to be stopped.
529 // Enable the catching of Ctrl+C
530 memset(&action
, 0, sizeof (action
));
531 action
.sa_handler
= main_terminate
;
533 sigemptyset(&action
.sa_mask
);
534 sigaction(SIGINT
, &action
, NULL
);
536 // generated under unix with 'kill -HUP', needed to reload the configuration
537 // We do not have this kind of signal in Win32
538 memset(&action
, 0, sizeof (action
));
539 action
.sa_handler
= main_reread_config
;
541 sigemptyset(&action
.sa_mask
);
542 sigaction(SIGHUP
, &action
, NULL
);
545 printf("Press CTRL + C to stop the server...\n");
548 // If we're a Win32 service, we have already called this function in the service_main
551 // The code should never arrive here (since the main_startup is blocking)
552 // however this avoids a compiler warning
556 void main_startup(void)
558 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
559 struct addrinfo
*addrinfo
; // keeps the addrinfo chain; required to open a new socket
562 HANDLE threadId
; // handle for the subthread
569 memset(errbuf
, 0, sizeof(errbuf
));
571 // Starts all the active threads
572 while ((i
< MAX_ACTIVE_LIST
) && (activelist
[i
].address
[0] != 0))
574 activelist
[i
].ai_family
= mainhints
.ai_family
;
577 threadId
= (HANDLE
)_beginthreadex(NULL
, 0, main_active
,
578 (void *)&activelist
[i
], 0, NULL
);
581 rpcapd_log(LOGPRIO_DEBUG
, "Error creating the active child threads");
584 CloseHandle(threadId
);
586 if ((pid
= fork()) == 0) // I am the child
588 main_active((void *) &activelist
[i
]);
596 * The code that manages the active connections is not blocking;
597 * the code that manages the passive connection is blocking.
598 * So, if the user does not want to run in passive mode, we have
599 * to block the main thread here, otherwise the program ends and
600 * all threads are stopped.
602 * WARNING: this means that in case we have only active mode,
603 * the program does not terminate even if all the child thread
604 * terminates. The user has always to press Ctrl+C (or send a
605 * SIGTERM) to terminate the program.
609 struct addrinfo
*tempaddrinfo
;
612 // Get a list of sockets on which to listen.
614 if (sock_initaddress((address
[0]) ? address
: NULL
, port
, &mainhints
, &addrinfo
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
616 rpcapd_log(LOGPRIO_DEBUG
, "%s", errbuf
);
620 for (tempaddrinfo
= addrinfo
; tempaddrinfo
;
621 tempaddrinfo
= tempaddrinfo
->ai_next
)
624 struct listen_sock
*sock_info
;
626 if ((sock
= sock_open(NULL
, tempaddrinfo
, SOCKOPEN_SERVER
, SOCKET_MAXCONN
, errbuf
, PCAP_ERRBUF_SIZE
)) == INVALID_SOCKET
)
628 switch (tempaddrinfo
->ai_family
)
632 struct sockaddr_in
*in
;
633 char addrbuf
[INET_ADDRSTRLEN
];
635 in
= (struct sockaddr_in
*)tempaddrinfo
->ai_addr
;
636 rpcapd_log(LOGPRIO_WARNING
, "Can't listen on socket for %s:%u: %s",
637 inet_ntop(AF_INET
, &in
->sin_addr
,
638 addrbuf
, sizeof (addrbuf
)),
646 struct sockaddr_in6
*in6
;
647 char addrbuf
[INET6_ADDRSTRLEN
];
649 in6
= (struct sockaddr_in6
*)tempaddrinfo
->ai_addr
;
650 rpcapd_log(LOGPRIO_WARNING
, "Can't listen on socket for %s:%u: %s",
651 inet_ntop(AF_INET6
, &in6
->sin6_addr
,
652 addrbuf
, sizeof (addrbuf
)),
653 ntohs(in6
->sin6_port
),
659 rpcapd_log(LOGPRIO_WARNING
, "Can't listen on socket for address family %u: %s",
660 tempaddrinfo
->ai_family
,
667 sock_info
= (struct listen_sock
*) malloc(sizeof (struct listen_sock
));
668 if (sock_info
== NULL
)
670 rpcapd_log(LOGPRIO_ERROR
, "Can't allocate structure for listen socket");
673 sock_info
->sock
= sock
;
674 sock_info
->next
= listen_socks
;
675 listen_socks
= sock_info
;
678 freeaddrinfo(addrinfo
);
680 if (listen_socks
== NULL
)
682 rpcapd_log(LOGPRIO_ERROR
, "Can't listen on any address");
687 // Now listen on all of them, waiting for connections.
689 accept_connections();
695 rpcapd_log(LOGPRIO_DEBUG
, PROGRAM_NAME
" is closing.\n");
699 // Sends a KILL signal to all the processes in this process's
700 // process group; i.e., it kills all the child processes
703 // XXX - that also includes us, so we will be killed as well;
704 // that may cause a message to be printed or logged.
710 // Just leave. We shouldn't need to clean up sockets or
711 // anything else, and if we try to do so, we'll could end
712 // up closing sockets, or shutting Winsock down, out from
713 // under service loops, causing all sorts of noisy error
716 // We shouldn't need to worry about cleaning up any resources
717 // such as handles, sockets, threads, etc. - exit() should
718 // terminate the process, causing all those resources to be
719 // cleaned up (including the threads; Microsoft claims in the
720 // ExitProcess() documentation that, if ExitProcess() is called,
721 // "If a thread is waiting on a kernel object, it will not be
722 // terminated until the wait has completed.", but claims in the
723 // _beginthread()/_beginthreadex() documentation that "All threads
724 // are terminated if any thread calls abort, exit, _exit, or
725 // ExitProcess." - the latter appears to be the case, even for
726 // threads waiting on the event for a pcap_t).
733 send_state_change_event(void)
735 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
737 if (!SetEvent(state_change_event
))
739 sock_geterrmsg(errbuf
, PCAP_ERRBUF_SIZE
,
740 "SetEvent on shutdown event failed");
741 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
746 send_shutdown_notification(void)
749 // Indicate that the server should shut down.
754 // Send a state change event, to wake up WSAWaitForMultipleEvents().
756 send_state_change_event();
760 send_reread_configuration_notification(void)
763 // Indicate that the server should re-read its configuration file.
768 // Send a state change event, to wake up WSAWaitForMultipleEvents().
770 send_state_change_event();
773 static BOOL WINAPI
main_ctrl_event(DWORD ctrltype
)
776 // ctrltype is one of:
778 // CTRL_C_EVENT - we got a ^C; this is like SIGINT
779 // CTRL_BREAK_EVENT - we got Ctrl+Break
780 // CTRL_CLOSE_EVENT - the console was closed; this is like SIGHUP
781 // CTRL_LOGOFF_EVENT - a user is logging off; this is received
783 // CTRL_SHUTDOWN_EVENT - the systemis shutting down; this is
784 // received only by services
786 // For now, we treat all but CTRL_LOGOFF_EVENT as indications
787 // that we should shut down.
792 case CTRL_BREAK_EVENT
:
793 case CTRL_CLOSE_EVENT
:
794 case CTRL_SHUTDOWN_EVENT
:
796 // Set a shutdown notification.
798 send_shutdown_notification();
811 static void main_terminate(int sign _U_
)
814 // Note that the server should shut down.
815 // select() should get an EINTR error when we return,
816 // so it will wake up and know it needs to check the flag.
821 static void main_reread_config(int sign _U_
)
824 // Note that the server should re-read its configuration file.
825 // select() should get an EINTR error when we return,
826 // so it will wake up and know it needs to check the flag.
831 static void main_reap_children(int sign _U_
)
836 // Reap all child processes that have exited.
837 // For reference, Stevens, pg 128
839 while ((pid
= waitpid(-1, &exitstat
, WNOHANG
)) > 0)
840 rpcapd_log(LOGPRIO_DEBUG
, "Child terminated");
847 // Loop waiting for incoming connections and accepting them.
850 accept_connections(void)
853 struct listen_sock
*sock_info
;
857 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
860 // How big does the set of events need to be?
861 // One for the shutdown event, plus one for every socket on which
862 // we'll be listening.
864 num_events
= 1; // shutdown event
865 for (sock_info
= listen_socks
; sock_info
;
866 sock_info
= sock_info
->next
)
868 if (num_events
== WSA_MAXIMUM_WAIT_EVENTS
)
871 // WSAWaitForMultipleEvents() doesn't support
872 // more than WSA_MAXIMUM_WAIT_EVENTS events
875 rpcapd_log(LOGPRIO_ERROR
, "Too many sockets on which to listen");
882 // Allocate the array of events.
884 events
= (WSAEVENT
*) malloc(num_events
* sizeof (WSAEVENT
));
887 rpcapd_log(LOGPRIO_ERROR
, "Can't allocate array of events which to listen");
894 events
[0] = state_change_event
; // state change event first
895 for (sock_info
= listen_socks
, i
= 1; sock_info
;
896 sock_info
= sock_info
->next
, i
++)
901 // Create an event that is signaled if there's a connection
902 // to accept on the socket in question.
904 event
= WSACreateEvent();
905 if (event
== WSA_INVALID_EVENT
)
907 sock_geterrmsg(errbuf
, PCAP_ERRBUF_SIZE
,
908 "Can't create socket event");
909 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
912 if (WSAEventSelect(sock_info
->sock
, event
, FD_ACCEPT
) == SOCKET_ERROR
)
914 sock_geterrmsg(errbuf
, PCAP_ERRBUF_SIZE
,
915 "Can't setup socket event");
916 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
925 // Wait for incoming connections.
929 ret
= WSAWaitForMultipleEvents(num_events
, events
, FALSE
,
930 WSA_INFINITE
, FALSE
);
931 if (ret
== WSA_WAIT_FAILED
)
933 sock_geterrmsg(errbuf
, PCAP_ERRBUF_SIZE
,
934 "WSAWaitForMultipleEvents failed");
935 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
939 if (ret
== WSA_WAIT_EVENT_0
)
942 // The state change event was set.
947 // Time to quit. Exit the loop.
954 // We should re-read the configuration
957 reread_config
= 0; // clear the indicator
963 // Check each socket.
965 for (sock_info
= listen_socks
, i
= 1; sock_info
;
966 sock_info
= sock_info
->next
, i
++)
968 WSANETWORKEVENTS network_events
;
970 if (WSAEnumNetworkEvents(sock_info
->sock
,
971 events
[i
], &network_events
) == SOCKET_ERROR
)
973 sock_geterrmsg(errbuf
, PCAP_ERRBUF_SIZE
,
974 "WSAEnumNetworkEvents failed");
975 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
978 if (network_events
.lNetworkEvents
& FD_ACCEPT
)
981 // Did an error occur?
983 if (network_events
.iErrorCode
[FD_ACCEPT_BIT
] != 0)
986 // Yes - report it and keep going.
988 sock_fmterrmsg(errbuf
,
990 network_events
.iErrorCode
[FD_ACCEPT_BIT
],
992 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
997 // Accept the connection.
999 accept_connection(sock_info
->sock
);
1004 struct listen_sock
*sock_info
;
1008 // How big does the bitset of sockets on which to select() have
1012 for (sock_info
= listen_socks
; sock_info
; sock_info
= sock_info
->next
)
1014 if (sock_info
->sock
+ 1 > num_sock_fds
)
1016 if ((unsigned int)(sock_info
->sock
+ 1) >
1017 (unsigned int)FD_SETSIZE
)
1019 rpcapd_log(LOGPRIO_ERROR
, "Socket FD is too bit for an fd_set");
1022 num_sock_fds
= sock_info
->sock
+ 1;
1032 // Set up an fd_set for all the sockets on which we're
1035 // This set is modified by select(), so we have to
1036 // construct it anew each time.
1039 for (sock_info
= listen_socks
; sock_info
;
1040 sock_info
= sock_info
->next
)
1042 FD_SET(sock_info
->sock
, &sock_fds
);
1046 // Wait for incoming connections.
1048 ret
= select(num_sock_fds
, &sock_fds
, NULL
, NULL
, NULL
);
1054 // If this is a "terminate the
1055 // server" signal, exit the loop,
1056 // otherwise just keep trying.
1058 if (shutdown_server
)
1061 // Time to quit. Exit the loop.
1068 // We should re-read the configuration
1071 reread_config
= 0; // clear the indicator
1076 // Go back and wait again.
1082 rpcapd_log(LOGPRIO_ERROR
, "select failed: %s",
1089 // Check each socket.
1091 for (sock_info
= listen_socks
; sock_info
;
1092 sock_info
= sock_info
->next
)
1094 if (FD_ISSET(sock_info
->sock
, &sock_fds
))
1097 // Accept the connection.
1099 accept_connection(sock_info
->sock
);
1106 // Close all the listen sockets.
1108 for (sock_info
= listen_socks
; sock_info
; sock_info
= sock_info
->next
)
1110 closesocket(sock_info
->sock
);
1117 // A structure to hold the parameters to the daemon service loop
1118 // thread on Windows.
1120 // (On UN*X, there is no need for this explicit copy since the
1121 // fork "inherits" the parent stack.)
1123 struct params_copy
{
1130 // Accept a connection and start a worker thread, on Windows, or a
1131 // worker process, on UN*X, to handle the connection.
1134 accept_connection(SOCKET listen_sock
)
1136 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
1137 SOCKET sockctrl
; // keeps the socket ID for this control connection
1138 struct sockaddr_storage from
; // generic sockaddr_storage variable
1139 socklen_t fromlen
; // keeps the length of the sockaddr_storage variable
1142 HANDLE threadId
; // handle for the subthread
1144 struct params_copy
*params_copy
= NULL
;
1149 // Initialize errbuf
1150 memset(errbuf
, 0, sizeof(errbuf
));
1154 // Accept the connection
1155 fromlen
= sizeof(struct sockaddr_storage
);
1157 sockctrl
= accept(listen_sock
, (struct sockaddr
*) &from
, &fromlen
);
1159 if (sockctrl
!= INVALID_SOCKET
)
1165 // The accept() call can return this error when a signal is caught
1166 // In this case, we have simply to ignore this error code
1169 if (WSAGetLastError() == WSAEINTR
)
1175 // Don't check for errors here, since the error can be due to the fact that the thread
1177 sock_geterrmsg(errbuf
, PCAP_ERRBUF_SIZE
, "accept() failed");
1178 rpcapd_log(LOGPRIO_ERROR
, "Accept of control connection from client failed: %s",
1185 // Put the socket back into blocking mode; doing WSAEventSelect()
1186 // on the listen socket makes that socket non-blocking, and it
1187 // appears that sockets returned from an accept() on that socket
1188 // are also non-blocking.
1190 // First, we have to un-WSAEventSelect() this socket, and then
1191 // we can turn non-blocking mode off.
1193 // If this fails, we aren't guaranteed that, for example, any
1194 // of the error message will be sent - if it can't be put in
1195 // the socket queue, the send will just fail.
1197 // So we just log the message and close the connection.
1199 if (WSAEventSelect(sockctrl
, NULL
, 0) == SOCKET_ERROR
)
1201 sock_geterrmsg(errbuf
, PCAP_ERRBUF_SIZE
,
1202 "WSAEventSelect() failed");
1203 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
1204 sock_close(sockctrl
, NULL
, 0);
1207 if (ioctlsocket(sockctrl
, FIONBIO
, &off
) == SOCKET_ERROR
)
1209 sock_geterrmsg(errbuf
, PCAP_ERRBUF_SIZE
,
1210 "ioctlsocket(FIONBIO) failed");
1211 rpcapd_log(LOGPRIO_ERROR
, "%s", errbuf
);
1212 sock_close(sockctrl
, NULL
, 0);
1217 // Make a copy of the host list to pass to the new thread, so that
1218 // if we update it in the main thread, it won't catch us in the
1219 // middle of updating it.
1221 // daemon_serviceloop() will free it once it's done with it.
1223 char *hostlist_copy
= strdup(hostlist
);
1224 if (hostlist_copy
== NULL
)
1226 rpcapd_log(LOGPRIO_ERROR
, "Out of memory copying the host/port list");
1227 sock_close(sockctrl
, NULL
, 0);
1232 // Allocate a location to hold the values of sockctrl.
1233 // It will be freed in the newly-created thread once it's
1234 // finished with it.
1236 params_copy
= malloc(sizeof(*params_copy
));
1237 if (params_copy
== NULL
)
1239 rpcapd_log(LOGPRIO_ERROR
, "Out of memory allocating the parameter copy structure");
1240 free(hostlist_copy
);
1241 sock_close(sockctrl
, NULL
, 0);
1244 params_copy
->sockctrl
= sockctrl
;
1245 params_copy
->hostlist
= hostlist_copy
;
1247 threadId
= (HANDLE
)_beginthreadex(NULL
, 0,
1248 main_passive_serviceloop_thread
, (void *) params_copy
, 0, NULL
);
1251 rpcapd_log(LOGPRIO_ERROR
, "Error creating the child thread");
1253 free(hostlist_copy
);
1254 sock_close(sockctrl
, NULL
, 0);
1257 CloseHandle(threadId
);
1262 rpcapd_log(LOGPRIO_ERROR
, "Error creating the child process: %s",
1264 sock_close(sockctrl
, NULL
, 0);
1272 // Close the socket on which we're listening (must
1273 // be open only in the parent).
1275 closesocket(listen_sock
);
1279 // Modify thread params so that it can be killed at any time
1280 // XXX - is this necessary? This is the main and, currently,
1281 // only thread in the child process, and nobody tries to
1282 // cancel us, although *we* may cancel the thread that's
1283 // handling the capture loop.
1285 if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE
, NULL
))
1287 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS
, NULL
))
1292 // Run the service loop.
1293 // This is passive mode, so we don't care whether we were
1294 // told by the client to close.
1296 char *hostlist_copy
= strdup(hostlist
);
1297 if (hostlist_copy
== NULL
)
1299 rpcapd_log(LOGPRIO_ERROR
, "Out of memory copying the host/port list");
1302 (void)daemon_serviceloop(sockctrl
, 0, hostlist_copy
,
1303 nullAuthAllowed
, uses_ssl
);
1309 // Close the socket for this session (must be open only in the child)
1310 closesocket(sockctrl
);
1315 \brief 'true' main of the program in case the active mode is turned on.
1317 This function loops forever trying to connect to the remote host, until the
1318 daemon is turned down.
1320 \param ptr: it keeps the 'activepars' parameters. It is a 'void *'
1321 just because the thread APIs want this format.
1324 static unsigned __stdcall
1328 main_active(void *ptr
)
1330 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
1331 SOCKET sockctrl
; // keeps the socket ID for this control connection
1332 struct addrinfo hints
; // temporary struct to keep settings needed to open the new socket
1333 struct addrinfo
*addrinfo
; // keeps the addrinfo chain; required to open a new socket
1334 struct active_pars
*activepars
;
1336 activepars
= (struct active_pars
*) ptr
;
1338 // Prepare to open a new server socket
1339 memset(&hints
, 0, sizeof(struct addrinfo
));
1340 // WARNING Currently it supports only ONE socket family among IPv4 and IPv6
1341 hints
.ai_family
= AF_INET
; // PF_UNSPEC to have both IPv4 and IPv6 server
1342 hints
.ai_socktype
= SOCK_STREAM
;
1343 hints
.ai_family
= activepars
->ai_family
;
1345 rpcapd_log(LOGPRIO_DEBUG
, "Connecting to host %s, port %s, using protocol %s",
1346 activepars
->address
, activepars
->port
, (hints
.ai_family
== AF_INET
) ? "IPv4":
1347 (hints
.ai_family
== AF_INET6
) ? "IPv6" : "Unspecified");
1349 // Initialize errbuf
1350 memset(errbuf
, 0, sizeof(errbuf
));
1353 if (sock_initaddress(activepars
->address
, activepars
->port
, &hints
, &addrinfo
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
1355 rpcapd_log(LOGPRIO_DEBUG
, "%s", errbuf
);
1363 if ((sockctrl
= sock_open(activepars
->address
, addrinfo
, SOCKOPEN_CLIENT
, 0, errbuf
, PCAP_ERRBUF_SIZE
)) == INVALID_SOCKET
)
1365 rpcapd_log(LOGPRIO_DEBUG
, "%s", errbuf
);
1367 DIAG_OFF_FORMAT_TRUNCATION
1368 snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Error connecting to host %s, port %s, using protocol %s",
1369 activepars
->address
, activepars
->port
, (hints
.ai_family
== AF_INET
) ? "IPv4":
1370 (hints
.ai_family
== AF_INET6
) ? "IPv6" : "Unspecified");
1371 DIAG_ON_FORMAT_TRUNCATION
1373 rpcapd_log(LOGPRIO_DEBUG
, "%s", errbuf
);
1375 sleep_secs(RPCAP_ACTIVE_WAIT
);
1380 char *hostlist_copy
= strdup(hostlist
);
1381 if (hostlist_copy
== NULL
)
1383 rpcapd_log(LOGPRIO_ERROR
, "Out of memory copying the host/port list");
1385 sock_close(sockctrl
, NULL
, 0);
1390 // daemon_serviceloop() will free the copy.
1392 activeclose
= daemon_serviceloop(sockctrl
, 1,
1393 hostlist_copy
, nullAuthAllowed
, uses_ssl
);
1396 // If the connection is closed by the user explicitly, don't try to connect to it again
1397 // just exit the program
1398 if (activeclose
== 1)
1402 freeaddrinfo(addrinfo
);
1408 // Main routine of a passive-mode service thread.
1410 unsigned __stdcall
main_passive_serviceloop_thread(void *ptr
)
1412 struct params_copy params
= *(struct params_copy
*)ptr
;
1416 // Handle this client.
1417 // This is passive mode, so we don't care whether we were
1418 // told by the client to close.
1420 (void)daemon_serviceloop(params
.sockctrl
, 0, params
.hostlist
,
1421 nullAuthAllowed
, uses_ssl
);