libpcap  1.10.1
About: libpcap is a packet filter library used by tools like tcpdump.
  Fossies Dox: libpcap-1.10.1.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

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