--- tcpflow-0.21/src/main.c.jdw 2009-01-23 11:45:04.000000000 +1100 +++ tcpflow-0.21/src/main.c 2009-01-23 13:12:14.000000000 +1100 @@ -73,6 +73,8 @@ int suppress_header = 0; int strip_nonprint = 0; int use_color = 0; +int timeout = 1000; + pcap_t *pd; char error[PCAP_ERRBUF_SIZE]; @@ -81,7 +83,7 @@ { fprintf(stderr, "%s version %s by Jeremy Elson \n\n", PACKAGE, VERSION); - fprintf(stderr, "usage: %s [-chpsv] [-b max_bytes] [-d debug_level] [-f max_fds]\n", progname); + fprintf(stderr, "usage: %s [-chpsv] [-b max_bytes] [-d debug_level] [-f max_fds] [-t timeout]\n", progname); fprintf(stderr, " [-i iface] [-w file] [expression]\n\n"); fprintf(stderr, " -b: max number of bytes per flow to save\n"); fprintf(stderr, " -c: console print only (don't create files)\n"); @@ -95,6 +97,7 @@ fprintf(stderr, " -p: don't use promiscuous mode\n"); fprintf(stderr, " -r: read packets from tcpdump output file\n"); fprintf(stderr, " -s: strip non-printable characters (change to '.')\n"); + fprintf(stderr, " -t: set read timeout in milliseconds (%d)\n", timeout); fprintf(stderr, " -v: verbose operation equivalent to -d 10\n"); fprintf(stderr, "expression: tcpdump-like filtering expression\n"); fprintf(stderr, "\nSee the man page for additional information.\n\n"); @@ -103,6 +106,19 @@ RETSIGTYPE terminate(int sig) { + if (pd) + { + /* + * We need to see if any packets have been dropped. + * And whether, perhaps, net.core.rmem_max and net.core.rmem_default + * should be increased to something sensible like 8388608. + */ + struct pcap_stat stat = {0}; + pcap_stats(pd, &stat); + DEBUG(1) ("pcap: recv=%d", stat.ps_recv); + DEBUG(1) ("pcap: drop=%d", stat.ps_drop); + DEBUG(1) ("pcap: ifdrop=%d", stat.ps_ifdrop); + } DEBUG(1) ("terminating"); exit(0); /* libpcap uses onexit to clean up */ } @@ -120,7 +136,6 @@ char *device = NULL; char *infile = NULL; char *expression = NULL; - pcap_t *pd; struct bpf_program fcode; pcap_handler handler; @@ -128,7 +143,7 @@ opterr = 0; - while ((arg = getopt(argc, argv, "b:cCd:ef:hi:pr:sv")) != EOF) { + while ((arg = getopt(argc, argv, "b:cCd:ef:hi:pr:st:v")) != EOF) { switch (arg) { case 'b': if ((bytes_per_flow = atoi(optarg)) < 0) { @@ -184,6 +199,9 @@ use_color = 1; DEBUG(10) ("using colors"); break; + case 't': + timeout = atoi(optarg); + break; default: DEBUG(1) ("error: unrecognized switch '%c'", optopt); need_usage = 1; @@ -219,7 +237,7 @@ die("%s", error); /* make sure we can open the device */ - if ((pd = pcap_open_live(device, SNAPLEN, !no_promisc, 1000, error)) == NULL) + if ((pd = pcap_open_live(device, SNAPLEN, !no_promisc, timeout, error)) == NULL) die("%s", error); /* drop root privileges - we don't need them any more */