int run() { // Returns // 0 - Success // -1 - API mode looks down on ofline captures. // -2 - api_max_con makes sense only with api_sock. // -3 - Daemon mode and offline captures don't mix. // -4 - Daemon mode requires log_file or api_sock. // -5 - [!] Note: under cygwin, switch_user is largely useless // -6 - [!] Consider specifying switch_user in daemon mode (see README) int ret = 0; if (read_file && api_sock) { printf("\nFATAL: API mode looks down on ofline captures"); ret = -1; } if (!api_sock && api_max_conn != API_MAX_CONN) { printf("\nFATAL: api_max_con makes sense only with api_sock."); ret = -2; } if (daemon_mode) { if (read_file) { printf("\nFATAL: Daemon mode and offline captures don't mix."); ret = -3; } if (!log_file && !api_sock) { printf("\nFATAL: Daemon mode requires log_file or api_sock."); ret = -4; } #ifdef __CYGWIN__ if (switch_user) { printf("\n[!] Note: under cygwin, switch_user is largely useless"); ret = -5; } #else if (!switch_user) { printf("\n[!] Consider specifying switch_user in daemon mode (see README)"); ret = -6; } #endif /* ^__CYGWIN__ */ } tzset(); setlocale(LC_TIME, "C"); close_spare_fds(); get_hash_seed(); http_init(); read_config(fp_file ? fp_file : (u8*)FP_FILE); prepare_pcap(); prepare_bpf(); if (log_file) open_log(); if (api_sock) open_api(); if (daemon_mode) { null_fd = open("/dev/null", O_RDONLY); if (null_fd < 0) printf("\nFATAL: Cannot open '/dev/null'."); } if (switch_user) drop_privs(); if (daemon_mode) fork_off(); signal(SIGHUP, daemon_mode ? SIG_IGN : abort_handler); signal(SIGINT, abort_handler); signal(SIGTERM, abort_handler); if (read_file) offline_event_loop(); else live_event_loop(); if (!daemon_mode) printf("\nAll done. Processed %llu packets.\n", packet_cnt); #ifdef DEBUG_BUILD destroy_all_hosts(); TRK_report(); #endif /* DEBUG_BUILD */ return ret; }
int main(int argc, char** argv) { s32 r; setlinebuf(stdout); SAYF("--- p0f " VERSION " by Michal Zalewski <*****@*****.**> ---\n\n"); if (getuid() != geteuid()) FATAL("Please don't make me setuid. See README for more.\n"); while ((r = getopt(argc, argv, "+LS:df:i:m:o:pr:s:t:u:")) != -1) switch (r) { case 'L': list_interfaces(); exit(0); case 'S': #ifdef __CYGWIN__ FATAL("API mode not supported on Windows (see README)."); #else if (api_max_conn != API_MAX_CONN) FATAL("Multiple -S options not supported."); api_max_conn = atol(optarg); if (!api_max_conn || api_max_conn > 100) FATAL("Outlandish value specified for -S."); break; #endif /* ^__CYGWIN__ */ case 'd': if (daemon_mode) FATAL("Double werewolf mode not supported yet."); daemon_mode = 1; break; case 'f': if (fp_file) FATAL("Multiple -f options not supported."); fp_file = (u8*)optarg; break; case 'i': if (use_iface) FATAL("Multiple -i options not supported (try '-i any')."); use_iface = (u8*)optarg; break; case 'm': if (max_conn != MAX_CONN || max_hosts != MAX_HOSTS) FATAL("Multiple -m options not supported."); if (sscanf(optarg, "%u,%u", &max_conn, &max_hosts) != 2 || !max_conn || max_conn > 100000 || !max_hosts || max_hosts > 500000) FATAL("Outlandish value specified for -m."); break; case 'o': if (log_file) FATAL("Multiple -o options not supported."); log_file = (u8*)optarg; break; case 'p': if (set_promisc) FATAL("Even more promiscuous? People will call me slutty!"); set_promisc = 1; break; case 'r': if (read_file) FATAL("Multiple -r options not supported."); read_file = (u8*)optarg; break; case 's': #ifdef __CYGWIN__ FATAL("API mode not supported on Windows (see README)."); #else if (api_sock) FATAL("Multiple -s options not supported."); api_sock = (u8*)optarg; break; #endif /* ^__CYGWIN__ */ case 't': if (conn_max_age != CONN_MAX_AGE || host_idle_limit != HOST_IDLE_LIMIT) FATAL("Multiple -t options not supported."); if (sscanf(optarg, "%u,%u", &conn_max_age, &host_idle_limit) != 2 || !conn_max_age || conn_max_age > 1000000 || !host_idle_limit || host_idle_limit > 1000000) FATAL("Outlandish value specified for -t."); break; case 'u': if (switch_user) FATAL("Split personality mode not supported."); switch_user = (u8*)optarg; break; default: usage(); } if (optind < argc) { if (optind + 1 == argc) orig_rule = (u8*)argv[optind]; else FATAL("Filter rule must be a single parameter (use quotes)."); } if (read_file && api_sock) FATAL("API mode looks down on ofline captures."); if (!api_sock && api_max_conn != API_MAX_CONN) FATAL("Option -S makes sense only with -s."); if (daemon_mode) { if (read_file) FATAL("Daemon mode and offline captures don't mix."); if (!log_file && !api_sock) FATAL("Daemon mode requires -o or -s."); #ifdef __CYGWIN__ if (switch_user) SAYF("[!] Note: under cygwin, -u is largely useless.\n"); #else if (!switch_user) SAYF("[!] Consider specifying -u in daemon mode (see README).\n"); #endif /* ^__CYGWIN__ */ } tzset(); setlocale(LC_TIME, "C"); close_spare_fds(); get_hash_seed(); http_init(); read_config(fp_file ? fp_file : (u8*)FP_FILE); prepare_pcap(); prepare_bpf(); if (log_file) open_log(); if (api_sock) open_api(); if (daemon_mode) { null_fd = open("/dev/null", O_RDONLY); if (null_fd < 0) PFATAL("Cannot open '/dev/null'."); } if (switch_user) drop_privs(); if (daemon_mode) fork_off(); signal(SIGHUP, daemon_mode ? SIG_IGN : abort_handler); signal(SIGINT, abort_handler); signal(SIGTERM, abort_handler); if (read_file) offline_event_loop(); else live_event_loop(); if (!daemon_mode) SAYF("\nAll done. Processed %llu packets.\n", packet_cnt); #ifdef DEBUG_BUILD destroy_all_hosts(); TRK_report(); #endif /* DEBUG_BUILD */ return 0; }