7dbda33e53
- tcpflow 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 'tcpdump' 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 separate file for later analysis. tcpflow understands sequence numbers and will correctly reconstruct data streams regardless of retransmissions or out-of-order delivery. However, it currently does not understand IP fragments; flows containing IP fragments will not be recorded properly. Note: this port includes a small patch that adds the capability of reading the packets from a tcpdump(1) capture file, using a new option (-r).
102 lines
3.6 KiB
Plaintext
102 lines
3.6 KiB
Plaintext
--- main.c.orig Tue Apr 20 21:40:14 1999
|
|
+++ main.c Sun Oct 10 21:31:33 1999
|
|
@@ -63,7 +63,7 @@
|
|
fprintf(stderr, "%s version %s by Jeremy Elson <jelson@circlemud.org>\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 <jelson@circlemud.org>",
|
|
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));
|
|
|