add winpcap 4.0.2 from url http://www.winpcap.org/
[natblaster.git] / winpcap / wpcap / libpcap / rpcapd / rpcapd.c
blob32f881fd860f9c26e44b37bb9f206d84a80eefbe
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.
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.
37 #include <errno.h> // for the errno variable
38 #include <string.h> // for strtok, etc
39 #include <stdlib.h> // for malloc(), free(), ...
40 #include <pcap.h> // for PCAP_ERRBUF_SIZE
41 #include <signal.h> // for signal()
42 #include <pthread.h>
43 #include "rpcapd.h"
44 #include "fileconf.h" // for the configuration file management
45 #include "pcap-remote.h"
46 #include "daemon.h" // the true main() method of this daemon
47 #include "utils.h" // Missing calls and such
48 #include "sockutils.h" // for socket calls
50 #ifndef WIN32
51 #include <unistd.h> // for exit()
52 #include <sys/wait.h> // waitpid()
53 #else
54 #include "win32-svc.h" // for Win32 service stuff
55 #endif
58 // Global variables
59 char hostlist[MAX_HOST_LIST + 1]; //!< Keeps the list of the hosts that are allowed to connect to this server
60 struct active_pars activelist[MAX_ACTIVE_LIST]; //!< Keeps the list of the hosts (host, port) on which I want to connect to (active mode)
61 int nullAuthAllowed; //!< '1' if we permit NULL authentication, '0' otherwise
62 SOCKET sockmain; //!< keeps the main socket identifier
63 char loadfile[MAX_LINE + 1]; //!< Name of the file from which we have to load the configuration
64 int passivemode= 1; //!< '1' if we want to run in passive mode as well
65 struct addrinfo mainhints; //!< temporary struct to keep settings needed to open the new socket
66 char address[MAX_LINE + 1]; //!< keeps the network address (either numeric or literal) to bind to
67 char port[MAX_LINE + 1]; //!< keeps the network port to bind to
69 extern char *optarg; // for getopt()
73 // Function definition
74 void main_passive(void *ptr);
75 void main_active(void *ptr);
78 #ifndef WIN32
79 void main_cleanup_childs(int sign);
80 #endif
83 /*!
84 \brief Prints the usage screen if it is launched in console mode.
86 void printusage()
88 char *usagetext =
89 "USAGE:\n"
90 " " PROGRAM_NAME " [-b <address>] [-p <port>] [-6] [-l <host_list>] [-a <host,port>]\n"
91 " [-n] [-v] [-d] [-s <file>] [-f <file>]\n"
92 " -b <address>: the address to bind to (either numeric or literal).\n"
93 " Default: it binds to all local IPv4 addresses\n"
94 " -p <port>: the port to bind to. Default: it binds to port " RPCAP_DEFAULT_NETPORT "\n"
95 " -4: use only IPv4 (default both IPv4 and IPv6 waiting sockets are used)\n"
96 " -l <host_list>: a file that keeps the list of the hosts which are allowed\n"
97 " to connect to this server (if more than one, list them one per line).\n"
98 " We suggest to use literal names (instead of numeric ones) in order to\n"
99 " avoid problems with different address families\n"
100 " -n: permit NULL authentication (usually used with '-l')\n"
101 " -a <host,port>: run in active mode when connecting to 'host' on port 'port'\n"
102 " In case 'port' is omitted, the default port (" RPCAP_DEFAULT_NETPORT_ACTIVE ") is used\n"
103 " -v: run in active mode only (default: if '-a' is specified, it accepts\n"
104 " passive connections as well\n"
105 " -d: run in daemon mode (UNIX only) or as a service (Win32 only)\n"
106 " Warning (Win32): this switch is provided automatically when the service\n"
107 " is started from the control panel\n"
108 " -s <file>: save the current configuration to file\n"
109 " -f <file>: load the current configuration from file; all the switches\n"
110 " specified from the command line are ignored\n"
111 " -h: print this help screen\n\n";
113 printf(usagetext);
118 //! Program main
119 int main(int argc, char *argv[], char *envp[])
121 char savefile[MAX_LINE + 1]; // name of the file on which we have to save the configuration
122 int isdaemon= 0; // Not null if the user wants to run this program as a daemon
123 int retval; // keeps the returning value from several functions
124 char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
127 savefile[0]= 0;
128 loadfile[0]= 0;
129 hostlist[0]= 0;
131 // Initialize errbuf
132 memset(errbuf, 0, sizeof(errbuf) );
134 if (sock_init(errbuf, PCAP_ERRBUF_SIZE) == -1)
136 SOCK_ASSERT(errbuf, 1);
137 exit(-1);
140 strncpy(address, RPCAP_DEFAULT_NETADDR, MAX_LINE);
141 strncpy(port, RPCAP_DEFAULT_NETPORT, MAX_LINE);
143 // Prepare to open a new server socket
144 memset(&mainhints, 0, sizeof(struct addrinfo));
146 mainhints.ai_family = PF_UNSPEC;
147 mainhints.ai_flags = AI_PASSIVE; // Ready to a bind() socket
148 mainhints.ai_socktype = SOCK_STREAM;
150 // Getting the proper command line options
151 while ((retval = getopt(argc, argv, "b:dhp:4l:na:s:f:v")) != -1)
153 switch (retval)
155 case 'b':
156 strncpy(address, optarg, MAX_LINE);
157 break;
158 case 'p':
159 strncpy(port, optarg, MAX_LINE);
160 break;
161 case '4':
162 mainhints.ai_family = PF_INET; // IPv4 server only
163 break;
164 case 'd':
165 isdaemon= 1;
166 break;
167 case 'n':
168 nullAuthAllowed= 1;
169 break;
170 case 'v':
171 passivemode= 0;
172 break;
173 case 'l':
175 strncpy(hostlist, optarg, sizeof(hostlist) );
176 break;
178 case 'a':
180 char *tmpaddress, *tmpport;
181 int i= 0;
183 tmpaddress= strtok(optarg, RPCAP_HOSTLIST_SEP);
185 while ( (tmpaddress != NULL) && (i < MAX_ACTIVE_LIST) )
187 tmpport= strtok(NULL, RPCAP_HOSTLIST_SEP);
189 snprintf(activelist[i].address, MAX_LINE, tmpaddress);
191 if ( (tmpport == NULL) || (strcmp(tmpport, "DEFAULT") == 0) ) // the user choose a custom port
192 snprintf(activelist[i].port, MAX_LINE, RPCAP_DEFAULT_NETPORT_ACTIVE);
193 else
194 snprintf(activelist[i].port, MAX_LINE, tmpport);
196 tmpaddress = strtok(NULL, RPCAP_HOSTLIST_SEP);
198 i++;
201 if (i > MAX_ACTIVE_LIST)
202 SOCK_ASSERT("Only MAX_ACTIVE_LIST active connections are currently supported.", 1);
204 // I don't initialize the remaining part of the structure, since
205 // it is already zeroed (it is a global var)
206 break;
208 case 'f':
209 strncpy(loadfile, optarg, MAX_LINE);
210 break;
211 case 's':
212 strncpy(savefile, optarg, MAX_LINE);
213 break;
214 case 'h':
215 printusage();
216 exit(0);
217 default:
218 break;
222 if (savefile[0])
224 if (fileconf_save(savefile) )
225 SOCK_ASSERT("Error when saving the configuration to file", 1);
228 // If the file does not exist, it keeps the settings provided by the command line
229 if (loadfile[0])
230 fileconf_read(0);
232 #ifdef linux
233 // SIGTERM (i.e. kill -15) is not generated in WIN32, although it is included for ANSI compatibility
234 signal(SIGTERM, main_cleanup);
235 signal(SIGCHLD, main_cleanup_childs);
236 #endif
238 // forking a daemon, if it is needed
239 if (isdaemon)
241 #ifndef WIN32
242 int pid;
244 // Unix Network Programming, pg 336
245 if ( (pid = fork() ) != 0)
246 exit(0); // Parent terminates
248 // First child continues
249 // Set daemon mode
250 setsid();
252 // generated under unix with 'kill -HUP', needed to reload the configuration
253 signal(SIGHUP, fileconf_read);
255 if ( (pid = fork() ) != 0)
256 exit(0); // First child terminates
258 // LINUX WARNING: the current linux implementation of pthreads requires a management thread
259 // to handle some hidden stuff. So, as soon as you create the first thread, two threads are
260 // created. Fom this point on, the number of threads active are always one more compared
261 // to the number you're expecting
263 // Second child continues
264 // umask(0);
265 // chdir("/");
266 #else
267 // We use the SIGABRT signal to kill the Win32 service
268 signal(SIGABRT, main_cleanup);
270 // If this call succeeds, it is blocking on Win32
271 if ( svc_start() != 1)
272 SOCK_ASSERT(1, "Unable to start the service");
274 // When the previous call returns, the entire application has to be stopped.
275 exit(0);
276 #endif
278 else // Console mode
280 // Enable the catching of Ctrl+C
281 signal(SIGINT, main_cleanup);
283 #ifndef WIN32
284 // generated under unix with 'kill -HUP', needed to reload the configuration
285 // We do not have this kind of signal in Win32
286 signal(SIGHUP, fileconf_read);
287 #endif
289 printf("Press CTRL + C to stop the server...\n");
292 // If we're a Win32 service, we have already called this function in the service_main
293 main_startup();
295 // The code should never arrive here (since the main_startup is blocking)
296 // however this avoids a compiler warning
297 exit(0);
302 void main_startup(void)
304 char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
305 struct addrinfo *addrinfo; // keeps the addrinfo chain; required to open a new socket
306 int i;
307 #ifdef WIN32
308 pthread_t threadId; // Pthread variable that keeps the thread structures
309 pthread_attr_t detachedAttribute; // PThread attribute needed to create the thread as detached
310 #else
311 pid_t pid;
312 #endif
314 i= 0;
315 addrinfo= NULL;
316 memset(errbuf, 0, sizeof(errbuf) );
318 // Starts all the active threads
319 while ( (activelist[i].address[0] != 0) && (i < MAX_ACTIVE_LIST) )
321 activelist[i].ai_family= mainhints.ai_family;
323 #ifdef WIN32
324 /* GV we need this to create the thread as detached. */
325 /* GV otherwise, the thread handle is not destroyed */
326 pthread_attr_init(&detachedAttribute);
327 pthread_attr_setdetachstate(&detachedAttribute, PTHREAD_CREATE_DETACHED);
329 if ( pthread_create( &threadId, &detachedAttribute, (void *) &main_active, (void *) &activelist[i]) )
331 SOCK_ASSERT("Error creating the active child thread", 1);
332 pthread_attr_destroy(&detachedAttribute);
333 continue;
335 pthread_attr_destroy(&detachedAttribute);
336 #else
337 if ( (pid= fork() ) == 0) // I am the child
339 main_active( (void *) &activelist[i]);
340 exit(0);
342 #endif
343 i++;
347 The code that manages the active connections is not blocking;
348 vice versa, the code that manages the passive connection is blocking.
349 So, if the user do not want to run in passive mode, we have to block
350 the main thread here, otherwise the program ends and all threads
351 are stopped.
353 WARNING: this means that in case we have only active mode, the program does
354 not terminate even if all the child thread terminates. The user has always to
355 press Ctrl+C (or send a SIGTERM) to terminate the program.
358 if (passivemode)
360 struct addrinfo *tempaddrinfo;
362 // Do the work
363 if (sock_initaddress((address[0]) ? address : NULL, port, &mainhints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
365 SOCK_ASSERT(errbuf, 1);
366 return;
369 tempaddrinfo= addrinfo;
371 while (tempaddrinfo)
373 SOCKET *socktemp;
375 if ( (sockmain= sock_open(tempaddrinfo, SOCKOPEN_SERVER, SOCKET_MAXCONN, errbuf, PCAP_ERRBUF_SIZE)) == -1)
377 SOCK_ASSERT(errbuf, 1);
378 tempaddrinfo= tempaddrinfo->ai_next;
379 continue;
382 // This trick is needed in order to allow the child thread to save the 'sockmain' variable
383 // withouth getting it overwritten by the sock_open, in case we want to open more than one waiting sockets
384 // For instance, the pthread_create() will accept the socktemp variable, and it will deallocate immediately that variable
385 socktemp= (SOCKET *) malloc (sizeof (SOCKET));
386 if (socktemp == NULL)
387 exit(0);
389 *socktemp= sockmain;
391 #ifdef WIN32
392 /* GV we need this to create the thread as detached. */
393 /* GV otherwise, the thread handle is not destroyed */
394 pthread_attr_init(&detachedAttribute);
395 pthread_attr_setdetachstate(&detachedAttribute, PTHREAD_CREATE_DETACHED);
397 if ( pthread_create( &threadId, &detachedAttribute, (void *) &main_passive, (void *) socktemp ) )
399 SOCK_ASSERT("Error creating the passive child thread", 1);
400 pthread_attr_destroy(&detachedAttribute);
401 continue;
404 pthread_attr_destroy(&detachedAttribute);
405 #else
406 if ( (pid= fork() ) == 0) // I am the child
408 main_passive( (void *) socktemp);
409 return;
411 #endif
412 tempaddrinfo= tempaddrinfo->ai_next;
415 freeaddrinfo(addrinfo);
418 // All the previous calls are no blocking, so the main line of execution goes here
419 // and I have to avoid that the program terminates
420 while (1)
421 pthread_suspend(10*60*1000); // it wakes up every 10 minutes; it seems to me reasonable
426 \brief Closes gracefully (more or less) the program.
428 This function is called:
429 - when we're running in console
430 - when we're running as a Win32 service (in case we press STOP)
432 It is not called when we are running as a daemon on UNIX, since
433 we do not define a signal in order to terminate gracefully the daemon.
435 This function makes a fast cleanup (it does not clean everything, as
436 you can see from the fact that it uses kill() on UNIX), closes
437 the main socket, free winsock resources (on Win32) and exits the
438 program.
440 void main_cleanup(int sign)
442 #ifndef WIN32
443 // Sends a KILL signal to all the processes
444 // that share the same process group (i.e. kills all the childs)
445 kill(0, SIGKILL);
446 #endif
448 SOCK_ASSERT(PROGRAM_NAME " is closing.\n", 1);
450 // FULVIO (bug)
451 // Here we close only the latest 'sockmain' created; if we opened more than one waiting sockets,
452 // only the latest one is closed correctly.
453 if (sockmain)
454 closesocket(sockmain);
455 sock_cleanup();
458 This code is executed under the following conditions:
459 - SIGTERM: we're under UNIX, and the user kills us with 'kill -15'
460 (no matter is we're a daemon or in a console mode)
461 - SIGINT: we're in console mode and the user sends us a Ctrl+C
462 (SIGINT signal), no matter if we're UNIX or Win32
464 In all these cases, we have to terminate the program.
465 The case that still remains is if we're a Win32 service: in this case,
466 we're a child thread, and we want just to terminate ourself. This is because
467 the exit(0) will be invoked by the main thread, which is blocked waiting that
468 all childs terminates. We are forced to call exit from the main thread otherwise
469 the Win32 service control manager (SCM) does not work well.
471 if ( (sign == SIGTERM) || (sign == SIGINT) )
472 exit(0);
473 else
474 return;
479 #ifdef linux
481 void main_cleanup_childs(int sign)
483 pid_t pid;
484 int stat;
486 // For reference, Stevens, pg 128
488 while ( (pid= waitpid(-1, &stat, WNOHANG) ) > 0)
489 SOCK_ASSERT("Child terminated", 1);
491 return;
494 #endif
501 \brief 'true' main of the program.
503 It must be in a separate function because:
504 - if we're in 'console' mode, we have to put the main thread waiting for a Ctrl+C
505 (in order to be able to stop everything)
506 - if we're in daemon mode, the main program must terminate and a new child must be
507 created in order to create the daemon
509 \param ptr: it keeps the main socket handler (what's called 'sockmain' in the main() ), that
510 represents the socket used in the main connection. It is a 'void *' just because pthreads
511 want this format.
513 void main_passive(void *ptr)
515 char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
516 SOCKET sockctrl; // keeps the socket ID for this control connection
517 struct sockaddr_storage from; // generic sockaddr_storage variable
518 socklen_t fromlen; // keeps the length of the sockaddr_storage variable
519 SOCKET sockmain;
521 #ifndef WIN32
522 pid_t pid;
523 #endif
525 sockmain= *((SOCKET *) ptr);
527 // Delete the pointer (which has been allocated in the main)
528 free(ptr);
530 // Initialize errbuf
531 memset(errbuf, 0, sizeof(errbuf) );
533 // main thread loop
534 while (1)
536 #ifdef WIN32
537 pthread_t threadId; // Pthread variable that keeps the thread structures
538 pthread_attr_t detachedAttribute;
539 #endif
540 struct daemon_slpars *pars; // parameters needed by the daemon_serviceloop()
542 // Connection creation
543 fromlen = sizeof(struct sockaddr_storage);
545 sockctrl= accept(sockmain, (struct sockaddr *) &from, &fromlen);
547 if (sockctrl == -1)
549 // The accept() call can return this error when a signal is catched
550 // In this case, we have simply to ignore this error code
551 // Stevens, pg 124
552 #ifdef WIN32
553 if (WSAGetLastError() == WSAEINTR)
554 #else
555 if (errno == EINTR)
556 #endif
557 continue;
559 // Don't check for errors here, since the error can be due to the fact that the thread
560 // has been killed
561 sock_geterror("accept(): ", errbuf, PCAP_ERRBUF_SIZE);
562 SOCK_ASSERT(errbuf, 1);
563 continue;
566 // checks if the connecting host is among the ones allowed
567 if (sock_check_hostlist(hostlist, RPCAP_HOSTLIST_SEP, &from, errbuf, PCAP_ERRBUF_SIZE) < 0 )
569 rpcap_senderror(sockctrl, errbuf, PCAP_ERR_HOSTNOAUTH, NULL);
570 sock_close(sockctrl, NULL, 0);
571 continue;
575 #ifdef WIN32
576 // in case of passive mode, this variable is deallocated by the daemon_serviceloop()
577 pars= (struct daemon_slpars *) malloc ( sizeof(struct daemon_slpars) );
578 if (pars == NULL)
580 snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno));
581 continue;
584 pars->sockctrl= sockctrl;
585 pars->activeclose= 0; // useless in passive mode
586 pars->isactive= 0;
587 pars->nullAuthAllowed= nullAuthAllowed;
589 /* GV we need this to create the thread as detached. */
590 /* GV otherwise, the thread handle is not destroyed */
591 pthread_attr_init(&detachedAttribute);
592 pthread_attr_setdetachstate(&detachedAttribute, PTHREAD_CREATE_DETACHED);
593 if ( pthread_create( &threadId, &detachedAttribute, (void *) &daemon_serviceloop, (void *) pars) )
595 SOCK_ASSERT("Error creating the child thread", 1);
596 pthread_attr_destroy(&detachedAttribute);
597 continue;
599 pthread_attr_destroy(&detachedAttribute);
601 #else
602 if ( (pid= fork() ) == 0) // I am the child
604 // in case of passive mode, this variable is deallocated by the daemon_serviceloop()
605 pars= (struct daemon_slpars *) malloc ( sizeof(struct daemon_slpars) );
606 if (pars == NULL)
608 snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno));
609 exit(0);
612 pars->sockctrl= sockctrl;
613 pars->activeclose= 0; // useless in passive mode
614 pars->isactive= 0;
615 pars->nullAuthAllowed= nullAuthAllowed;
617 // Close the main socket (must be open only in the parent)
618 closesocket(sockmain);
620 daemon_serviceloop( (void *) pars);
621 exit(0);
624 // I am the parent
625 // Close the childsocket (must be open only in the child)
626 closesocket(sockctrl);
627 #endif
629 // loop forever, until interrupted
637 \brief 'true' main of the program in case the active mode is turned on.
639 It does not have any return value nor parameters.
640 This function loops forever trying to connect to the remote host, until the
641 daemon is turned down.
643 \param ptr: it keeps the 'activepars' parameters. It is a 'void *' just because pthreads
644 want this format.
646 void main_active(void *ptr)
648 char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
649 SOCKET sockctrl; // keeps the socket ID for this control connection
650 struct addrinfo hints; // temporary struct to keep settings needed to open the new socket
651 struct addrinfo *addrinfo; // keeps the addrinfo chain; required to open a new socket
652 struct active_pars *activepars;
653 struct daemon_slpars *pars; // parameters needed by the daemon_serviceloop()
656 activepars= (struct active_pars *) ptr;
658 // Prepare to open a new server socket
659 memset(&hints, 0, sizeof(struct addrinfo));
660 // WARNING Currently it supports only ONE socket family among IPv4 and IPv6
661 hints.ai_family = AF_INET; // PF_UNSPEC to have both IPv4 and IPv6 server
662 hints.ai_socktype = SOCK_STREAM;
663 hints.ai_family= activepars->ai_family;
665 snprintf(errbuf, PCAP_ERRBUF_SIZE, "Connecting to host %s, port %s, using protocol %s",
666 activepars->address, activepars->port, (hints.ai_family == AF_INET) ? "IPv4":
667 (hints.ai_family == AF_INET6) ? "IPv6" : "Unspecified");
668 SOCK_ASSERT(errbuf, 1);
670 // Initialize errbuf
671 memset(errbuf, 0, sizeof(errbuf) );
673 // Do the work
674 if (sock_initaddress(activepars->address, activepars->port, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
676 SOCK_ASSERT(errbuf, 1);
677 return;
680 while (1)
682 int activeclose;
684 if ( (sockctrl= sock_open(addrinfo, SOCKOPEN_CLIENT, 0, errbuf, PCAP_ERRBUF_SIZE)) == -1)
686 SOCK_ASSERT(errbuf, 1);
688 snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error connecting to host %s, port %s, using protocol %s",
689 activepars->address, activepars->port, (hints.ai_family == AF_INET) ? "IPv4":
690 (hints.ai_family == AF_INET6) ? "IPv6" : "Unspecified" );
692 SOCK_ASSERT(errbuf, 1);
694 pthread_suspend(RPCAP_ACTIVE_WAIT * 1000);
696 continue;
699 pars= (struct daemon_slpars *) malloc ( sizeof(struct daemon_slpars) );
700 if (pars == NULL)
702 snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno));
703 continue;
706 pars->sockctrl= sockctrl;
707 pars->activeclose= 0;
708 pars->isactive= 1;
709 pars->nullAuthAllowed= nullAuthAllowed;
711 daemon_serviceloop( (void *) pars);
713 activeclose= pars->activeclose;
715 free(pars);
717 // If the connection is closed by the user explicitely, don't try to connect to it again
718 // just exit the program
719 if (activeclose == 1)
720 break;