int main(int argc, char **argv) { char *ptr; int c, i, j, cpu_tmp, opt_index, ops_touched = 0, vals[4] = {0}; bool prio_high = false, setsockmem = true; void (*main_loop)(struct ctx *ctx) = NULL; struct ctx ctx = { .link_type = LINKTYPE_EN10MB, .print_mode = PRINT_NORM, .cpu = -1, .packet_type = -1, .promiscuous = true, .randomize = false, .pcap = PCAP_OPS_SG, .dump_interval = 60, .dump_mode = DUMP_INTERVAL_TIME, .uid = getuid(), .gid = getgid(), .magic = ORIGINAL_TCPDUMP_MAGIC, }; srand(time(NULL)); while ((c = getopt_long(argc, argv, short_options, long_options, &opt_index)) != EOF) { switch (c) { case 'd': case 'i': ctx.device_in = xstrdup(optarg); break; case 'o': ctx.device_out = xstrdup(optarg); break; case 'P': ctx.prefix = xstrdup(optarg); break; case 'R': ctx.link_type = LINKTYPE_IEEE802_11; ctx.rfraw = 1; break; case 'r': ctx.randomize = true; break; case 'J': ctx.jumbo = true; break; case 'T': ctx.magic = (uint32_t) strtoul(optarg, NULL, 0); pcap_check_magic(ctx.magic); break; case 'f': ctx.filter = xstrdup(optarg); break; case 'M': ctx.promiscuous = false; break; case 'A': setsockmem = false; break; case 'u': ctx.uid = strtoul(optarg, NULL, 0); ctx.enforce = true; break; case 'g': ctx.gid = strtoul(optarg, NULL, 0); ctx.enforce = true; break; case 't': if (!strncmp(optarg, "host", strlen("host"))) ctx.packet_type = PACKET_HOST; else if (!strncmp(optarg, "broadcast", strlen("broadcast"))) ctx.packet_type = PACKET_BROADCAST; else if (!strncmp(optarg, "multicast", strlen("multicast"))) ctx.packet_type = PACKET_MULTICAST; else if (!strncmp(optarg, "others", strlen("others"))) ctx.packet_type = PACKET_OTHERHOST; else if (!strncmp(optarg, "outgoing", strlen("outgoing"))) ctx.packet_type = PACKET_OUTGOING; else ctx.packet_type = -1; break; case 'S': ptr = optarg; ctx.reserve_size = 0; for (j = i = strlen(optarg); i > 0; --i) { if (!isdigit(optarg[j - i])) break; ptr++; } if (!strncmp(ptr, "KiB", strlen("KiB"))) ctx.reserve_size = 1 << 10; else if (!strncmp(ptr, "MiB", strlen("MiB"))) ctx.reserve_size = 1 << 20; else if (!strncmp(ptr, "GiB", strlen("GiB"))) ctx.reserve_size = 1 << 30; else panic("Syntax error in ring size param!\n"); *ptr = 0; ctx.reserve_size *= strtol(optarg, NULL, 0); break; case 'b': cpu_tmp = strtol(optarg, NULL, 0); cpu_affinity(cpu_tmp); if (ctx.cpu != -2) ctx.cpu = cpu_tmp; break; case 'H': prio_high = true; break; case 'c': ctx.pcap = PCAP_OPS_RW; ops_touched = 1; break; case 'm': ctx.pcap = PCAP_OPS_MM; ops_touched = 1; break; case 'G': ctx.pcap = PCAP_OPS_SG; ops_touched = 1; break; case 'Q': ctx.cpu = -2; break; case 's': ctx.print_mode = PRINT_NONE; break; case 'q': ctx.print_mode = PRINT_LESS; break; case 'X': ctx.print_mode = (ctx.print_mode == PRINT_ASCII) ? PRINT_HEX_ASCII : PRINT_HEX; break; case 'l': ctx.print_mode = (ctx.print_mode == PRINT_HEX) ? PRINT_HEX_ASCII : PRINT_ASCII; break; case 'k': ctx.kpull = strtol(optarg, NULL, 0); break; case 'n': frame_count_max = strtol(optarg, NULL, 0); break; case 'F': ptr = optarg; ctx.dump_interval = 0; for (j = i = strlen(optarg); i > 0; --i) { if (!isdigit(optarg[j - i])) break; ptr++; } if (!strncmp(ptr, "KiB", strlen("KiB"))) { ctx.dump_interval = 1 << 10; ctx.dump_mode = DUMP_INTERVAL_SIZE; } else if (!strncmp(ptr, "MiB", strlen("MiB"))) { ctx.dump_interval = 1 << 20; ctx.dump_mode = DUMP_INTERVAL_SIZE; } else if (!strncmp(ptr, "GiB", strlen("GiB"))) { ctx.dump_interval = 1 << 30; ctx.dump_mode = DUMP_INTERVAL_SIZE; } else if (!strncmp(ptr, "sec", strlen("sec"))) { ctx.dump_interval = 1; ctx.dump_mode = DUMP_INTERVAL_TIME; } else if (!strncmp(ptr, "min", strlen("min"))) { ctx.dump_interval = 60; ctx.dump_mode = DUMP_INTERVAL_TIME; } else if (!strncmp(ptr, "hrs", strlen("hrs"))) { ctx.dump_interval = 60 * 60; ctx.dump_mode = DUMP_INTERVAL_TIME; } else if (!strncmp(ptr, "s", strlen("s"))) { ctx.dump_interval = 1; ctx.dump_mode = DUMP_INTERVAL_TIME; } else { panic("Syntax error in time/size param!\n"); } *ptr = 0; ctx.dump_interval *= strtol(optarg, NULL, 0); break; case 'V': ctx.verbose = 1; break; case 'B': ctx.dump_bpf = true; break; case 'D': pcap_dump_type_features(); die(); break; case 'U': update_geoip(); die(); break; case 'v': version(); break; case 'h': help(); break; case '?': switch (optopt) { case 'd': case 'i': case 'o': case 'f': case 't': case 'P': case 'F': case 'n': case 'S': case 'b': case 'k': case 'T': case 'u': case 'g': case 'e': panic("Option -%c requires an argument!\n", optopt); default: if (isprint(optopt)) printf("Unknown option character `0x%X\'!\n", optopt); die(); } default: break; } } if (!ctx.filter && optind != argc) { int ret; off_t offset = 0; for (i = optind; i < argc; ++i) { size_t alen = strlen(argv[i]) + 2; size_t flen = ctx.filter ? strlen(ctx.filter) : 0; ctx.filter = xrealloc(ctx.filter, 1, flen + alen); ret = slprintf(ctx.filter + offset, strlen(argv[i]) + 2, "%s ", argv[i]); if (ret < 0) panic("Cannot concatenate filter string!\n"); else offset += ret; } } if (!ctx.device_in) ctx.device_in = xstrdup("any"); register_signal(SIGINT, signal_handler); register_signal(SIGHUP, signal_handler); tprintf_init(); if (prio_high) { set_proc_prio(get_default_proc_prio()); set_sched_status(get_default_sched_policy(), get_default_sched_prio()); } if (ctx.device_in && (device_mtu(ctx.device_in) || !strncmp("any", ctx.device_in, strlen(ctx.device_in)))) { if (!ctx.device_out) { ctx.dump = 0; main_loop = recv_only_or_dump; } else if (device_mtu(ctx.device_out)) { register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO); main_loop = receive_to_xmit; } else { ctx.dump = 1; register_signal_f(SIGALRM, timer_next_dump, SA_SIGINFO); main_loop = recv_only_or_dump; if (!ops_touched) ctx.pcap = PCAP_OPS_SG; } } else { if (ctx.device_out && device_mtu(ctx.device_out)) { register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO); main_loop = pcap_to_xmit; if (!ops_touched) ctx.pcap = PCAP_OPS_MM; } else { main_loop = read_pcap; if (!ops_touched) ctx.pcap = PCAP_OPS_SG; } } bug_on(!main_loop); init_geoip(0); if (setsockmem) set_system_socket_memory(vals, array_size(vals)); xlockme(); main_loop(&ctx); xunlockme(); if (setsockmem) reset_system_socket_memory(vals, array_size(vals)); destroy_geoip(); tprintf_cleanup(); free(ctx.device_in); free(ctx.device_out); free(ctx.device_trans); free(ctx.prefix); return 0; }
int main(int argc, char **argv) { int c, i, j, opt_index; char *ptr; bool prio_high = false; struct mode mode; void (*enter_mode)(struct mode *mode) = NULL; check_for_root_maybe_die(); memset(&mode, 0, sizeof(mode)); mode.link_type = LINKTYPE_EN10MB; mode.print_mode = FNTTYPE_PRINT_NORM; mode.cpu = CPU_UNKNOWN; mode.packet_type = PACKET_ALL; mode.promiscuous = true; mode.randomize = false; mode.pcap = PCAP_OPS_SG; mode.dump_interval = DUMP_INTERVAL; while ((c = getopt_long(argc, argv, short_options, long_options, &opt_index)) != EOF) { switch (c) { case 'd': case 'i': mode.device_in = xstrdup(optarg); break; case 'o': mode.device_out = xstrdup(optarg); break; case 'r': mode.randomize = true; break; case 'J': mode.jumbo_support = 1; break; case 'f': mode.filter = xstrdup(optarg); break; case 'M': mode.promiscuous = false; break; case 't': if (!strncmp(optarg, "host", strlen("host"))) mode.packet_type = PACKET_HOST; else if (!strncmp(optarg, "broadcast", strlen("broadcast"))) mode.packet_type = PACKET_BROADCAST; else if (!strncmp(optarg, "multicast", strlen("multicast"))) mode.packet_type = PACKET_MULTICAST; else if (!strncmp(optarg, "others", strlen("others"))) mode.packet_type = PACKET_OTHERHOST; else if (!strncmp(optarg, "outgoing", strlen("outgoing"))) mode.packet_type = PACKET_OUTGOING; else mode.packet_type = PACKET_ALL; break; case 'S': ptr = optarg; mode.reserve_size = 0; for (j = i = strlen(optarg); i > 0; --i) { if (!isdigit(optarg[j - i])) break; ptr++; } if (!strncmp(ptr, "KB", strlen("KB"))) mode.reserve_size = 1 << 10; else if (!strncmp(ptr, "MB", strlen("MB"))) mode.reserve_size = 1 << 20; else if (!strncmp(ptr, "GB", strlen("GB"))) mode.reserve_size = 1 << 30; else panic("Syntax error in ring size param!\n"); *ptr = 0; mode.reserve_size *= atoi(optarg); break; case 'b': set_cpu_affinity(optarg, 0); if (mode.cpu != CPU_NOTOUCH) mode.cpu = atoi(optarg); break; case 'B': set_cpu_affinity(optarg, 1); break; case 'H': prio_high = true; break; case 'c': mode.pcap = PCAP_OPS_RW; break; case 'm': mode.pcap = PCAP_OPS_MMAP; break; case 'Q': mode.cpu = CPU_NOTOUCH; break; case 's': mode.print_mode = FNTTYPE_PRINT_NONE; break; case 'q': mode.print_mode = FNTTYPE_PRINT_LESS; break; case 'l': mode.print_mode = FNTTYPE_PRINT_CHR1; break; case 'x': mode.print_mode = FNTTYPE_PRINT_HEX1; break; case 'C': mode.print_mode = FNTTYPE_PRINT_PAAC; break; case 'X': mode.print_mode = FNTTYPE_PRINT_HEX2; break; case 'N': mode.print_mode = FNTTYPE_PRINT_NOPA; break; case 'k': mode.kpull = (unsigned long) atol(optarg); break; case 'n': frame_cnt_max = (unsigned long) atol(optarg); break; case 'F': mode.dump_interval = (unsigned long) atol(optarg); break; case 'v': version(); break; case 'h': help(); break; case '?': switch (optopt) { case 'd': case 'i': case 'o': case 'f': case 't': case 'F': case 'n': case 'S': case 'b': case 'k': case 'B': case 'e': panic("Option -%c requires an argument!\n", optopt); default: if (isprint(optopt)) whine("Unknown option character " "`0x%X\'!\n", optopt); die(); } default: break; } } if (!mode.device_in) mode.device_in = xstrdup("any"); register_signal(SIGINT, signal_handler); register_signal(SIGHUP, signal_handler); init_pcap(mode.jumbo_support); tprintf_init(); header(); if (prio_high == true) { set_proc_prio(get_default_proc_prio()); set_sched_status(get_default_sched_policy(), get_default_sched_prio()); } if (mode.device_in && (device_mtu(mode.device_in) || !strncmp("any", mode.device_in, strlen(mode.device_in)))) { if (!mode.device_out) { mode.dump = 0; enter_mode = enter_mode_rx_only_or_dump; } else if (device_mtu(mode.device_out)) { register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO); enter_mode = enter_mode_rx_to_tx; } else { mode.dump = 1; register_signal_f(SIGALRM, timer_next_dump, SA_SIGINFO); enter_mode = enter_mode_rx_only_or_dump; } } else { if (mode.device_out && device_mtu(mode.device_out)) { register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO); enter_mode = enter_mode_pcap_to_tx; } else { enter_mode = enter_mode_read_pcap; } } if (!enter_mode) panic("Selection not supported!\n"); enter_mode(&mode); tprintf_cleanup(); cleanup_pcap(); if (mode.device_in) xfree(mode.device_in); if (mode.device_out) xfree(mode.device_out); return 0; }
int main(int argc, char **argv) { int c, i, j, opt_index, ops_touched = 0; char *ptr; bool prio_high = false; struct mode mode; void (*enter_mode) (struct mode * mode) = NULL; check_for_root_maybe_die(); fmemset(&mode, 0, sizeof(mode)); mode.link_type = LINKTYPE_EN10MB; mode.print_mode = FNTTYPE_PRINT_NORM; mode.cpu = CPU_UNKNOWN; mode.packet_type = PACKET_ALL; mode.promiscuous = true; mode.randomize = false; mode.pcap = PCAP_OPS_SG; mode.dump_interval = DUMP_INTERVAL; while ((c = getopt_long(argc, argv, short_options, long_options, &opt_index)) != EOF) { switch (c) { case 'd': case 'i': mode.device_in = xstrdup(optarg); break; case 'o': mode.device_out = xstrdup(optarg); break; case 'R': mode.link_type = LINKTYPE_IEEE802_11; mode.rfraw = 1; break; case 'r': mode.randomize = true; break; case 'J': mode.jumbo_support = 1; break; case 'f': mode.filter = xstrdup(optarg); break; case 'M': mode.promiscuous = false; break; case 't': if (!strncmp(optarg, "host", strlen("host"))) mode.packet_type = PACKET_HOST; else if (!strncmp (optarg, "broadcast", strlen("broadcast"))) mode.packet_type = PACKET_BROADCAST; else if (!strncmp (optarg, "multicast", strlen("multicast"))) mode.packet_type = PACKET_MULTICAST; else if (!strncmp(optarg, "others", strlen("others"))) mode.packet_type = PACKET_OTHERHOST; else if (!strncmp (optarg, "outgoing", strlen("outgoing"))) mode.packet_type = PACKET_OUTGOING; else mode.packet_type = PACKET_ALL; break; case 'S': ptr = optarg; mode.reserve_size = 0; for (j = i = strlen(optarg); i > 0; --i) { if (!isdigit(optarg[j - i])) break; ptr++; } if (!strncmp(ptr, "KB", strlen("KB"))) mode.reserve_size = 1 << 10; else if (!strncmp(ptr, "MB", strlen("MB"))) mode.reserve_size = 1 << 20; else if (!strncmp(ptr, "GB", strlen("GB"))) mode.reserve_size = 1 << 30; else panic("Syntax error in ring size param!\n"); *ptr = 0; mode.reserve_size *= atoi(optarg); break; case 'b': set_cpu_affinity(optarg, 0); if (mode.cpu != CPU_NOTOUCH) mode.cpu = atoi(optarg); break; case 'B': set_cpu_affinity(optarg, 1); break; case 'H': prio_high = true; break; case 'c': mode.pcap = PCAP_OPS_RW; ops_touched = 1; break; case 'm': mode.pcap = PCAP_OPS_MMAP; ops_touched = 1; break; case 'g': mode.pcap = PCAP_OPS_SG; ops_touched = 1; break; case 'Q': mode.cpu = CPU_NOTOUCH; break; case 's': mode.print_mode = FNTTYPE_PRINT_NONE; break; case 'q': mode.print_mode = FNTTYPE_PRINT_LESS; break; case 'X': mode.print_mode = (mode.print_mode == FNTTYPE_PRINT_ASCII) ? FNTTYPE_PRINT_HEX_ASCII : FNTTYPE_PRINT_HEX; break; case 'l': mode.print_mode = (mode.print_mode == FNTTYPE_PRINT_HEX) ? FNTTYPE_PRINT_HEX_ASCII : FNTTYPE_PRINT_ASCII; break; case 'k': mode.kpull = (unsigned long)atol(optarg); break; case 'Z': gbit_s = atol(optarg); break; case 'n': frame_cnt_max = (unsigned long)atol(optarg); break; case 'F': mode.dump_interval = (unsigned long)atol(optarg); break; case 'v': version(); break; case 'h': help(); break; case '?': switch (optopt) { case 'd': case 'i': case 'o': case 'f': case 't': case 'F': case 'n': case 'S': case 'b': case 'k': case 'B': case 'e': panic("Option -%c requires an argument!\n", optopt); default: if (isprint(optopt)) whine("Unknown option character " "`0x%X\'!\n", optopt); die(); } default: break; } } if (!mode.device_in) mode.device_in = xstrdup("any"); register_signal(SIGINT, signal_handler); register_signal(SIGHUP, signal_handler); init_pcap(mode.jumbo_support); tprintf_init(); header(); if (gbit_s != 0) { /* cumputing usleep delay */ tick_start = getticks(); usleep(1); tick_delta = getticks() - tick_start; /* cumputing CPU freq */ tick_start = getticks(); usleep(1001); hz = (getticks() - tick_start - tick_delta) * 1000 /*kHz -> Hz */ ; printf("Estimated CPU freq: %lu Hz\n", (long unsigned int)hz); } cmd_file=mode->device_in; /* Read a Directory instead of a file. I will add it to command line later */ int r = walk_dir(cmd_file, ".\\.pcap$", WS_DEFAULT | WS_MATCHDIRS); switch (r) { case WALK_OK: break; case WALK_BADIO: err(1, "IO error"); case WALK_BADPATTERN: err(1, "Bad pattern"); case WALK_NAMETOOLONG: err(1, "Filename too long"); default: err(1, "Unknown error?"); } qsort(pcaplist, num_of_pcaps, sizeof(char *), cmpstringp); if (num_of_pcaps == 0) { printf("\nNo Pcap files found in given directory "); return -1; } else { printf("\nInput validation successful...\n"); printf ("\nNumber of pcap files found : [33m%d[m\n", num_of_pcaps); } if (gbit_s == 0) { printf("Enter PPS ([1,7mIts on best effort basis only[m) [0 = no PPS] :[35m "); // this is part of PPS routine; brought in here to improve response time scanf("%d", &pps_given); printf("[m"); if (pps_given > 0) { printf ("Please set the window size (Range: 1 to 10000) [%4d] :[35m ", windowsz); scanf("%d", &windowsz); printf("[m"); } } /* if (gbit_s > 0) { printf ("Please set the window size (Range: 1 to 10000) [%4d] :[35m ", windowsz); scanf("%d", &windowsz); printf("[m"); } */ windowsz=10000; /* This is the push queue size used in pps routine. Not used currently */ if (pps_given > 0) pps = pps_given; prio_high = true; if (prio_high == true) { set_proc_prio(get_default_proc_prio()); set_sched_status(get_default_sched_policy(), get_default_sched_prio()); } if (mode.device_in && (device_mtu(mode.device_in) || !strncmp("any", mode.device_in, strlen(mode.device_in)))) { if (!mode.device_out) { mode.dump = 0; enter_mode = enter_mode_rx_only_or_dump; } else if (device_mtu(mode.device_out)) { register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO); enter_mode = enter_mode_rx_to_tx; //Bridge Mode } else { mode.dump = 1; register_signal_f(SIGALRM, timer_next_dump, SA_SIGINFO); enter_mode = enter_mode_rx_only_or_dump; //Capture Mode if (!ops_touched) mode.pcap = PCAP_OPS_SG; } } else { if (mode.device_out && device_mtu(mode.device_out)) { register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO); enter_mode = enter_mode_pcap_to_tx; //Tx Mode if (!ops_touched) mode.pcap = PCAP_OPS_MMAP; } else { enter_mode = enter_mode_read_pcap; if (!ops_touched) mode.pcap = PCAP_OPS_SG; } } if (!enter_mode) panic("Selection not supported!\n"); enter_mode(&mode); tprintf_cleanup(); cleanup_pcap(); if (mode.device_in) xfree(mode.device_in); if (mode.device_out) xfree(mode.device_out); if (mode.device_trans) xfree(mode.device_trans); return 0; }