--- main.c.orig Wed Apr 21 03:40:14 1999 +++ main.c Thu Aug 19 16:36:06 1999 @@ -63,7 +63,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, " [-i iface] [expression]\n\n"); + fprintf(stderr, " [-i iface] [-r 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"); fprintf(stderr, " -d: debug level; default is %d\n", DEFAULT_DEBUG_LEVEL); @@ -72,6 +72,7 @@ fprintf(stderr, " -i: network interface on which to listen\n"); fprintf(stderr, " (type \"ifconfig -a\" for a list of interfaces)\n"); fprintf(stderr, " -p: don't use promiscuous mode\n"); + fprintf(stderr, " -r: read packets from file\n"); fprintf(stderr, " -s: strip non-printable characters (change to '.')\n"); fprintf(stderr, " -v: verbose operation equivalent to -d 10\n"); fprintf(stderr, "expression: tcpdump-like filtering expression\n"); @@ -89,6 +90,7 @@ int need_usage = 0; char *device = NULL; + char *infile = NULL; char *expression = NULL; pcap_t *pd; struct bpf_program fcode; @@ -98,7 +100,7 @@ opterr = 0; - while ((arg = getopt(argc, argv, "b:cd:f:hi:psv")) != EOF) { + while ((arg = getopt(argc, argv, "b:cd:f:hi:pr:sv")) != EOF) { switch (arg) { case 'b': if ((bytes_per_flow = atoi(optarg)) < 0) { @@ -140,6 +142,9 @@ no_promisc = 1; DEBUG(10) ("NOT turning on promiscuous mode"); break; + case 'r': + infile = optarg; + break; case 'v': debug_level = 10; break; @@ -160,23 +165,32 @@ DEBUG(10) ("%s version %s by Jeremy Elson ", PACKAGE, VERSION); - /* if the user didn't specify a device, try to find a reasonable one */ - if (device == NULL) - if ((device = pcap_lookupdev(error)) == NULL) + if (infile != NULL) { + /* Since we don't need network access, drop root privileges */ + setuid(getuid()); + + /* open the capture file */ + if ((pd = pcap_open_offline(infile, error)) == NULL) die(error); - /* make sure we can open the device */ - if ((pd = pcap_open_live(device, SNAPLEN, !no_promisc, 1000, error)) == NULL) - die(error); + /* get the handler for this kind of packets */ + handler = find_handler(pcap_datalink(pd), infile); + } else { + /* if the user didn't specify a device, try to find a reasonable one */ + if (device == NULL) + if ((device = pcap_lookupdev(error)) == NULL) + die(error); - /* drop root privileges - we don't need them any more */ - setuid(getuid()); + /* make sure we can open the device */ + if ((pd = pcap_open_live(device, SNAPLEN, !no_promisc, 1000, error)) == NULL) + die(error); - /* remember what datalink type the selected network interface is */ - dlt = pcap_datalink(pd); + /* drop root privileges - we don't need them any more */ + setuid(getuid()); - /* get the handler for this network interface */ - handler = find_handler(dlt, device); + /* get the handler for this kind of packets */ + handler = find_handler(pcap_datalink(pd), device); + } /* get the user's expression out of argv */ expression = copy_argv(&argv[optind]); @@ -223,7 +237,8 @@ init_flow_state(); /* start listening! */ - DEBUG(1) ("listening on %s", device); + if (infile == NULL) + DEBUG(1) ("listening on %s", device); if (pcap_loop(pd, -1, handler, NULL) < 0) die(pcap_geterr(pd)); --- tcpflow.1.in.orig Wed Apr 21 10:57:20 1999 +++ tcpflow.1.in Thu Aug 19 19:36:04 1999 @@ -21,6 +21,9 @@ .BI \-i \ iface\fR\c ] [\c +.BI \-r \ file\fR\c +] +[\c .BI expression\fR\c ] .SH DESCRIPTION @@ -29,7 +32,7 @@ is a program that captures data transmitted as part of TCP connections (flows), and stores it in a way that is convenient for protocol analysis or debugging. A program like -.IR tcpdump (4) +.IR tcpdump (1) only shows a summary of packets seen on the wire, but usually doesn't store the data that's actually being transmitted. In contrast, tcpflow reconstructs the actual data streams and stores each flow in a @@ -93,6 +96,13 @@ .B \-i , a reasonable default will be used by libpcap automatically. .TP +.B \-r +Read packets from \fIfile\fP, which was created using the +.B \-w +option of +.IR tcpdump (1). +Standard input is used if \fIfile\fP is ``-''. +.TP .B \-p No promiscuous mode. Normally, tcpflow attempts to put the network interface into promiscuous mode before capturing packets. The @@ -118,7 +128,7 @@ specified on the command-line specifies which packets should be captured. Because tcpflow uses the the libpcap library, tcpflow has the same powerful filtering language available as programs such as -.IR tcpdump (4). +.IR tcpdump (1). .LP .B The following part of the man page is excerpted from the tcpdump man page. .LP @@ -259,7 +269,7 @@ .IP "\fBdst net \fInet\fR" True if the IP destination address of the packet has a network number of \fInet\fP. \fINet\fP may be either a name from /etc/networks -or a network number (see \fInetworks(4)\fP for details). +or a network number (see \fInetworks(5)\fP for details). .IP "\fBsrc net \fInet\fR" True if the IP source address of the packet has a network number of \fInet\fP.