コード例 #1
0
ファイル: daemon.c プロジェクト: aaqqaaddeerr/dsc
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;
}
コード例 #2
0
ファイル: daemon.c プロジェクト: aaqqaaddeerr/dsc
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;
}
コード例 #3
0
ファイル: daemon.c プロジェクト: DNS-OARC/dsc
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;
}