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
94 extern char *optarg
; // for getopt()
96 // Function definition
98 static unsigned __stdcall
main_active(void *ptr
);
99 static BOOL WINAPI
main_ctrl_event(DWORD
);
101 static void *main_active(void *ptr
);
102 static void main_terminate(int sign
);
103 static void main_reread_config(int sign
);
105 static void accept_connections(void);
106 static void accept_connection(SOCKET listen_sock
);
108 static void main_reap_children(int sign
);
111 static unsigned __stdcall
main_passive_serviceloop_thread(void *ptr
);
114 #define RPCAP_ACTIVE_WAIT 30 /* Waiting time between two attempts to open a connection, in active mode (default: 30 sec) */
117 \brief Prints the usage screen if it is launched in console mode.
119 static void printusage(void)
121 const char *usagetext
=
123 " " PROGRAM_NAME
" [-b <address>] [-p <port>] [-4] [-l <host_list>] [-a <host,port>]\n"
128 "[-s <config_file>] [-f <config_file>]\n\n"
129 " -b <address> the address to bind to (either numeric or literal).\n"
130 " Default: binds to all local IPv4 and IPv6 addresses\n\n"
131 " -p <port> the port to bind to.\n"
132 " Default: binds to port " RPCAP_DEFAULT_NETPORT
"\n\n"
133 " -4 use only IPv4.\n"
134 " Default: use both IPv4 and IPv6 waiting sockets\n\n"
135 " -l <host_list> a file that contains a list of hosts that are allowed\n"
136 " to connect to this server (if more than one, list them one\n"
138 " We suggest to use literal names (instead of numeric ones)\n"
139 " in order to avoid problems with different address families.\n\n"
140 " -n permit NULL authentication (usually used with '-l')\n\n"
141 " -a <host,port> run in active mode when connecting to 'host' on port 'port'\n"
142 " In case 'port' is omitted, the default port (" RPCAP_DEFAULT_NETPORT_ACTIVE
") is used\n\n"
143 " -v run in active mode only (default: if '-a' is specified, it\n"
144 " accepts passive connections as well)\n\n"
145 " -d run in daemon mode (UNIX only) or as a service (Win32 only)\n"
146 " Warning (Win32): this switch is provided automatically when\n"
147 " the service is started from the control panel\n\n"
149 " -i run in inetd mode (UNIX only)\n\n"
151 " -s <config_file> save the current configuration to file\n\n"
152 " -f <config_file> load the current configuration from file; all switches\n"
153 " specified from the command line are ignored\n\n"
154 " -h print this help screen\n\n";
156 (void)fprintf(stderr
, "RPCAPD, a remote packet capture daemon.\n"
157 "Compiled with %s\n\n", pcap_lib_version());
158 printf("%s", usagetext
);
164 int main(int argc
, char *argv
[])
166 char savefile
[MAX_LINE
+ 1]; // name of the file on which we have to save the configuration
167 int isdaemon
= 0; // Non-zero if the user wants to run this program as a daemon
169 int isrunbyinetd
= 0; // Non-zero if this is being run by inetd or something inetd-like
171 int retval
; // keeps the returning value from several functions
172 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
174 struct sigaction action
;
182 memset(errbuf
, 0, sizeof(errbuf
));
184 if (sock_init(errbuf
, PCAP_ERRBUF_SIZE
) == -1)
186 SOCK_DEBUG_MESSAGE(errbuf
);
190 strncpy(address
, RPCAP_DEFAULT_NETADDR
, MAX_LINE
);
191 strncpy(port
, RPCAP_DEFAULT_NETPORT
, MAX_LINE
);
193 // Prepare to open a new server socket
194 memset(&mainhints
, 0, sizeof(struct addrinfo
));
196 mainhints
.ai_family
= PF_UNSPEC
;
197 mainhints
.ai_flags
= AI_PASSIVE
; // Ready to a bind() socket
198 mainhints
.ai_socktype
= SOCK_STREAM
;
200 // Getting the proper command line options
202 # define SSL_CLOPTS "SK:C:"
204 # define SSL_CLOPTS ""
207 # define CLOPTS "b:dhip:4l:na:s:f:v" SSL_CLOPTS
209 while ((retval
= getopt(argc
, argv
, CLOPTS
)) != -1)
214 strncpy(address
, optarg
, MAX_LINE
);
217 strncpy(port
, optarg
, MAX_LINE
);
220 mainhints
.ai_family
= PF_INET
; // IPv4 server only
241 strncpy(hostlist
, optarg
, sizeof(hostlist
));
246 char *tmpaddress
, *tmpport
;
250 tmpaddress
= pcap_strtok_r(optarg
, RPCAP_HOSTLIST_SEP
, &lasts
);
252 while ((tmpaddress
!= NULL
) && (i
< MAX_ACTIVE_LIST
))
254 tmpport
= pcap_strtok_r(NULL
, RPCAP_HOSTLIST_SEP
, &lasts
);
256 strlcpy(activelist
[i
].address
, tmpaddress
, MAX_LINE
);
258 if ((tmpport
== NULL
) || (strcmp(tmpport
, "DEFAULT") == 0)) // the user choose a custom port
259 strlcpy(activelist
[i
].port
, RPCAP_DEFAULT_NETPORT_ACTIVE
, MAX_LINE
);
261 strlcpy(activelist
[i
].port
, tmpport
, MAX_LINE
);
263 tmpaddress
= pcap_strtok_r(NULL
, RPCAP_HOSTLIST_SEP
, &lasts
);
268 if (i
> MAX_ACTIVE_LIST
)
269 SOCK_DEBUG_MESSAGE("Only MAX_ACTIVE_LIST active connections are currently supported.");
271 // I don't initialize the remaining part of the structure, since
272 // it is already zeroed (it is a global var)
276 strlcpy(loadfile
, optarg
, MAX_LINE
);
279 strlcpy(savefile
, optarg
, MAX_LINE
);
286 snprintf(ssl_keyfile
, sizeof ssl_keyfile
, "%s", optarg
);
289 snprintf(ssl_certfile
, sizeof ssl_certfile
, "%s", optarg
);
303 if (isdaemon
&& isrunbyinetd
)
305 fprintf(stderr
, "rpcapd: -d and -i can't be used together\n");
310 if (savefile
[0] && fileconf_save(savefile
))
311 SOCK_DEBUG_MESSAGE("Error when saving the configuration to file");
313 // If the file does not exist, it keeps the settings provided by the command line
319 // Create a handle to signal the main loop to tell it to do
322 state_change_event
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
323 if (state_change_event
== NULL
)
325 sock_geterror(NULL
, errbuf
, PCAP_ERRBUF_SIZE
);
326 rpcapd_log(LOGPRIO_ERROR
, "Can't create state change event: %s",
332 // Catch control signals.
334 if (!SetConsoleCtrlHandler(main_ctrl_event
, TRUE
))
336 sock_geterror(NULL
, errbuf
, PCAP_ERRBUF_SIZE
);
337 rpcapd_log(LOGPRIO_ERROR
, "Can't set control handler: %s",
342 memset(&action
, 0, sizeof (action
));
343 action
.sa_handler
= main_terminate
;
345 sigemptyset(&action
.sa_mask
);
346 sigaction(SIGTERM
, &action
, NULL
);
347 memset(&action
, 0, sizeof (action
));
348 action
.sa_handler
= main_reap_children
;
350 sigemptyset(&action
.sa_mask
);
351 sigaction(SIGCHLD
, &action
, NULL
);
352 // Ignore SIGPIPE - we'll get EPIPE when trying to write to a closed
353 // connection, we don't want to get killed by a signal in that case
354 signal(SIGPIPE
, SIG_IGN
);
359 if (uses_ssl
) init_ssl_or_die(1);
364 // -i was specified, indicating that this is being run
365 // by inetd or something that can run network daemons
366 // as if it were inetd (xinetd, launchd, systemd, etc.).
368 // Our standard input is the input side of a connection,
369 // and our standard output is the output side of a
372 int sockctrl_in
, sockctrl_out
;
376 // Duplicate the standard input and output, making them
377 // the input and output side of the control connection.
379 sockctrl_in
= dup(0);
380 if (sockctrl_in
== -1)
382 sock_geterror(NULL
, errbuf
, PCAP_ERRBUF_SIZE
);
383 rpcapd_log(LOGPRIO_ERROR
, "Can't dup standard input: %s",
387 sockctrl_out
= dup(1);
388 if (sockctrl_out
== -1)
390 sock_geterror(NULL
, errbuf
, PCAP_ERRBUF_SIZE
);
391 rpcapd_log(LOGPRIO_ERROR
, "Can't dup standard output: %s",
397 // Try to set the standard input and output to /dev/null.
399 devnull_fd
= open("/dev/null", O_RDWR
);
400 if (devnull_fd
!= -1)
403 // If this fails, just drive on.
405 (void)dup2(devnull_fd
, 0);
406 (void)dup2(devnull_fd
, 1);
411 // Handle this client.
412 // This is passive mode, so we don't care whether we were
413 // told by the client to close.
415 (void)daemon_serviceloop(sockctrl_in
, sockctrl_out
, 0,
419 // Nothing more to do.
428 // This is being run as a daemon.
429 // On UN*X, it might be manually run, or run from an
436 // Daemonize ourselves.
438 // Unix Network Programming, pg 336
440 if ((pid
= fork()) != 0)
441 exit(0); // Parent terminates
443 // First child continues
447 // generated under unix with 'kill -HUP', needed to reload the configuration
448 memset(&action
, 0, sizeof (action
));
449 action
.sa_handler
= main_reread_config
;
451 sigemptyset(&action
.sa_mask
);
452 sigaction(SIGHUP
, &action
, NULL
);
454 if ((pid
= fork()) != 0)
455 exit(0); // First child terminates
457 // LINUX WARNING: the current linux implementation of pthreads requires a management thread
458 // to handle some hidden stuff. So, as soon as you create the first thread, two threads are
459 // created. Fom this point on, the number of threads active are always one more compared
460 // to the number you're expecting
462 // Second child continues
467 // This is being run as a service on Windows.
469 // If this call succeeds, it is blocking on Win32
471 if (svc_start() != 1)
472 SOCK_DEBUG_MESSAGE("Unable to start the service");
474 // When the previous call returns, the entire application has to be stopped.
481 // Enable the catching of Ctrl+C
482 memset(&action
, 0, sizeof (action
));
483 action
.sa_handler
= main_terminate
;
485 sigemptyset(&action
.sa_mask
);
486 sigaction(SIGINT
, &action
, NULL
);
488 // generated under unix with 'kill -HUP', needed to reload the configuration
489 // We do not have this kind of signal in Win32
490 memset(&action
, 0, sizeof (action
));
491 action
.sa_handler
= main_reread_config
;
493 sigemptyset(&action
.sa_mask
);
494 sigaction(SIGHUP
, &action
, NULL
);
497 printf("Press CTRL + C to stop the server...\n");
500 // If we're a Win32 service, we have already called this function in the service_main
503 // The code should never arrive here (since the main_startup is blocking)
504 // however this avoids a compiler warning
508 void main_startup(void)
510 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
511 struct addrinfo
*addrinfo
; // keeps the addrinfo chain; required to open a new socket
514 HANDLE threadId
; // handle for the subthread
521 memset(errbuf
, 0, sizeof(errbuf
));
523 // Starts all the active threads
524 while ((i
< MAX_ACTIVE_LIST
) && (activelist
[i
].address
[0] != 0))
526 activelist
[i
].ai_family
= mainhints
.ai_family
;
529 threadId
= (HANDLE
)_beginthreadex(NULL
, 0, main_active
,
530 (void *)&activelist
[i
], 0, NULL
);
533 SOCK_DEBUG_MESSAGE("Error creating the active child threads");
536 CloseHandle(threadId
);
538 if ((pid
= fork()) == 0) // I am the child
540 main_active((void *) &activelist
[i
]);
548 * The code that manages the active connections is not blocking;
549 * the code that manages the passive connection is blocking.
550 * So, if the user does not want to run in passive mode, we have
551 * to block the main thread here, otherwise the program ends and
552 * all threads are stopped.
554 * WARNING: this means that in case we have only active mode,
555 * the program does not terminate even if all the child thread
556 * terminates. The user has always to press Ctrl+C (or send a
557 * SIGTERM) to terminate the program.
561 struct addrinfo
*tempaddrinfo
;
564 // Get a list of sockets on which to listen.
566 if (sock_initaddress((address
[0]) ? address
: NULL
, port
, &mainhints
, &addrinfo
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
568 SOCK_DEBUG_MESSAGE(errbuf
);
572 for (tempaddrinfo
= addrinfo
; tempaddrinfo
;
573 tempaddrinfo
= tempaddrinfo
->ai_next
)
576 struct listen_sock
*sock_info
;
578 if ((sock
= sock_open(tempaddrinfo
, SOCKOPEN_SERVER
, SOCKET_MAXCONN
, errbuf
, PCAP_ERRBUF_SIZE
)) == INVALID_SOCKET
)
580 switch (tempaddrinfo
->ai_family
)
584 struct sockaddr_in
*in
;
585 char addrbuf
[INET_ADDRSTRLEN
];
587 in
= (struct sockaddr_in
*)tempaddrinfo
->ai_addr
;
588 rpcapd_log(LOGPRIO_WARNING
, "Can't listen on socket for %s:%u: %s",
589 inet_ntop(AF_INET
, &in
->sin_addr
,
590 addrbuf
, sizeof (addrbuf
)),
598 struct sockaddr_in6
*in6
;
599 char addrbuf
[INET6_ADDRSTRLEN
];
601 in6
= (struct sockaddr_in6
*)tempaddrinfo
->ai_addr
;
602 rpcapd_log(LOGPRIO_WARNING
, "Can't listen on socket for %s:%u: %s",
603 inet_ntop(AF_INET6
, &in6
->sin6_addr
,
604 addrbuf
, sizeof (addrbuf
)),
605 ntohs(in6
->sin6_port
),
611 rpcapd_log(LOGPRIO_WARNING
, "Can't listen on socket for address family %u: %s",
612 tempaddrinfo
->ai_family
,
619 sock_info
= (struct listen_sock
*) malloc(sizeof (struct listen_sock
));
620 if (sock_info
== NULL
)
622 rpcapd_log(LOGPRIO_ERROR
, "Can't allocate structure for listen socket");
625 sock_info
->sock
= sock
;
626 sock_info
->next
= listen_socks
;
627 listen_socks
= sock_info
;
630 freeaddrinfo(addrinfo
);
632 if (listen_socks
== NULL
)
634 rpcapd_log(LOGPRIO_ERROR
, "Can't listen on any address");
639 // Now listen on all of them, waiting for connections.
641 accept_connections();
647 SOCK_DEBUG_MESSAGE(PROGRAM_NAME
" is closing.\n");
651 // Sends a KILL signal to all the processes in this process's
652 // process group; i.e., it kills all the child processes
655 // XXX - that also includes us, so we will be killed as well;
656 // that may cause a message to be printed or logged.
662 // Just leave. We shouldn't need to clean up sockets or
663 // anything else, and if we try to do so, we'll could end
664 // up closing sockets, or shutting Winsock down, out from
665 // under service loops, causing all sorts of noisy error
668 // We shouldn't need to worry about cleaning up any resources
669 // such as handles, sockets, threads, etc. - exit() should
670 // terminate the process, causing all those resources to be
671 // cleaned up (including the threads; Microsoft claims in the
672 // ExitProcess() documentation that, if ExitProcess() is called,
673 // "If a thread is waiting on a kernel object, it will not be
674 // terminated until the wait has completed.", but claims in the
675 // _beginthread()/_beginthreadex() documentation that "All threads
676 // are terminated if any thread calls abort, exit, _exit, or
677 // ExitProcess." - the latter appears to be the case, even for
678 // threads waiting on the event for a pcap_t).
685 send_state_change_event(void)
687 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
689 if (!SetEvent(state_change_event
))
691 sock_geterror(NULL
, errbuf
, PCAP_ERRBUF_SIZE
);
692 rpcapd_log(LOGPRIO_ERROR
, "SetEvent on shutdown event failed: %s", errbuf
);
697 send_shutdown_notification(void)
700 // Indicate that the server should shut down.
705 // Send a state change event, to wake up WSAWaitForMultipleEvents().
707 send_state_change_event();
711 send_reread_configuration_notification(void)
714 // Indicate that the server should re-read its configuration file.
719 // Send a state change event, to wake up WSAWaitForMultipleEvents().
721 send_state_change_event();
724 static BOOL WINAPI
main_ctrl_event(DWORD ctrltype
)
727 // ctrltype is one of:
729 // CTRL_C_EVENT - we got a ^C; this is like SIGINT
730 // CTRL_BREAK_EVENT - we got Ctrl+Break
731 // CTRL_CLOSE_EVENT - the console was closed; this is like SIGHUP
732 // CTRL_LOGOFF_EVENT - a user is logging off; this is received
734 // CTRL_SHUTDOWN_EVENT - the systemis shutting down; this is
735 // received only by services
737 // For now, we treat all but CTRL_LOGOFF_EVENT as indications
738 // that we should shut down.
743 case CTRL_BREAK_EVENT
:
744 case CTRL_CLOSE_EVENT
:
745 case CTRL_SHUTDOWN_EVENT
:
747 // Set a shutdown notification.
749 send_shutdown_notification();
762 static void main_terminate(int sign _U_
)
765 // Note that the server should shut down.
766 // select() should get an EINTR error when we return,
767 // so it will wake up and know it needs to check the flag.
772 static void main_reread_config(int sign _U_
)
775 // Note that the server should re-read its configuration file.
776 // select() should get an EINTR error when we return,
777 // so it will wake up and know it needs to check the flag.
782 static void main_reap_children(int sign _U_
)
787 // Reap all child processes that have exited.
788 // For reference, Stevens, pg 128
790 while ((pid
= waitpid(-1, &exitstat
, WNOHANG
)) > 0)
791 SOCK_DEBUG_MESSAGE("Child terminated");
798 // Loop waiting for incoming connections and accepting them.
801 accept_connections(void)
804 struct listen_sock
*sock_info
;
808 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
811 // How big does the set of events need to be?
812 // One for the shutdown event, plus one for every socket on which
813 // we'll be listening.
815 num_events
= 1; // shutdown event
816 for (sock_info
= listen_socks
; sock_info
;
817 sock_info
= sock_info
->next
)
819 if (num_events
== WSA_MAXIMUM_WAIT_EVENTS
)
822 // WSAWaitForMultipleEvents() doesn't support
823 // more than WSA_MAXIMUM_WAIT_EVENTS events
826 rpcapd_log(LOGPRIO_ERROR
, "Too many sockets on which to listen");
833 // Allocate the array of events.
835 events
= (WSAEVENT
*) malloc(num_events
* sizeof (WSAEVENT
));
838 rpcapd_log(LOGPRIO_ERROR
, "Can't allocate array of events which to listen");
845 events
[0] = state_change_event
; // state change event first
846 for (sock_info
= listen_socks
, i
= 1; sock_info
;
847 sock_info
= sock_info
->next
, i
++)
852 // Create an event that is signaled if there's a connection
853 // to accept on the socket in question.
855 event
= WSACreateEvent();
856 if (event
== WSA_INVALID_EVENT
)
858 sock_geterror(NULL
, errbuf
, PCAP_ERRBUF_SIZE
);
859 rpcapd_log(LOGPRIO_ERROR
, "Can't create socket event: %s", errbuf
);
862 if (WSAEventSelect(sock_info
->sock
, event
, FD_ACCEPT
) == SOCKET_ERROR
)
864 sock_geterror(NULL
, errbuf
, PCAP_ERRBUF_SIZE
);
865 rpcapd_log(LOGPRIO_ERROR
, "Can't setup socket event: %s", errbuf
);
874 // Wait for incoming connections.
878 ret
= WSAWaitForMultipleEvents(num_events
, events
, FALSE
,
879 WSA_INFINITE
, FALSE
);
880 if (ret
== WSA_WAIT_FAILED
)
882 sock_geterror(NULL
, errbuf
, PCAP_ERRBUF_SIZE
);
883 rpcapd_log(LOGPRIO_ERROR
, "WSAWaitForMultipleEvents failed: %s", errbuf
);
887 if (ret
== WSA_WAIT_EVENT_0
)
890 // The state change event was set.
895 // Time to quit. Exit the loop.
902 // We should re-read the configuration
905 reread_config
= 0; // clear the indicator
911 // Check each socket.
913 for (sock_info
= listen_socks
, i
= 1; sock_info
;
914 sock_info
= sock_info
->next
, i
++)
916 WSANETWORKEVENTS network_events
;
918 if (WSAEnumNetworkEvents(sock_info
->sock
,
919 events
[i
], &network_events
) == SOCKET_ERROR
)
921 sock_geterror(NULL
, errbuf
, PCAP_ERRBUF_SIZE
);
922 rpcapd_log(LOGPRIO_ERROR
, "WSAEnumNetworkEvents failed: %s", errbuf
);
925 if (network_events
.lNetworkEvents
& FD_ACCEPT
)
928 // Did an error occur?
930 if (network_events
.iErrorCode
[FD_ACCEPT_BIT
] != 0)
933 // Yes - report it and keep going.
936 network_events
.iErrorCode
[FD_ACCEPT_BIT
],
939 rpcapd_log(LOGPRIO_ERROR
, "Socket error: %s", errbuf
);
944 // Accept the connection.
946 accept_connection(sock_info
->sock
);
951 struct listen_sock
*sock_info
;
955 // How big does the bitset of sockets on which to select() have
959 for (sock_info
= listen_socks
; sock_info
; sock_info
= sock_info
->next
)
961 if (sock_info
->sock
+ 1 > num_sock_fds
)
963 if ((unsigned int)(sock_info
->sock
+ 1) >
964 (unsigned int)FD_SETSIZE
)
966 rpcapd_log(LOGPRIO_ERROR
, "Socket FD is too bit for an fd_set");
969 num_sock_fds
= sock_info
->sock
+ 1;
979 // Set up an fd_set for all the sockets on which we're
982 // This set is modified by select(), so we have to
983 // construct it anew each time.
986 for (sock_info
= listen_socks
; sock_info
;
987 sock_info
= sock_info
->next
)
989 FD_SET(sock_info
->sock
, &sock_fds
);
993 // Wait for incoming connections.
995 ret
= select(num_sock_fds
, &sock_fds
, NULL
, NULL
, NULL
);
1001 // If this is a "terminate the
1002 // server" signal, exit the loop,
1003 // otherwise just keep trying.
1005 if (shutdown_server
)
1008 // Time to quit. Exit the loop.
1015 // We should re-read the configuration
1018 reread_config
= 0; // clear the indicator
1023 // Go back and wait again.
1029 rpcapd_log(LOGPRIO_ERROR
, "select failed: %s",
1036 // Check each socket.
1038 for (sock_info
= listen_socks
; sock_info
;
1039 sock_info
= sock_info
->next
)
1041 if (FD_ISSET(sock_info
->sock
, &sock_fds
))
1044 // Accept the connection.
1046 accept_connection(sock_info
->sock
);
1053 // Close all the listen sockets.
1055 for (sock_info
= listen_socks
; sock_info
; sock_info
= sock_info
->next
)
1057 closesocket(sock_info
->sock
);
1063 // Accept a connection and start a worker thread, on Windows, or a
1064 // worker process, on UN*X, to handle the connection.
1067 accept_connection(SOCKET listen_sock
)
1069 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
1070 SOCKET sockctrl
; // keeps the socket ID for this control connection
1071 struct sockaddr_storage from
; // generic sockaddr_storage variable
1072 socklen_t fromlen
; // keeps the length of the sockaddr_storage variable
1075 HANDLE threadId
; // handle for the subthread
1077 SOCKET
*sockctrl_temp
;
1082 // Initialize errbuf
1083 memset(errbuf
, 0, sizeof(errbuf
));
1087 // Accept the connection
1088 fromlen
= sizeof(struct sockaddr_storage
);
1090 sockctrl
= accept(listen_sock
, (struct sockaddr
*) &from
, &fromlen
);
1092 if (sockctrl
!= INVALID_SOCKET
)
1098 // The accept() call can return this error when a signal is catched
1099 // In this case, we have simply to ignore this error code
1102 if (WSAGetLastError() == WSAEINTR
)
1108 // Don't check for errors here, since the error can be due to the fact that the thread
1110 sock_geterror("accept(): ", errbuf
, PCAP_ERRBUF_SIZE
);
1111 rpcapd_log(LOGPRIO_ERROR
, "Accept of control connection from client failed: %s",
1117 // We have a connection.
1118 // Check whether the connecting host is among the ones allowed.
1120 if (sock_check_hostlist(hostlist
, RPCAP_HOSTLIST_SEP
, &from
, errbuf
, PCAP_ERRBUF_SIZE
) < 0)
1122 rpcap_senderror(sockctrl
, 0, PCAP_ERR_HOSTNOAUTH
, errbuf
, NULL
);
1123 sock_close(sockctrl
, NULL
, 0);
1129 // Put the socket back into blocking mode; doing WSAEventSelect()
1130 // on the listen socket makes that socket non-blocking, and it
1131 // appears that sockets returned from an accept() on that socket
1132 // are also non-blocking.
1134 // First, we have to un-WSAEventSelect() this socket, and then
1135 // we can turn non-blocking mode off.
1137 if (WSAEventSelect(sockctrl
, NULL
, 0) == SOCKET_ERROR
)
1139 sock_geterror("ioctlsocket(FIONBIO): ", errbuf
, PCAP_ERRBUF_SIZE
);
1140 rpcap_senderror(sockctrl
, 0, PCAP_ERR_HOSTNOAUTH
, errbuf
, NULL
);
1141 sock_close(sockctrl
, NULL
, 0);
1144 if (ioctlsocket(sockctrl
, FIONBIO
, &off
) == SOCKET_ERROR
)
1146 sock_geterror("ioctlsocket(FIONBIO): ", errbuf
, PCAP_ERRBUF_SIZE
);
1147 rpcap_senderror(sockctrl
, 0, PCAP_ERR_HOSTNOAUTH
, errbuf
, NULL
);
1148 sock_close(sockctrl
, NULL
, 0);
1153 // Allocate a location to hold the value of sockctrl.
1154 // It will be freed in the newly-created thread once it's
1155 // finished with it.
1156 // I guess we *could* just cast sockctrl to a void *, but that's
1159 sockctrl_temp
= (SOCKET
*)malloc(sizeof (SOCKET
));
1160 if (sockctrl_temp
== NULL
)
1162 pcap_fmt_errmsg_for_errno(errbuf
, PCAP_ERRBUF_SIZE
,
1163 errno
, "malloc() failed");
1164 rpcap_senderror(sockctrl
, 0, PCAP_ERR_OPEN
, errbuf
, NULL
);
1165 sock_close(sockctrl
, NULL
, 0);
1168 *sockctrl_temp
= sockctrl
;
1170 threadId
= (HANDLE
)_beginthreadex(NULL
, 0,
1171 main_passive_serviceloop_thread
, (void *) sockctrl_temp
, 0, NULL
);
1174 pcap_snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Error creating the child thread");
1175 rpcap_senderror(sockctrl
, 0, PCAP_ERR_OPEN
, errbuf
, NULL
);
1176 sock_close(sockctrl
, NULL
, 0);
1177 free(sockctrl_temp
);
1180 CloseHandle(threadId
);
1185 pcap_snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Error creating the child process");
1186 rpcap_senderror(sockctrl
, 0, PCAP_ERR_OPEN
, errbuf
, NULL
);
1187 sock_close(sockctrl
, NULL
, 0);
1195 // Close the socket on which we're listening (must
1196 // be open only in the parent).
1198 closesocket(listen_sock
);
1202 // Modify thread params so that it can be killed at any time
1203 // XXX - is this necessary? This is the main and, currently,
1204 // only thread in the child process, and nobody tries to
1205 // cancel us, although *we* may cancel the thread that's
1206 // handling the capture loop.
1208 if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE
, NULL
))
1210 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS
, NULL
))
1215 // Run the service loop.
1216 // This is passive mode, so we don't care whether we were
1217 // told by the client to close.
1219 (void)daemon_serviceloop(sockctrl
, sockctrl
, 0,
1228 // Close the socket for this session (must be open only in the child)
1229 closesocket(sockctrl
);
1234 \brief 'true' main of the program in case the active mode is turned on.
1236 This function loops forever trying to connect to the remote host, until the
1237 daemon is turned down.
1239 \param ptr: it keeps the 'activepars' parameters. It is a 'void *'
1240 just because the thread APIs want this format.
1243 static unsigned __stdcall
1247 main_active(void *ptr
)
1249 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
1250 SOCKET sockctrl
; // keeps the socket ID for this control connection
1251 struct addrinfo hints
; // temporary struct to keep settings needed to open the new socket
1252 struct addrinfo
*addrinfo
; // keeps the addrinfo chain; required to open a new socket
1253 struct active_pars
*activepars
;
1255 activepars
= (struct active_pars
*) ptr
;
1257 // Prepare to open a new server socket
1258 memset(&hints
, 0, sizeof(struct addrinfo
));
1259 // WARNING Currently it supports only ONE socket family among IPv4 and IPv6
1260 hints
.ai_family
= AF_INET
; // PF_UNSPEC to have both IPv4 and IPv6 server
1261 hints
.ai_socktype
= SOCK_STREAM
;
1262 hints
.ai_family
= activepars
->ai_family
;
1264 pcap_snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Connecting to host %s, port %s, using protocol %s",
1265 activepars
->address
, activepars
->port
, (hints
.ai_family
== AF_INET
) ? "IPv4":
1266 (hints
.ai_family
== AF_INET6
) ? "IPv6" : "Unspecified");
1267 SOCK_DEBUG_MESSAGE(errbuf
);
1269 // Initialize errbuf
1270 memset(errbuf
, 0, sizeof(errbuf
));
1273 if (sock_initaddress(activepars
->address
, activepars
->port
, &hints
, &addrinfo
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
1275 SOCK_DEBUG_MESSAGE(errbuf
);
1283 if ((sockctrl
= sock_open(addrinfo
, SOCKOPEN_CLIENT
, 0, errbuf
, PCAP_ERRBUF_SIZE
)) == INVALID_SOCKET
)
1285 SOCK_DEBUG_MESSAGE(errbuf
);
1287 pcap_snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Error connecting to host %s, port %s, using protocol %s",
1288 activepars
->address
, activepars
->port
, (hints
.ai_family
== AF_INET
) ? "IPv4":
1289 (hints
.ai_family
== AF_INET6
) ? "IPv6" : "Unspecified");
1291 SOCK_DEBUG_MESSAGE(errbuf
);
1293 sleep_secs(RPCAP_ACTIVE_WAIT
);
1298 activeclose
= daemon_serviceloop(sockctrl
, sockctrl
, 1,
1301 sock_close(sockctrl
, NULL
, 0);
1303 // If the connection is closed by the user explicitely, don't try to connect to it again
1304 // just exit the program
1305 if (activeclose
== 1)
1309 freeaddrinfo(addrinfo
);
1315 // Main routine of a passive-mode service thread.
1317 unsigned __stdcall
main_passive_serviceloop_thread(void *ptr
)
1321 sockctrl
= *((SOCKET
*)ptr
);
1325 // Handle this client.
1326 // This is passive mode, so we don't care whether we were
1327 // told by the client to close.
1329 (void)daemon_serviceloop(sockctrl
, sockctrl
, 0, nullAuthAllowed
);
1331 sock_close(sockctrl
, NULL
, 0);