int main(int argc, char *argv[]) { int x; extern DMC dns_message_handle; int result; struct timeval break_start = {0,0}; progname = xstrdup(strrchr(argv[0], '/') ? strchr(argv[0], '/') + 1 : argv[0]); if (NULL == progname) return 1; srandom(time(NULL)); openlog(progname, LOG_PID | LOG_NDELAY, LOG_DAEMON); while ((x = getopt(argc, argv, "fpd")) != -1) { switch (x) { case 'f': nodaemon_flag = 1; break; case 'p': promisc_flag = 0; break; case 'd': debug_flag++; nodaemon_flag = 1; break; default: usage(); break; } } argc -= optind; argv += optind; if (argc != 1) usage(); dns_message_init(); ParseConfig(argv[0]); cip_net_indexer_init(); if (!nodaemon_flag) daemonize(); write_pid_file(); if (!debug_flag) { syslog(LOG_INFO, "Sleeping for %d seconds", 60 - (int) (time(NULL) % 60)); sleep(60 - (time(NULL) % 60)); } syslog(LOG_INFO, "%s", "Running"); do { useArena(); /* Initialize a memory arena for data collection. */ if (debug_flag && break_start.tv_sec > 0) { struct timeval now; gettimeofday(&now, NULL); syslog(LOG_INFO, "inter-run processing delay: %ld ms", (now.tv_usec - break_start.tv_usec) / 1000 + 1000 * (now.tv_sec - break_start.tv_sec)); } #if HAVE_LIBNCAP result = Ncap_run(dns_message_handle, ip_message_handle); #else result = Pcap_run(dns_message_handle, ip_message_handle); #endif if (debug_flag) gettimeofday(&break_start, NULL); if (0 == fork()) { dump_reports(); _exit(0); } /* Parent quickly frees and clears its copy of the data so it can resume processing packets. */ freeArena(); dns_message_clear_arrays(); ip_message_clear_arrays(); { /* Reap children. (Most recent probably has not exited yet, but * older ones should have.) */ int cstatus = 0; pid_t pid; while ((pid = waitpid(0, &cstatus, WNOHANG)) > 0) { if (WIFSIGNALED(cstatus)) syslog(LOG_NOTICE, "child %d exited with signal %d", pid, WTERMSIG(cstatus)); if (WIFEXITED(cstatus) && WEXITSTATUS(cstatus) != 0) syslog(LOG_NOTICE, "child %d exited with status %d", pid, WEXITSTATUS(cstatus)); } } } while (result > 0 && debug_flag == 0); #if HAVE_LIBNCAP Ncap_close(); #else Pcap_close(); #endif return 0; }
int main(int argc, char *argv[]) { int x; extern DMC dns_message_handle; progname = xstrdup(strrchr(argv[0], '/') ? strchr(argv[0], '/') + 1 : argv[0]); if (NULL == progname) return 1; srandom(time(NULL)); openlog(progname, LOG_PID | LOG_NDELAY, LOG_DAEMON); while ((x = getopt(argc, argv, "pd")) != -1) { switch (x) { case 'p': promisc_flag = 0; break; case 'd': debug_flag = 1; break; default: usage(); break; } } argc -= optind; argv += optind; if (argc != 1) usage(); dns_message_init(); ParseConfig(argv[0]); cip_net_indexer_init(); if (!debug_flag) daemonize(); write_pid_file(); /* * I'm using fork() in this loop, (a) out of laziness, and (b) * because I'm worried we might drop packets. Making sure each * child collector runs for a small amount of time (60 secodns) * means I can be lazy about memory management (leaks). To * minimize the chance for dropped packets, I'd like to spawn * a new collector as soon as (or even before) the current * collector exits. */ if (!debug_flag) { syslog(LOG_INFO, "Sleeping for %d seconds", 60 - (int) (time(NULL) % 60)); sleep(60 - (time(NULL) % 60)); } syslog(LOG_INFO, "Running"); for (;;) { pid_t cpid = fork(); if (0 == cpid) { Pcap_run(dns_message_handle, ip_message_handle); if (0 == fork()) { dns_message_report(); ip_message_report(); } _exit(0); } else { int cstatus = 0; syslog(LOG_DEBUG, "waiting for child pid %d", (int) cpid); while (waitpid(cpid, &cstatus, 0) < 0) (void) 0; if (WIFSIGNALED(cstatus)) syslog(LOG_NOTICE, "child exited with signal %d, status %d", WTERMSIG(cstatus), WEXITSTATUS(cstatus)); } if (debug_flag) break; } Pcap_close(); return 0; }
int main(int argc, char *argv[]) { int x; int result; struct timeval break_start = { 0, 0 }; struct sigaction action; progname = xstrdup(strrchr(argv[0], '/') ? strchr(argv[0], '/') + 1 : argv[0]); if (NULL == progname) return 1; srandom(time(NULL)); openlog(progname, LOG_PID | LOG_NDELAY, LOG_DAEMON); while ((x = getopt(argc, argv, "fpdvmiT")) != -1) { switch (x) { case 'f': nodaemon_flag = 1; break; case 'p': promisc_flag = 0; break; case 'd': debug_flag++; nodaemon_flag = 1; break; case 'm': monitor_flag = 1; break; case 'i': immediate_flag = 1; break; case 'T': threads_flag = 0; break; case 'v': version(); default: usage(); break; } } argc -= optind; argv += optind; if (argc != 1) usage(); if (!promisc_flag) dsyslog(LOG_INFO, "disabling interface promiscuous mode"); if (monitor_flag) dsyslog(LOG_INFO, "enabling interface monitor mode"); if (immediate_flag) dsyslog(LOG_INFO, "enabling interface immediate mode"); if (!threads_flag) dsyslog(LOG_INFO, "disabling usage of threads in pcap thread"); dns_message_init(); if (parse_conf(argv[0])) { return 1; } #if HAVE_LIBGEOIP country_indexer_init(); asn_indexer_init(); #endif cip_net_indexer_init(); if ( !output_format_xml && !output_format_json ) { output_format_xml = 1; } /* * Do not damonize if we only have offline files */ if (n_pcap_offline) { nodaemon_flag = 1; } if (!nodaemon_flag) daemonize(); write_pid_file(); /* * Install signal handler for signals to ignore */ memset(&action, 0, sizeof(action)); action.sa_handler = sig_ignore; sigfillset(&action.sa_mask); if (sigaction(SIGHUP, &action, NULL)) dsyslogf(LOG_ERR, "Unable to install signal handler for SIGHUP: %s", strerror(errno)); if (sigaction(SIGCHLD, &action, NULL)) dsyslogf(LOG_ERR, "Unable to install signal handler for SIGCHLD: %s", strerror(errno)); if (sigaction(SIGPIPE, &action, NULL)) dsyslogf(LOG_ERR, "Unable to install signal handler for SIGPIPE: %s", strerror(errno)); if (sigaction(SIGUSR1, &action, NULL)) dsyslogf(LOG_ERR, "Unable to install signal handler for SIGUSR1: %s", strerror(errno)); if (sigaction(SIGUSR2, &action, NULL)) dsyslogf(LOG_ERR, "Unable to install signal handler for SIGUSR2: %s", strerror(errno)); /* * Do not ignore SIGINT if we are running in the foreground */ if (!nodaemon_flag && sigaction(SIGINT, &action, NULL)) dsyslogf(LOG_ERR, "Unable to install signal handler for SIGINT: %s", strerror(errno)); /* * Install signal handler for signals to exit on */ if (dump_reports_on_exit) action.sa_handler = sig_exit_dumping; else action.sa_handler = sig_exit; if (sigaction(SIGTERM, &action, NULL)) dsyslogf(LOG_ERR, "Unable to install signal handler for SIGTERM: %s", strerror(errno)); if (sigaction(SIGQUIT, &action, NULL)) dsyslogf(LOG_ERR, "Unable to install signal handler for SIGQUIT: %s", strerror(errno)); if (!debug_flag && 0 == n_pcap_offline) { dsyslogf(LOG_INFO, "Sleeping for %ld seconds", statistics_interval - (int) (time(NULL) % statistics_interval)); sleep(statistics_interval - (time(NULL) % statistics_interval)); } dsyslog(LOG_INFO, "Running"); do { useArena(); /* Initialize a memory arena for data collection. */ if (debug_flag && break_start.tv_sec > 0) { struct timeval now; gettimeofday(&now, NULL); dsyslogf(LOG_INFO, "inter-run processing delay: %ld ms", (now.tv_usec - break_start.tv_usec) / 1000 + 1000 * (now.tv_sec - break_start.tv_sec)); } /* Indicate we might have reports to dump on exit */ have_reports = 1; result = Pcap_run(); if (debug_flag) gettimeofday(&break_start, NULL); if (0 == fork()) { dump_reports(); _exit(0); } if (sig_while_processing) { dsyslogf(LOG_INFO, "Received signal %d before, exiting now", sig_while_processing); exit(0); } have_reports = 0; /* Parent quickly frees and clears its copy of the data so it can * resume processing packets. */ freeArena(); dns_message_clear_arrays(); { /* Reap children. (Most recent probably has not exited yet, but * older ones should have.) */ int cstatus = 0; pid_t pid; while ((pid = waitpid(0, &cstatus, WNOHANG)) > 0) { if (WIFSIGNALED(cstatus)) dsyslogf(LOG_NOTICE, "child %d exited with signal %d", pid, WTERMSIG(cstatus)); if (WIFEXITED(cstatus) && WEXITSTATUS(cstatus) != 0) dsyslogf(LOG_NOTICE, "child %d exited with status %d", pid, WEXITSTATUS(cstatus)); } } } while (result > 0 && debug_flag == 0); Pcap_close(); return 0; }