Browse Source

Import upstream version 2.3.3

Aaron Turner 20 years ago
parent
commit
564129c502
100 changed files with 36813 additions and 1393 deletions
  1. 0 14
      CHANGES
  2. 0 20
      CREDITS
  3. 0 15
      CVS/Entries
  4. 0 1
      CVS/Repository
  5. 0 1
      CVS/Root
  6. 2 0
      Docs/.svn/README.txt
  7. 5 0
      Docs/.svn/dir-wcprops
  8. 0 0
      Docs/.svn/empty-file
  9. 104 0
      Docs/.svn/entries
  10. 1 0
      Docs/.svn/format
  11. 9 0
      Docs/.svn/prop-base/CHANGELOG.svn-base
  12. 9 0
      Docs/.svn/prop-base/CREDIT.svn-base
  13. 9 0
      Docs/.svn/prop-base/FAQ.lyx.svn-base
  14. 9 0
      Docs/.svn/prop-base/HACKING.svn-base
  15. 9 0
      Docs/.svn/prop-base/INSTALL.svn-base
  16. 9 0
      Docs/.svn/prop-base/LICENSE.svn-base
  17. 9 0
      Docs/.svn/prop-base/Makefile.svn-base
  18. 9 0
      Docs/.svn/prop-base/TODO.svn-base
  19. 5 0
      Docs/.svn/prop-base/flowheader.fig.svn-base
  20. 9 0
      Docs/.svn/prop-base/flowreplay.lyx.svn-base
  21. 9 0
      Docs/.svn/props/CHANGELOG.svn-work
  22. 9 0
      Docs/.svn/props/CREDIT.svn-work
  23. 9 0
      Docs/.svn/props/FAQ.lyx.svn-work
  24. 9 0
      Docs/.svn/props/HACKING.svn-work
  25. 9 0
      Docs/.svn/props/INSTALL.svn-work
  26. 9 0
      Docs/.svn/props/LICENSE.svn-work
  27. 9 0
      Docs/.svn/props/Makefile.svn-work
  28. 9 0
      Docs/.svn/props/TODO.svn-work
  29. 5 0
      Docs/.svn/props/flowheader.fig.svn-work
  30. 9 0
      Docs/.svn/props/flowreplay.lyx.svn-work
  31. 277 0
      Docs/.svn/text-base/CHANGELOG.svn-base
  32. 33 0
      Docs/.svn/text-base/CREDIT.svn-base
  33. 2277 0
      Docs/.svn/text-base/FAQ.lyx.svn-base
  34. 122 0
      Docs/.svn/text-base/HACKING.svn-base
  35. 24 0
      Docs/.svn/text-base/INSTALL.svn-base
  36. 32 0
      Docs/.svn/text-base/LICENSE.svn-base
  37. 40 0
      Docs/.svn/text-base/Makefile.svn-base
  38. 47 0
      Docs/.svn/text-base/TODO.svn-base
  39. 92 0
      Docs/.svn/text-base/flowheader.fig.svn-base
  40. 1125 0
      Docs/.svn/text-base/flowreplay.lyx.svn-base
  41. 5 0
      Docs/.svn/wcprops/CHANGELOG.svn-work
  42. 5 0
      Docs/.svn/wcprops/CREDIT.svn-work
  43. 5 0
      Docs/.svn/wcprops/FAQ.lyx.svn-work
  44. 5 0
      Docs/.svn/wcprops/HACKING.svn-work
  45. 5 0
      Docs/.svn/wcprops/INSTALL.svn-work
  46. 5 0
      Docs/.svn/wcprops/LICENSE.svn-work
  47. 5 0
      Docs/.svn/wcprops/Makefile.svn-work
  48. 5 0
      Docs/.svn/wcprops/TODO.svn-work
  49. 5 0
      Docs/.svn/wcprops/flowheader.fig.svn-work
  50. 5 0
      Docs/.svn/wcprops/flowreplay.lyx.svn-work
  51. 277 0
      Docs/CHANGELOG
  52. 33 0
      Docs/CREDIT
  53. 34 0
      Docs/FAQ.css
  54. BIN
      Docs/FAQ.dvi
  55. 2346 0
      Docs/FAQ.html
  56. 2277 0
      Docs/FAQ.lyx
  57. BIN
      Docs/FAQ.pdf
  58. 2028 0
      Docs/FAQ.ps
  59. 1355 0
      Docs/FAQ.tex
  60. 1499 0
      Docs/FAQ.txt
  61. 122 0
      Docs/HACKING
  62. 24 0
      Docs/INSTALL
  63. 9 6
      LICENSE
  64. 40 0
      Docs/Makefile
  65. 47 0
      Docs/TODO
  66. 9 0
      Docs/WARNINGS
  67. 278 0
      Docs/flowheader.eps
  68. 92 0
      Docs/flowheader.fig
  69. 172 0
      Docs/flowreplay.css
  70. BIN
      Docs/flowreplay.dvi
  71. 664 0
      Docs/flowreplay.html
  72. 1125 0
      Docs/flowreplay.lyx
  73. BIN
      Docs/flowreplay.pdf
  74. 1224 0
      Docs/flowreplay.ps
  75. 520 0
      Docs/flowreplay.tex
  76. 498 0
      Docs/flowreplay.txt
  77. 5 0
      Docs/images.aux
  78. 234 0
      Docs/images.log
  79. 12 0
      Docs/images.pl
  80. 193 0
      Docs/images.tex
  81. BIN
      Docs/img1.png
  82. 664 0
      Docs/index.html
  83. 13 0
      Docs/labels.pl
  84. 0 45
      INSTALL
  85. 125 35
      Makefile.in
  86. 1 54
      README
  87. 0 1
      VERSION
  88. 108 0
      aclocal.m4
  89. 375 0
      cache.c
  90. 103 0
      cache.h
  91. 152 0
      capinfo.c
  92. 46 0
      capinfo.h
  93. 504 0
      cidr.c
  94. 63 0
      cidr.h
  95. 1354 0
      config.guess
  96. 63 9
      config.h.in
  97. 1460 0
      config.sub
  98. 11731 1177
      configure
  99. 531 15
      configure.in
  100. 0 0
      dlt.h

+ 0 - 14
CHANGES

@@ -1,14 +0,0 @@
-$Id: CHANGES,v 1.3 1999/05/19 20:05:01 dugsong Exp $
-
-v1.0.1 Wed May 19 16:03:38 EDT 1999
-
-- Added Solaris support.
-
-v1.0 Thu May 13 11:05:04 EDT 1999
-
-- Public release.
-
-v0.1b Wed May  5 10:06:07 EDT 1999
-
-- Initial release.
-

+ 0 - 20
CREDITS

@@ -1,20 +0,0 @@
-
-Tcpreplay author:
-
-   Matt Undy <mundy@anzen.com>
-
-Tcpreplay includes code from libnet and libpcap:
-
-   LBNL Network Research Group <libpcap@ee.lbl.gov>
-   ftp://ftp.ee.lbl.gov/libpcap.tar.Z
-
-   Mike D. Schiffman <mike@infonexus.com>
-   route|daemon9 <route@infonexus.com>
-   http://www.packetfactory.net/libnet
-
-Additional contributors:
-
-   None so far!
-
----
-$Id: CREDITS,v 1.2 1999/05/13 15:02:10 dugsong Exp $

+ 0 - 15
CVS/Entries

@@ -1,15 +0,0 @@
-/CREDITS/1.2/Thu May 13 15:02:10 1999//
-/INSTALL/1.3/Thu May 13 15:02:10 1999//
-/LICENSE/1.2/Fri Apr 23 20:05:47 1999//
-/Makefile.in/1.5/Wed Apr 21 22:16:41 1999//
-/config.h.in/1.2/Wed Apr 21 22:16:41 1999//
-/install-sh/1.1/Tue Apr 20 19:41:49 1999//
-/tcpreplay.8/1.4/Wed May  5 13:16:55 1999//
-D/Libnet-0.99////
-D/libpcap-0.4////
-/CHANGES/1.3/Wed May 19 20:05:01 1999//
-/README/1.5/Wed May 19 20:05:01 1999//
-/VERSION/1.4/Wed May 19 20:00:42 1999//
-/configure/1.3/Wed May 19 19:55:31 1999//
-/configure.in/1.3/Wed May 19 19:55:28 1999//
-/tcpreplay.c/1.18/Wed May 19 20:00:35 1999//

+ 0 - 1
CVS/Repository

@@ -1 +0,0 @@
-/usr/anzen/src/nidsbench/nidsbench/tcpreplay

+ 0 - 1
CVS/Root

@@ -1 +0,0 @@
-/usr/anzen/src/nidsbench

+ 2 - 0
Docs/.svn/README.txt

@@ -0,0 +1,2 @@
+This is a Subversion working copy administrative directory.
+Visit http://subversion.tigris.org/ for more information.

+ 5 - 0
Docs/.svn/dir-wcprops

@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 48
+/svn/!svn/ver/769/tcpreplay/branches/stable/Docs
+END

+ 0 - 0
Docs/.svn/empty-file


+ 104 - 0
Docs/.svn/entries

@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="utf-8"?>
+<wc-entries
+   xmlns="svn:">
+<entry
+   committed-rev="767"
+   name=""
+   committed-date="2004-10-06T12:48:49.445445Z"
+   url="https://www.synfin.net:444/svn/tcpreplay/branches/stable/Docs"
+   last-author="aturner"
+   kind="dir"
+   uuid="0192c630-c6e5-0310-95d6-b430f9ea3712"
+   revision="877"/>
+<entry
+   committed-rev="622"
+   name="flowreplay.lyx"
+   text-time="2004-10-26T17:15:35.000000Z"
+   committed-date="2004-03-25T02:31:50.000000Z"
+   checksum="a786d7d9d39dc58eb5444edc98a79cc4"
+   last-author="aturner"
+   kind="file"
+   prop-time="2004-10-26T17:15:35.000000Z"/>
+<entry
+   committed-rev="578"
+   name="LICENSE"
+   text-time="2004-10-26T17:15:35.000000Z"
+   committed-date="2004-01-31T23:42:15.000000Z"
+   checksum="7dbc88d059f05dedbfa01da04edf1254"
+   last-author="aturner"
+   kind="file"
+   prop-time="2004-10-26T17:15:35.000000Z"/>
+<entry
+   committed-rev="753"
+   name="FAQ.lyx"
+   text-time="2004-10-26T17:15:36.000000Z"
+   committed-date="2004-09-20T21:32:36.000000Z"
+   checksum="5b69933de891d4e94273f89d17d66581"
+   last-author="aturner"
+   kind="file"
+   prop-time="2004-10-26T17:15:36.000000Z"/>
+<entry
+   committed-rev="479"
+   name="flowheader.fig"
+   text-time="2004-10-26T17:15:36.000000Z"
+   committed-date="2003-10-24T03:30:25.000000Z"
+   checksum="8e5e0f5a5ef76f6e7b22d912e0a8e2e8"
+   last-author="aturner"
+   kind="file"
+   prop-time="2004-10-26T17:15:36.000000Z"/>
+<entry
+   committed-rev="767"
+   name="HACKING"
+   text-time="2004-10-26T17:15:36.000000Z"
+   committed-date="2004-10-06T12:48:49.445445Z"
+   checksum="dbf38d3bfd5808e3a8bb4ca8e50ce87a"
+   last-author="aturner"
+   kind="file"
+   prop-time="2004-10-26T17:15:36.000000Z"/>
+<entry
+   committed-rev="720"
+   name="TODO"
+   text-time="2004-10-26T17:15:36.000000Z"
+   committed-date="2004-07-25T23:35:20.000000Z"
+   checksum="cc1965bd0bbd4a23532428611757c82c"
+   last-author="aturner"
+   kind="file"
+   prop-time="2004-10-26T17:15:36.000000Z"/>
+<entry
+   committed-rev="767"
+   name="INSTALL"
+   text-time="2004-10-26T17:15:36.000000Z"
+   committed-date="2004-10-06T12:48:49.445445Z"
+   checksum="ade780bbb32233787211dfd888359228"
+   last-author="aturner"
+   kind="file"
+   prop-time="2004-10-26T17:15:36.000000Z"/>
+<entry
+   committed-rev="1133"
+   name="CHANGELOG"
+   text-time="2005-02-09T01:31:17.000000Z"
+   committed-date="2005-02-09T01:31:16.732097Z"
+   checksum="ef930af2dd1ba2034447acbc50d47b18"
+   last-author="aturner"
+   kind="file"
+   prop-time="2004-10-26T17:15:36.000000Z"
+   revision="1133"/>
+<entry
+   committed-rev="767"
+   name="CREDIT"
+   text-time="2004-10-26T17:15:36.000000Z"
+   committed-date="2004-10-06T12:48:49.445445Z"
+   checksum="0214c3ee73a86b847cf8e43e39481160"
+   last-author="aturner"
+   kind="file"
+   prop-time="2004-10-26T17:15:36.000000Z"/>
+<entry
+   committed-rev="619"
+   name="Makefile"
+   text-time="2004-10-26T17:15:36.000000Z"
+   committed-date="2004-03-25T00:58:20.000000Z"
+   checksum="849ee017ce47422f81ccb0165f858541"
+   last-author="aturner"
+   kind="file"
+   prop-time="2004-10-26T17:15:36.000000Z"/>
+</wc-entries>

+ 1 - 0
Docs/.svn/format

@@ -0,0 +1 @@
+4

+ 9 - 0
Docs/.svn/prop-base/CHANGELOG.svn-base

@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 23
+author date id revision
+K 13
+svn:eol-style
+V 6
+native
+END

+ 9 - 0
Docs/.svn/prop-base/CREDIT.svn-base

@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 23
+author date id revision
+K 13
+svn:eol-style
+V 6
+native
+END

+ 9 - 0
Docs/.svn/prop-base/FAQ.lyx.svn-base

@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 23
+author date id revision
+K 13
+svn:eol-style
+V 6
+native
+END

+ 9 - 0
Docs/.svn/prop-base/HACKING.svn-base

@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 23
+author date id revision
+K 13
+svn:eol-style
+V 6
+native
+END

+ 9 - 0
Docs/.svn/prop-base/INSTALL.svn-base

@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 23
+author date id revision
+K 13
+svn:eol-style
+V 6
+native
+END

+ 9 - 0
Docs/.svn/prop-base/LICENSE.svn-base

@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 23
+author date id revision
+K 13
+svn:eol-style
+V 6
+native
+END

+ 9 - 0
Docs/.svn/prop-base/Makefile.svn-base

@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 23
+author date id revision
+K 13
+svn:eol-style
+V 6
+native
+END

+ 9 - 0
Docs/.svn/prop-base/TODO.svn-base

@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 23
+author date id revision
+K 13
+svn:eol-style
+V 6
+native
+END

+ 5 - 0
Docs/.svn/prop-base/flowheader.fig.svn-base

@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END

+ 9 - 0
Docs/.svn/prop-base/flowreplay.lyx.svn-base

@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 23
+author date id revision
+K 13
+svn:eol-style
+V 6
+native
+END

+ 9 - 0
Docs/.svn/props/CHANGELOG.svn-work

@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 23
+author date id revision
+K 13
+svn:eol-style
+V 6
+native
+END

+ 9 - 0
Docs/.svn/props/CREDIT.svn-work

@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 23
+author date id revision
+K 13
+svn:eol-style
+V 6
+native
+END

+ 9 - 0
Docs/.svn/props/FAQ.lyx.svn-work

@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 23
+author date id revision
+K 13
+svn:eol-style
+V 6
+native
+END

+ 9 - 0
Docs/.svn/props/HACKING.svn-work

@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 23
+author date id revision
+K 13
+svn:eol-style
+V 6
+native
+END

+ 9 - 0
Docs/.svn/props/INSTALL.svn-work

@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 23
+author date id revision
+K 13
+svn:eol-style
+V 6
+native
+END

+ 9 - 0
Docs/.svn/props/LICENSE.svn-work

@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 23
+author date id revision
+K 13
+svn:eol-style
+V 6
+native
+END

+ 9 - 0
Docs/.svn/props/Makefile.svn-work

@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 23
+author date id revision
+K 13
+svn:eol-style
+V 6
+native
+END

+ 9 - 0
Docs/.svn/props/TODO.svn-work

@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 23
+author date id revision
+K 13
+svn:eol-style
+V 6
+native
+END

+ 5 - 0
Docs/.svn/props/flowheader.fig.svn-work

@@ -0,0 +1,5 @@
+K 13
+svn:mime-type
+V 24
+application/octet-stream
+END

+ 9 - 0
Docs/.svn/props/flowreplay.lyx.svn-work

@@ -0,0 +1,9 @@
+K 12
+svn:keywords
+V 23
+author date id revision
+K 13
+svn:eol-style
+V 6
+native
+END

+ 277 - 0
Docs/.svn/text-base/CHANGELOG.svn-base

@@ -0,0 +1,277 @@
+$Id$
+
+02/09/2005: Version 2.3.3
+    - Fix port rewriting feature on little-endian systems
+    - configure now properly handles --with-libnet and --with-libpcap
+
+11/08/2004: Version 2.3.2
+    - When sending via -1, report which interface the packet will exit
+    - Fix bug when caplen > packet len
+    - Allow rewriting of Layer 2 via -2 for Cisco HDLC (DLT_CHDLC)
+
+09/19/2004: Version 2.3.1
+    - Fix bug with fakepcap.c which appeared on systems using an older
+      version of libpcap (such as Red Hat 9.0)
+    - Don't die when setting STDERR to non-blocking
+
+09/05/2004: Version 2.3.0
+    - Fix longstanding endian bug in cache files on little endian systems
+      (note that this breaks compatibility w/ existing cache files created
+      on little endian systems)
+    - Add support to tcpreplay and tcpprep for DLT_CHDLC (Cisco HDLC)
+    - Clean up validate_l2() and rewrite_l2()
+    - Write a simple perl script to parse net/bpf.h of DLT values
+    - Teach everything the names of all the current DLT values
+    - Detect if libpcap supports pcap_datalink_val_to_description()
+    - Start printing datalink descriptions instead of DLT values
+    - Remove magic numbers from tcpreplay.c
+    - Add a HACKING document
+
+06/21/2004: Version 2.2.2
+    - tcpprep now supports DLT_RAW and DLT_LINUX_SLL
+    - add makefile target for website docs (FAQ.html, FAQ.pdf, CHANGELOG)
+    - Fix some sanity checks in tcpreplay for processing various DLT types
+      in validate_l2()
+    - Fix -x & -X
+    - Merge in patch from Denis which rewrites TCP/UDP ports via -4
+    - Fix rewrite of source MAC address in single interface mode (bug #975848)
+
+05/16/2004: Version 2.2.1
+    - Fix compile issue under RH9
+    - Fix compile issue when not using --with-debug
+
+05/15/2004: Version 2.2.0
+    - Fix pseudo-NAT (not evaluating all rules and an infinate loop)
+    - Start using strtok_r() in any function to prevent future bugs
+    - Minor updates to tcpprep.1 & tcpreplay.8 man pages
+    - Re-org some functions into different files for better modularity
+    - Clean up of some of the cache comment code
+    - flowreplay man page moved to section 1
+    - Update tcpprep and tcpreplay man pages and the FAQ
+    - Improve documentation regarding pseudo-NAT feature
+    - Fix one output mode which treated all packets as primary
+    - Add endpoint mode (-e) which rewrites all traffic between two IP's
+    - Fix rewrite of IP addresses in ARP requests & replies w/ pseudo-NAT
+    - Fix CIDR matching of 0.0.0.0/0 (all packets) which matched only 
+      255.255.255.255
+    - All CIDR notation now accepts IP addresses w/o requiring /32
+    - non-debug mode now uses -O3 -funroll-loops for better performance
+
+05/01/2004: Version 2.1.1
+    - Fix ntohll/htonll compile error on big endian systems
+
+04/23/2004: Version 2.1.0
+    - Add support for per output interface/file NAT tables 
+    - Add support for using dual output features w/ a single output
+    - Add support to tcpprep for splitting via destination port
+    - Now fully 64bit when tracking number of packets
+    - Fix a bug where sometimes the last few packets are not sent when using
+      a tcpprep cache file
+    - Some code refactorization/cleanup
+    - tcpprep cache files now support user comments
+    - Fix bug where regex optimization was turned always turned off
+
+03/24/2004: Version 2.0.3
+    - Add support for rewriting src mac & Linux SLL loopback frames
+    - Update FAQ
+
+02/25/2004: Version 2.0.2
+    - Fix compile issue in edit_packet.c on strict aligned archs
+
+02/03/2004: Version 2.0.1
+    - Re-organize FAQ and add more content
+    - Add support for "pseudo NAT" (-N) for ARP and IPv4
+    - Code optimization to only run the checksum fixer once per packet
+    - Clean up help (-h) a little
+
+02/01/2004: Version 2.0.0
+    - Remove libpcapnav requirement
+    - Now support libpcapnav >= 0.4
+    - Add -1 to replay one packet at a time (user must hit <ENTER>)
+    - Add tcpdump packet parsing to print packets as sent (-v)
+    - Place flowreplay manpage in correct location
+    - More FAQ updates
+    - Rename 1.5.x as 2.0
+    - Fix/standardize all licensing info.  Still BSD of course.
+    - -T now forces -F
+    - tcpprep now actually accepts -n (client|server)
+    - Update the INSTALL doc
+    - Remove the Docs/README... the FAQ has replaced it.
+
+12/10/2003: Version 1.5.alpha6
+    - Add BPF filter support to tcpprep and tcpreplay (-x F:"filter")
+    - Update the FAQ
+    - Add two new auto modes to tcpprep (client and server)
+    - Make clean no longer wipes out the compiled documentation in Docs
+    - Add support for replaying live traffic
+    - Add bridge mode
+    - Add -L to limit the total number of packets to send
+
+11/03/2003: Version 1.5.alpha5
+    - Add -T to truncate packets > MTU so they can be sent
+    - Now fixes ICMP checksums as appropriate
+    - Updated FAQ
+    - Updated flowreplay design doc
+    - Merge packetrate code from 1.4.5
+    - Fix compile issues under Libnet 1.1.1
+    - --with-debug now enables debuging during 'make test'
+    - Fix various Solaris compatibility bugs
+    - Add data dump mode which dumps layer 7 data to the file (-D)
+    - Now requires libpcapnav
+    - Allow to jump X bytes into the pcap and start replaying packets (-o)
+    - Can now split traffic/data into files (-w & -W)
+
+07/16/2003: Version 1.5.alpha4
+    - Split do_packets.c & do_packets() -> edit_packet.c & rewrite_l2()
+    - Don't die when packet > MTU, just skip
+    - Fix a ptr bug in do_packets() w/ the ethernet header
+    - Merge Ctrl-C fix from 1.4.4 for libnet_adv_write_link() 
+        in do_packets.c
+    - Rewrite flowreplay design document
+    - Fix an integer overflow in packet_stats() in tcpreplay.c
+    - tcpreplay's -2 now accepts a hex string rather then a filename
+    - tcpreplay now can output to a file (-w <file>)
+    - fix bug in checksum fixer
+    - Add support for files > 2GB
+
+06/06/2003: Version 1.5.alpha3
+    - Add support for Linux Cooked Sockets (SLL) format rewriting
+    - Added a flowreplay design doc in Docs/
+    - A lot more work on flowreplay
+    - Start work on read-ahead buffering of packets in flowreplay        
+    - Add support for specifying MTU.
+    - Update tcpreplay man page
+    - Fix compile of do_packets() under OpenBSD
+    - configure now checks for libpcap >= 0.6 (required for SLL)
+
+
+05/29/2003: Version 1.5.alpha2
+    - Add -F to force checksum fixing
+    - Fix packet corruption when not using -2
+    - Improve timerdiv() code
+    - Port from libredblack to OpenBSD RB_*
+    - Add flowreplay application
+    - Fix a bunch of compiler warnings about miss-matched sign
+    - IP & layer 4 checksums now work when IP options exist (tcpreplay)
+    - Updated FAQ
+    - Fix spec file
+
+05/07/2003: Version 1.5.alpha1
+    - Add layer2 rewriting
+
+05/07/2002: Branch 1.4.x tree
+
+05/04/2003: Version 1.4.beta5
+    - Fixed a one-off bug when replaying tcpprep cache files
+    - Fixed a small reporting bug in tcpprep
+
+05/02/2003: Version 1.4.beta4
+    - significantly improved timing accuracy between packets
+    - fix bug with writing only about 1/2 of cache data which caused
+        tcpreplay to bitch
+    - updated 'make test' standard cache files
+    - improved alignment of cache header (20bytes vs 17bytes)
+
+04/30/2003: Version 1.4.beta3
+    - Specifying a list of packets to include/exclude now works (-x/X P:)
+    - Minor code cleanups (better error messages, etc)
+    - Add -p option to pause a given number of sec/usec between each packet
+    - Ported tcpprep to libpcap
+    - Increase final report resolution to two sig digits
+    - Switch to err.h that we ship rather then system provided err.h
+    - Don't reset timer each time we open a file for reading
+    - fix --mandir option for ./configure
+    - fix SIGSEGV in tcpprep
+    - Add SIGUSR1 and SIGCONT signal support to tcpreplay
+    - Updated tcpreplay man pages
+    - Remove need for math.h/libm
+
+01/07/2003: Version 1.4.beta2
+    - Major updates to configure script
+    - Remove unneeded memcpy() for non-strict aligned architectures
+        for added performance boost
+    - Switch to libpcap for reading packets
+    - Fix portability issues with tcpprep cache files
+
+12/23/2002: Version 1.4.beta1
+    - Remove libnet 1.0 support
+    - Start a quality FAQ for all programs
+    - Add support for detecting libpcap in autoconf
+    - Add pcapmerge to makefile and port to non-BSD OS's
+    - Write pcapmerge manpage
+    - Variety of small configure/makefile improvements
+
+12/13/2002: Version 1.3.0
+    - Re-release 1.3.beta6 as 1.3.0
+
+11/22/2002: Version 1.3.beta6
+    - Improve cross platform compatibility of test subsystem
+    - Fix bug in Makefile which caused possible failures of clean/distclean
+    - Fix bug with CCFLAGS when using --with-debug
+    - Fix bug with -x/-X which would drop/send all packets in certain 
+        conditions
+    - Update libredblack to 1.2 (latest)
+    - Add support for OSX
+    - Add --with-testnic and --with-testnic2 to allow end user to specify
+        specific network cards to be used for 'make test'
+    - Fixes SIGBUS errors on SPARC
+
+11/08/2002: Version 1.3-beta5
+    - Add testing subsystem
+    - Fix segfault when we don't send a packet
+    - Improve debug output support in dbg()
+
+10/21/2002: Version 1.3-beta4
+    - Updated tcpprep man page with -x and -X options
+    - Now supports (again) the include/exclude options in the config file
+    - Fixed -x|-X sanity check in tcpprep/tcpreplay
+
+10/13/2002: Version 1.3-beta3
+    - Fix compile of list.c under FreeBSD 4.7 and others
+    - Add -x|-X to tcpprep
+    - Modify cache file format to be 2 bits/packet to allow caching of
+        -x|-X args (dropping packets)
+    - Modularize some more code
+
+10/08/2002: Version 1.3-beta2
+    - Fix ./configure bug w/ INET_ATON and INET_ADDR
+    - Add support for filtering packets to send based on
+        IP address or packet number (-x & -X)
+    - Move a lot of code from tcpreplay.c to do_packets.c
+    - Update tcpreplay man page
+
+10/03/2002: Version 1.3-beta1
+    - Add support for randomizing IP addresses (-s)
+    - Update tcpreplay man page
+    - Fix problem with checksums after untruncate
+
+08/21/2002: Version 1.2a
+    - Fix compile bug in tree.c w/ libnet 1.1
+    - Sync tcpprep version to tcpreplay
+
+08/19/2002: Version 1.2
+    - Configuration files specified via -f
+    - Now requires a recent version of AutoConf (2.53)
+    - Added support for Libnet 1.1.x (requires beta8 or better)
+    - Added -V switch to print version info (tcpprep & tcpreplay)
+    - Added CIDR dual-nic support to tcpreplay. 
+    - Fix for -I in tcpreplay when only using a single NIC.
+    - Remove requirement for libpcap in tcpprep.  We're now
+        100% libpcap independant.
+    - tcpprep now supports snoop files.
+    - Added -u flag to untruncate IP packets (pad/trunc)
+    - Fixed --with-debug configure option
+    - Added RPM .spec file
+    - Added -M flag to ignore martian IP packets
+    - Now auto-detects snoop/pcap files.  Remove -S flag from tcpprep and
+        tcpreplay
+    - tcpprep now detects servers via ICMP port unreachable
+    - Improve usefulness of -h
+    - Rename -I to -v in tcpprep
+
+06/17/2002: Version 1.1
+    - Major rewrite
+    - Support multiple nics
+    - Better control over packet rates
+    - Added support for snoop capture files
+    - Includes tcpprep and capinfo commands

+ 33 - 0
Docs/.svn/text-base/CREDIT.svn-base

@@ -0,0 +1,33 @@
+$Id$ 
+
+Here's a list of people in no particular order who have kindly submitted
+patches or code snippets for me to use in tcpreplay.
+
+Branden Moore <bmoore-at-cse.nd.edu>
+	- Patch to pad truncated packets
+	- Patch to allow specifying a destination MAC w/ only a single NIC
+
+Scott Mace <smace@intt.org>
+	- Patch for tcpreplay to support CIDR mode
+	- Patch for ignoring martian IP packets 
+
+Jeffrey Guttenfelder <guttenfelder@sourceforge.net>
+        - Code for pausing/restarting tcpreplay via signals.
+
+John Carlson
+        - Patch for improved timerdiv() accuracy
+
+Frey Kuo <kero@3sheep.com>
+        - Patch to replace pause option with packets/sec
+
+Seth Robertson (seth at sysd dot com)
+        - Patch to allow replaying of live traffic
+
+Nick Mathewson <nickm@freehaven.net>
+	- Kindly giving me his BSD licensed implimentation of poll()
+	  using select() so I don't have to worry about cross platform
+	  issues.
+          
+Denis McLaughlin <denism@cyberus.ca>
+        - Patch to allow TCP/UDP port translation
+

File diff suppressed because it is too large
+ 2277 - 0
Docs/.svn/text-base/FAQ.lyx.svn-base


+ 122 - 0
Docs/.svn/text-base/HACKING.svn-base

@@ -0,0 +1,122 @@
+$Id$
+
+                          Guide to Hacking Tcpreplay
+
+[Note: Pay attention to the last update date at the top of this file.  If it
+was significantly long ago, this document may be out of date.]
+
+0. Contributing Code
+
+If you contribute code the following will happen:
+    a) You will be given credit in the CREDITS file
+    b) Your code will be licensed under the same license as that of tcpreplay
+    c) You will be assigning your copyright to me
+
+I do this for a simple reason: keep things simple for me.
+
+1. Introduction
+
+If you're reading this to find out how to add a new feature or fix a bug in
+tcpreplay or tcpprep, then you've come to the right place.  This isn't the
+place to find answers regarding how to use tcpreplay, the meaning of life,
+etc.
+
+2. File Layout
+
+The file layout is pretty simple:
+
+/       - Code, header files, autoconf stuff
+/Docs   - Where to find documentation
+/test   - Test scripts and stuff which is used during 'make test'
+/man    - Unix man pages which get copied to $MANPATH
+
+3. Adding support for additional DLTs (Data Link Types)
+
+There are a number of files/functions that need to be touched to add support
+for a new DLT to tcpreplay and tcpprep.  Note that for a patch to be
+accepted, BOTH tcpreplay and tcpprep need to be updated to support the new
+DLT.
+
+3a) dlt.h
+Two things need to be added here:
+    - A structure defining the header
+    - A #define for the length of the header
+
+    example for DLT_CHDLC (Cisco HDLC):
+    
+/* Cisco HDLC has a simple 32 bit header */
+#define CISCO_HDLC_LEN 4
+struct cisco_hdlc_header {
+    u_int16_t address;
+    u_int16_t protocol;
+}
+
+3b) tcpreplay.c
+You will need to edit validate_l2() to process the DLT type as defined by
+pcap-bpf.h which is included with libpcap.  The key here is that tcpreplay
+needs to be able to generate a valid 802.3 ethernet frame.  Basically
+validate_l2() has to make sure that between the existing Layer 2 header (if
+any) and the user supplied arguments (-2, -I, -J, -K and -k) that enough
+information is available.  Generally this means one of:
+    - The DLT already has a valid header
+    - User specified their own complete header via -2
+    - The existing header + user specified MAC addresses are enough
+
+validate_l2() also calcuates the 'maxpacket' which is the maximum size of a
+packet that we can send out of the interface.  Generally this is the length
+of the Layer 2 header + MTU.  You shouldn't need to change anything here.
+
+3c) edit_packet.c
+Next, you'll have to edit rewrite_l2() to add support for rewriting the
+Layer 2 header from your DLT to a standard 802.3 header.  Note that
+do_packets.c will automatically fill out the source/destination MAC address
+if the appropriate flag is used (-I, -J, -K and -k) so there is no need to
+copy those values over here.
+
+3d) tcpprep.c
+Look at process_raw_packets().  Should be painfully obvious what do do here.
+
+3e) dlt_names.h
+Look in dlt_names.h and make sure your DLT type is listed here.  Note that
+this file is generated by scripts/dlt2name.pl.  If it's not listed here,
+your best bet is to edit scripts/dlt2name.pl and list it in the %known hash
+and then run:
+    make dlt_names
+
+Note that editing dlt_names.h is NOT going to work, since it will get 
+overwritten the next time it is regenerated.
+
+4. Hacking tcprewrite
+
+tcprewrite order of execution:
+
+Figure out if input file's DLT is supported
+
+foreach (packet) {
+	Update packet timestamp based on modifier
+	
+	Decide packet path via cache or CIDR lookup
+	
+	if (a Layer 2 header is specified) {
+	    if (existing Layer 2 header) {
+	        strip existing Layer 2 header
+	    }
+	    prepend specified Layer 2 header
+	}
+	
+	if (primary path or single path) {
+	    re-write MAC addresses
+	    re-write IP addresses
+	    re-write Ports
+	} else if (secondary path) {
+	    re-write MAC addresses
+	    re-write IP addresses
+	    re-write Ports
+	}
+	
+	pad or truncate packet
+	
+	fix checksums
+	
+	write packet to outfile
+}

+ 24 - 0
Docs/.svn/text-base/INSTALL.svn-base

@@ -0,0 +1,24 @@
+$Id$
+
+You'll need:
+
+- libnet 1.1.x (1.1.1 or greater is recommended)
+http://www.packetfactory.net/Projects/libnet/
+
+- libpcap >= 0.6 (0.7 or greater is recommended)
+http://www.tcpdump.org/
+
+- libpcapnav >= 0.4 (Optional. If you want the jump to byte offset feature)
+http://netdude.sf.net/
+
+- tcpdump (Also optional. If you want packet decoding of sent packets)
+http://www.tcpdump.org/
+
+Run:
+./configure ; make
+
+Run as root:
+make test -i    (optional)
+make install
+
+For more detailed information, see the FAQ.

+ 32 - 0
Docs/.svn/text-base/LICENSE.svn-base

@@ -0,0 +1,32 @@
+Copyright (c) 2001-2004 Aaron Turner, Matt Bing.  All rights reserved.
+
+Some portions of code are:
+Copyright(c) 1999 Anzen Computing. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the names of the copyright owners nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+4. All advertising materials mentioning features or use of this software
+   must display the following acknowledgement:
+       This product includes software developed by Anzen Computing, Inc.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 40 - 0
Docs/.svn/text-base/Makefile.svn-base

@@ -0,0 +1,40 @@
+MAKEFLAGS=-s
+
+all: images pdf txt ps rmtemp html
+
+images:
+	fig2dev -L eps flowheader.fig flowheader.eps
+
+tex: images
+	lyx -e latex FAQ.lyx
+	lyx -e latex flowreplay.lyx
+
+dvi: tex 
+	texi2dvi FAQ.tex
+	texi2dvi flowreplay.tex
+
+html: tex 
+	latex2html -nonavigation -no_subdir -split 0 -show_section_numbers FAQ.tex
+	latex2html -nonavigation -no_subdir -split 0 -show_section_numbers flowreplay.tex
+
+
+pdf: dvi
+	dvipdfm FAQ.dvi
+	dvipdfm flowreplay.dvi
+
+txt:
+	lyx -e text FAQ.lyx
+	lyx -e text flowreplay.lyx
+
+ps: dvi
+	dvips -o FAQ.ps FAQ.dvi
+	dvips -o flowreplay.ps flowreplay.dvi
+
+rmtemp:
+	rm -f labels.pl *.log *.toc WARNINGS *.aux index.html 
+
+clean: rmtemp
+	rm -f *~
+
+distclean: rmtemp clean
+	rm -f *.html *.pdf *.txt *.ps *.dvi *.tex  *.css images.pl img1.png *.eps

+ 47 - 0
Docs/.svn/text-base/TODO.svn-base

@@ -0,0 +1,47 @@
+This is a general list of things which should/could/may be done.
+If any of these features interest you let me know- especially if you're
+willing and able to help code it.
+
+- Look at VLAN packets
+    - others non-vanilla types?
+    - Add tags?  Remove tags?  Change tags?
+
+- Add support for setting the ethernet protocol field so we can use
+    -I, -K to fill out an entire ethernet header w/o using -2
+
+- Add a secondary interface full layer two rewrite option
+
+- Fix MAC rewriting to allow sending packets with a MAC of 00:00:00:00:00:00
+
+- Add support for more linktypes (Prism Monitor, 802.11, etc)
+    - Make it easier for others to add support for others
+
+- Rip out packet munger from tcpreplay and put it into another tool so
+  that tcpreplay can be more optimized
+    - perhaps use libnetdude?
+    - make into a library?
+    - definately put it into a seperate binary
+
+- Improve config file format
+  - better variable names
+  - use "var: value" format
+  - have tcpreplay, tcpprep, tcprewrite sections
+
+- Add support for dual-nic send on one intf, wait for packet, send next.
+  would be really useful for testing the effectiveness of how well an IPS
+  detects and blocks attacks.
+
+- Support fragrouter like features 
+    - basic IP fragmenation
+    - TCP fudging 
+    - then more advanced stuff
+
+- Support connection tracking and generating 3way handshake for connections
+  missing them.
+
+- Bump Syn/Ack numbers by a random or given value so that running 
+  the same pcap will behave as different streams.
+
+- Improve flowreplay so it actually works
+
+- IPv6 support?

+ 92 - 0
Docs/.svn/text-base/flowheader.fig.svn-base

@@ -0,0 +1,92 @@
+#FIG 3.2
+Landscape
+Center
+Inches
+Letter  
+100.00
+Single
+-2
+1200 2
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 6000 3150 6000 3450
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 6000 3450 6000 3750
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3600 2850 8400 2850
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3600 3150 8400 3150
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3600 3450 8400 3450
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3600 3750 8400 3750
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3600 2550 8400 2550 8400 4350 3600 4350 3600 2550
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 7200 3150 7200 3450
+2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2
+	 3600 4050 8400 4050
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3600 4950 8400 4950 8400 5250 3600 5250 3600 4950
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 4800 5250 4800 5550
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3600 5550 8400 5550
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3600 5250 8400 5250 8400 6150 3600 6150 3600 5250
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3600 1350 8400 1350 8400 1950 3600 1950 3600 1350
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3600 1650 8400 1650
+2 2 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 5
+	 3600 6750 8400 6750 8400 7950 3600 7950 3600 6750
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3600 6150 8400 6150 8400 6750 3600 6750 3600 6150
+2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2
+	 3600 6450 8400 6450
+2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2
+	 3600 5850 8400 5850
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3600 450 8400 450
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3600 150 8400 150 8400 750 3600 750 3600 150
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 4800 150 4800 450
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 6000 150 6000 450
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 7200 150 7200 450
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 6000 5250 6000 5550
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 6000 1650 6000 1950
+4 0 0 50 0 0 12 0.0000 4 135 840 4350 3375 IP Protocol\001
+4 0 0 50 0 0 12 0.0000 4 180 1380 5250 2775 Client (Source) IP\001
+4 0 0 50 0 0 12 0.0000 4 180 1785 5100 3075 Server (Destination) IP\001
+4 0 0 50 0 0 12 0.0000 4 180 1725 3900 3675 Client Port/ICMP Type\001
+4 0 0 50 0 0 12 0.0000 4 135 1785 6375 3675 Server Port/ICMP Code\001
+4 0 0 50 0 0 12 0.0000 4 180 420 6375 3375 Flags\001
+4 0 0 50 0 0 12 0.0000 4 135 660 7350 3375 Instance\001
+4 0 0 50 0 0 12 0.0000 4 180 1260 8625 5100 Flag 1: Direction\001
+4 0 0 50 0 0 12 0.0000 4 180 1365 8625 2775 Flag 1: Last Index\001
+4 0 0 50 0 0 12 0.0000 4 180 1035 8625 3000 Flag 2: Ignore\001
+4 0 0 50 0 0 12 0.0000 4 180 1620 8625 3225 Flag 3: Server Socket\001
+4 0 0 50 0 0 12 0.0000 4 180 1035 8625 5325 Flag 2: Ignore\001
+4 0 0 50 0 0 12 0.0000 4 180 2100 4950 5175 Data Length of This Stream\001
+4 0 0 50 0 0 12 0.0000 4 180 420 3675 5475 Flags\001
+4 0 0 50 0 0 12 0.0000 4 135 2100 4875 3975 Offset to First Data Stream\001
+4 0 0 50 0 0 12 0.0000 4 180 2040 8625 5775 Flag 4: Urgent Data Exists\001
+4 0 0 50 0 0 12 0.0000 4 180 1125 5400 1575 Magic Number\001
+4 0 0 50 0 0 12 0.0000 4 135 960 5475 7350 Data Stream\001
+4 0 0 50 0 0 12 0.0000 4 180 2235 4950 6375 Offset to Next Data Segment\001
+4 0 0 50 0 0 12 0.0000 4 135 915 5475 675 32 Bit Word\001
+4 0 0 50 0 0 12 0.0000 4 135 450 3975 375 8 Bits\001
+4 0 0 50 0 0 12 0.0000 4 180 705 5100 5475 Urg Data\001
+4 0 0 50 0 0 12 0.0000 4 135 720 6825 5475 Reserved\001
+4 0 0 50 0 0 12 0.0000 4 180 840 5625 5775 Timestamp\001
+4 0 0 50 0 0 12 0.0000 4 135 945 5475 6675 In This Flow\001
+4 0 0 50 0 0 12 0.0000 4 180 1305 5325 2475 Flow Index Entry\001
+4 0 0 50 0 0 12 0.0000 4 135 1560 5250 4875 Data Stream Header\001
+4 0 0 50 0 0 12 0.0000 4 180 1635 5250 1275 Flowprep File Header\001
+4 0 0 50 0 0 12 0.0000 4 180 2055 8625 5550 Flag 3: More Data Streams\001
+4 0 0 50 0 0 12 0.0000 4 135 720 6900 1875 Reserved\001
+4 0 0 50 0 0 12 0.0000 4 135 600 4575 1875 Version\001

File diff suppressed because it is too large
+ 1125 - 0
Docs/.svn/text-base/flowreplay.lyx.svn-base


+ 5 - 0
Docs/.svn/wcprops/CHANGELOG.svn-work

@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 59
+/svn/!svn/ver/1133/tcpreplay/branches/stable/Docs/CHANGELOG
+END

+ 5 - 0
Docs/.svn/wcprops/CREDIT.svn-work

@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 55
+/svn/!svn/ver/769/tcpreplay/branches/stable/Docs/CREDIT
+END

+ 5 - 0
Docs/.svn/wcprops/FAQ.lyx.svn-work

@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 56
+/svn/!svn/ver/769/tcpreplay/branches/stable/Docs/FAQ.lyx
+END

+ 5 - 0
Docs/.svn/wcprops/HACKING.svn-work

@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 56
+/svn/!svn/ver/769/tcpreplay/branches/stable/Docs/HACKING
+END

+ 5 - 0
Docs/.svn/wcprops/INSTALL.svn-work

@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 56
+/svn/!svn/ver/769/tcpreplay/branches/stable/Docs/INSTALL
+END

+ 5 - 0
Docs/.svn/wcprops/LICENSE.svn-work

@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 56
+/svn/!svn/ver/769/tcpreplay/branches/stable/Docs/LICENSE
+END

+ 5 - 0
Docs/.svn/wcprops/Makefile.svn-work

@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 57
+/svn/!svn/ver/769/tcpreplay/branches/stable/Docs/Makefile
+END

+ 5 - 0
Docs/.svn/wcprops/TODO.svn-work

@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 53
+/svn/!svn/ver/769/tcpreplay/branches/stable/Docs/TODO
+END

+ 5 - 0
Docs/.svn/wcprops/flowheader.fig.svn-work

@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/svn/!svn/ver/769/tcpreplay/branches/stable/Docs/flowheader.fig
+END

+ 5 - 0
Docs/.svn/wcprops/flowreplay.lyx.svn-work

@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/svn/!svn/ver/769/tcpreplay/branches/stable/Docs/flowreplay.lyx
+END

+ 277 - 0
Docs/CHANGELOG

@@ -0,0 +1,277 @@
+$Id: CHANGELOG 1133 2005-02-09 01:31:16Z aturner $
+
+02/09/2005: Version 2.3.3
+    - Fix port rewriting feature on little-endian systems
+    - configure now properly handles --with-libnet and --with-libpcap
+
+11/08/2004: Version 2.3.2
+    - When sending via -1, report which interface the packet will exit
+    - Fix bug when caplen > packet len
+    - Allow rewriting of Layer 2 via -2 for Cisco HDLC (DLT_CHDLC)
+
+09/19/2004: Version 2.3.1
+    - Fix bug with fakepcap.c which appeared on systems using an older
+      version of libpcap (such as Red Hat 9.0)
+    - Don't die when setting STDERR to non-blocking
+
+09/05/2004: Version 2.3.0
+    - Fix longstanding endian bug in cache files on little endian systems
+      (note that this breaks compatibility w/ existing cache files created
+      on little endian systems)
+    - Add support to tcpreplay and tcpprep for DLT_CHDLC (Cisco HDLC)
+    - Clean up validate_l2() and rewrite_l2()
+    - Write a simple perl script to parse net/bpf.h of DLT values
+    - Teach everything the names of all the current DLT values
+    - Detect if libpcap supports pcap_datalink_val_to_description()
+    - Start printing datalink descriptions instead of DLT values
+    - Remove magic numbers from tcpreplay.c
+    - Add a HACKING document
+
+06/21/2004: Version 2.2.2
+    - tcpprep now supports DLT_RAW and DLT_LINUX_SLL
+    - add makefile target for website docs (FAQ.html, FAQ.pdf, CHANGELOG)
+    - Fix some sanity checks in tcpreplay for processing various DLT types
+      in validate_l2()
+    - Fix -x & -X
+    - Merge in patch from Denis which rewrites TCP/UDP ports via -4
+    - Fix rewrite of source MAC address in single interface mode (bug #975848)
+
+05/16/2004: Version 2.2.1
+    - Fix compile issue under RH9
+    - Fix compile issue when not using --with-debug
+
+05/15/2004: Version 2.2.0
+    - Fix pseudo-NAT (not evaluating all rules and an infinate loop)
+    - Start using strtok_r() in any function to prevent future bugs
+    - Minor updates to tcpprep.1 & tcpreplay.8 man pages
+    - Re-org some functions into different files for better modularity
+    - Clean up of some of the cache comment code
+    - flowreplay man page moved to section 1
+    - Update tcpprep and tcpreplay man pages and the FAQ
+    - Improve documentation regarding pseudo-NAT feature
+    - Fix one output mode which treated all packets as primary
+    - Add endpoint mode (-e) which rewrites all traffic between two IP's
+    - Fix rewrite of IP addresses in ARP requests & replies w/ pseudo-NAT
+    - Fix CIDR matching of 0.0.0.0/0 (all packets) which matched only 
+      255.255.255.255
+    - All CIDR notation now accepts IP addresses w/o requiring /32
+    - non-debug mode now uses -O3 -funroll-loops for better performance
+
+05/01/2004: Version 2.1.1
+    - Fix ntohll/htonll compile error on big endian systems
+
+04/23/2004: Version 2.1.0
+    - Add support for per output interface/file NAT tables 
+    - Add support for using dual output features w/ a single output
+    - Add support to tcpprep for splitting via destination port
+    - Now fully 64bit when tracking number of packets
+    - Fix a bug where sometimes the last few packets are not sent when using
+      a tcpprep cache file
+    - Some code refactorization/cleanup
+    - tcpprep cache files now support user comments
+    - Fix bug where regex optimization was turned always turned off
+
+03/24/2004: Version 2.0.3
+    - Add support for rewriting src mac & Linux SLL loopback frames
+    - Update FAQ
+
+02/25/2004: Version 2.0.2
+    - Fix compile issue in edit_packet.c on strict aligned archs
+
+02/03/2004: Version 2.0.1
+    - Re-organize FAQ and add more content
+    - Add support for "pseudo NAT" (-N) for ARP and IPv4
+    - Code optimization to only run the checksum fixer once per packet
+    - Clean up help (-h) a little
+
+02/01/2004: Version 2.0.0
+    - Remove libpcapnav requirement
+    - Now support libpcapnav >= 0.4
+    - Add -1 to replay one packet at a time (user must hit <ENTER>)
+    - Add tcpdump packet parsing to print packets as sent (-v)
+    - Place flowreplay manpage in correct location
+    - More FAQ updates
+    - Rename 1.5.x as 2.0
+    - Fix/standardize all licensing info.  Still BSD of course.
+    - -T now forces -F
+    - tcpprep now actually accepts -n (client|server)
+    - Update the INSTALL doc
+    - Remove the Docs/README... the FAQ has replaced it.
+
+12/10/2003: Version 1.5.alpha6
+    - Add BPF filter support to tcpprep and tcpreplay (-x F:"filter")
+    - Update the FAQ
+    - Add two new auto modes to tcpprep (client and server)
+    - Make clean no longer wipes out the compiled documentation in Docs
+    - Add support for replaying live traffic
+    - Add bridge mode
+    - Add -L to limit the total number of packets to send
+
+11/03/2003: Version 1.5.alpha5
+    - Add -T to truncate packets > MTU so they can be sent
+    - Now fixes ICMP checksums as appropriate
+    - Updated FAQ
+    - Updated flowreplay design doc
+    - Merge packetrate code from 1.4.5
+    - Fix compile issues under Libnet 1.1.1
+    - --with-debug now enables debuging during 'make test'
+    - Fix various Solaris compatibility bugs
+    - Add data dump mode which dumps layer 7 data to the file (-D)
+    - Now requires libpcapnav
+    - Allow to jump X bytes into the pcap and start replaying packets (-o)
+    - Can now split traffic/data into files (-w & -W)
+
+07/16/2003: Version 1.5.alpha4
+    - Split do_packets.c & do_packets() -> edit_packet.c & rewrite_l2()
+    - Don't die when packet > MTU, just skip
+    - Fix a ptr bug in do_packets() w/ the ethernet header
+    - Merge Ctrl-C fix from 1.4.4 for libnet_adv_write_link() 
+        in do_packets.c
+    - Rewrite flowreplay design document
+    - Fix an integer overflow in packet_stats() in tcpreplay.c
+    - tcpreplay's -2 now accepts a hex string rather then a filename
+    - tcpreplay now can output to a file (-w <file>)
+    - fix bug in checksum fixer
+    - Add support for files > 2GB
+
+06/06/2003: Version 1.5.alpha3
+    - Add support for Linux Cooked Sockets (SLL) format rewriting
+    - Added a flowreplay design doc in Docs/
+    - A lot more work on flowreplay
+    - Start work on read-ahead buffering of packets in flowreplay        
+    - Add support for specifying MTU.
+    - Update tcpreplay man page
+    - Fix compile of do_packets() under OpenBSD
+    - configure now checks for libpcap >= 0.6 (required for SLL)
+
+
+05/29/2003: Version 1.5.alpha2
+    - Add -F to force checksum fixing
+    - Fix packet corruption when not using -2
+    - Improve timerdiv() code
+    - Port from libredblack to OpenBSD RB_*
+    - Add flowreplay application
+    - Fix a bunch of compiler warnings about miss-matched sign
+    - IP & layer 4 checksums now work when IP options exist (tcpreplay)
+    - Updated FAQ
+    - Fix spec file
+
+05/07/2003: Version 1.5.alpha1
+    - Add layer2 rewriting
+
+05/07/2002: Branch 1.4.x tree
+
+05/04/2003: Version 1.4.beta5
+    - Fixed a one-off bug when replaying tcpprep cache files
+    - Fixed a small reporting bug in tcpprep
+
+05/02/2003: Version 1.4.beta4
+    - significantly improved timing accuracy between packets
+    - fix bug with writing only about 1/2 of cache data which caused
+        tcpreplay to bitch
+    - updated 'make test' standard cache files
+    - improved alignment of cache header (20bytes vs 17bytes)
+
+04/30/2003: Version 1.4.beta3
+    - Specifying a list of packets to include/exclude now works (-x/X P:)
+    - Minor code cleanups (better error messages, etc)
+    - Add -p option to pause a given number of sec/usec between each packet
+    - Ported tcpprep to libpcap
+    - Increase final report resolution to two sig digits
+    - Switch to err.h that we ship rather then system provided err.h
+    - Don't reset timer each time we open a file for reading
+    - fix --mandir option for ./configure
+    - fix SIGSEGV in tcpprep
+    - Add SIGUSR1 and SIGCONT signal support to tcpreplay
+    - Updated tcpreplay man pages
+    - Remove need for math.h/libm
+
+01/07/2003: Version 1.4.beta2
+    - Major updates to configure script
+    - Remove unneeded memcpy() for non-strict aligned architectures
+        for added performance boost
+    - Switch to libpcap for reading packets
+    - Fix portability issues with tcpprep cache files
+
+12/23/2002: Version 1.4.beta1
+    - Remove libnet 1.0 support
+    - Start a quality FAQ for all programs
+    - Add support for detecting libpcap in autoconf
+    - Add pcapmerge to makefile and port to non-BSD OS's
+    - Write pcapmerge manpage
+    - Variety of small configure/makefile improvements
+
+12/13/2002: Version 1.3.0
+    - Re-release 1.3.beta6 as 1.3.0
+
+11/22/2002: Version 1.3.beta6
+    - Improve cross platform compatibility of test subsystem
+    - Fix bug in Makefile which caused possible failures of clean/distclean
+    - Fix bug with CCFLAGS when using --with-debug
+    - Fix bug with -x/-X which would drop/send all packets in certain 
+        conditions
+    - Update libredblack to 1.2 (latest)
+    - Add support for OSX
+    - Add --with-testnic and --with-testnic2 to allow end user to specify
+        specific network cards to be used for 'make test'
+    - Fixes SIGBUS errors on SPARC
+
+11/08/2002: Version 1.3-beta5
+    - Add testing subsystem
+    - Fix segfault when we don't send a packet
+    - Improve debug output support in dbg()
+
+10/21/2002: Version 1.3-beta4
+    - Updated tcpprep man page with -x and -X options
+    - Now supports (again) the include/exclude options in the config file
+    - Fixed -x|-X sanity check in tcpprep/tcpreplay
+
+10/13/2002: Version 1.3-beta3
+    - Fix compile of list.c under FreeBSD 4.7 and others
+    - Add -x|-X to tcpprep
+    - Modify cache file format to be 2 bits/packet to allow caching of
+        -x|-X args (dropping packets)
+    - Modularize some more code
+
+10/08/2002: Version 1.3-beta2
+    - Fix ./configure bug w/ INET_ATON and INET_ADDR
+    - Add support for filtering packets to send based on
+        IP address or packet number (-x & -X)
+    - Move a lot of code from tcpreplay.c to do_packets.c
+    - Update tcpreplay man page
+
+10/03/2002: Version 1.3-beta1
+    - Add support for randomizing IP addresses (-s)
+    - Update tcpreplay man page
+    - Fix problem with checksums after untruncate
+
+08/21/2002: Version 1.2a
+    - Fix compile bug in tree.c w/ libnet 1.1
+    - Sync tcpprep version to tcpreplay
+
+08/19/2002: Version 1.2
+    - Configuration files specified via -f
+    - Now requires a recent version of AutoConf (2.53)
+    - Added support for Libnet 1.1.x (requires beta8 or better)
+    - Added -V switch to print version info (tcpprep & tcpreplay)
+    - Added CIDR dual-nic support to tcpreplay. 
+    - Fix for -I in tcpreplay when only using a single NIC.
+    - Remove requirement for libpcap in tcpprep.  We're now
+        100% libpcap independant.
+    - tcpprep now supports snoop files.
+    - Added -u flag to untruncate IP packets (pad/trunc)
+    - Fixed --with-debug configure option
+    - Added RPM .spec file
+    - Added -M flag to ignore martian IP packets
+    - Now auto-detects snoop/pcap files.  Remove -S flag from tcpprep and
+        tcpreplay
+    - tcpprep now detects servers via ICMP port unreachable
+    - Improve usefulness of -h
+    - Rename -I to -v in tcpprep
+
+06/17/2002: Version 1.1
+    - Major rewrite
+    - Support multiple nics
+    - Better control over packet rates
+    - Added support for snoop capture files
+    - Includes tcpprep and capinfo commands

+ 33 - 0
Docs/CREDIT

@@ -0,0 +1,33 @@
+$Id: CREDIT 767 2004-10-06 12:48:49Z aturner $ 
+
+Here's a list of people in no particular order who have kindly submitted
+patches or code snippets for me to use in tcpreplay.
+
+Branden Moore <bmoore-at-cse.nd.edu>
+	- Patch to pad truncated packets
+	- Patch to allow specifying a destination MAC w/ only a single NIC
+
+Scott Mace <smace@intt.org>
+	- Patch for tcpreplay to support CIDR mode
+	- Patch for ignoring martian IP packets 
+
+Jeffrey Guttenfelder <guttenfelder@sourceforge.net>
+        - Code for pausing/restarting tcpreplay via signals.
+
+John Carlson
+        - Patch for improved timerdiv() accuracy
+
+Frey Kuo <kero@3sheep.com>
+        - Patch to replace pause option with packets/sec
+
+Seth Robertson (seth at sysd dot com)
+        - Patch to allow replaying of live traffic
+
+Nick Mathewson <nickm@freehaven.net>
+	- Kindly giving me his BSD licensed implimentation of poll()
+	  using select() so I don't have to worry about cross platform
+	  issues.
+          
+Denis McLaughlin <denism@cyberus.ca>
+        - Patch to allow TCP/UDP port translation
+

+ 34 - 0
Docs/FAQ.css

@@ -0,0 +1,34 @@
+/* Century Schoolbook font is very similar to Computer Modern Math: cmmi */
+.MATH    { font-family: "Century Schoolbook", serif; }
+.MATH I  { font-family: "Century Schoolbook", serif; font-style: italic }
+.BOLDMATH { font-family: "Century Schoolbook", serif; font-weight: bold }
+
+/* implement both fixed-size and relative sizes */
+SMALL.XTINY		{ font-size : xx-small }
+SMALL.TINY		{ font-size : x-small  }
+SMALL.SCRIPTSIZE	{ font-size : smaller  }
+SMALL.FOOTNOTESIZE	{ font-size : small    }
+SMALL.SMALL		{  }
+BIG.LARGE		{  }
+BIG.XLARGE		{ font-size : large    }
+BIG.XXLARGE		{ font-size : x-large  }
+BIG.HUGE		{ font-size : larger   }
+BIG.XHUGE		{ font-size : xx-large }
+
+/* heading styles */
+H1		{  }
+H2		{  }
+H3		{  }
+H4		{  }
+H5		{  }
+
+/* mathematics styles */
+DIV.displaymath		{ }	/* math displays */
+TD.eqno			{ }	/* equation-number cells */
+
+
+/* document-specific styles come next */
+DIV.navigation		{   }
+DIV.center		{   }
+SPAN.textit		{ font-style: italic  }
+SPAN.arabic		{   }

BIN
Docs/FAQ.dvi


File diff suppressed because it is too large
+ 2346 - 0
Docs/FAQ.html


File diff suppressed because it is too large
+ 2277 - 0
Docs/FAQ.lyx


BIN
Docs/FAQ.pdf


File diff suppressed because it is too large
+ 2028 - 0
Docs/FAQ.ps


File diff suppressed because it is too large
+ 1355 - 0
Docs/FAQ.tex


File diff suppressed because it is too large
+ 1499 - 0
Docs/FAQ.txt


+ 122 - 0
Docs/HACKING

@@ -0,0 +1,122 @@
+$Id: HACKING 767 2004-10-06 12:48:49Z aturner $
+
+                          Guide to Hacking Tcpreplay
+
+[Note: Pay attention to the last update date at the top of this file.  If it
+was significantly long ago, this document may be out of date.]
+
+0. Contributing Code
+
+If you contribute code the following will happen:
+    a) You will be given credit in the CREDITS file
+    b) Your code will be licensed under the same license as that of tcpreplay
+    c) You will be assigning your copyright to me
+
+I do this for a simple reason: keep things simple for me.
+
+1. Introduction
+
+If you're reading this to find out how to add a new feature or fix a bug in
+tcpreplay or tcpprep, then you've come to the right place.  This isn't the
+place to find answers regarding how to use tcpreplay, the meaning of life,
+etc.
+
+2. File Layout
+
+The file layout is pretty simple:
+
+/       - Code, header files, autoconf stuff
+/Docs   - Where to find documentation
+/test   - Test scripts and stuff which is used during 'make test'
+/man    - Unix man pages which get copied to $MANPATH
+
+3. Adding support for additional DLTs (Data Link Types)
+
+There are a number of files/functions that need to be touched to add support
+for a new DLT to tcpreplay and tcpprep.  Note that for a patch to be
+accepted, BOTH tcpreplay and tcpprep need to be updated to support the new
+DLT.
+
+3a) dlt.h
+Two things need to be added here:
+    - A structure defining the header
+    - A #define for the length of the header
+
+    example for DLT_CHDLC (Cisco HDLC):
+    
+/* Cisco HDLC has a simple 32 bit header */
+#define CISCO_HDLC_LEN 4
+struct cisco_hdlc_header {
+    u_int16_t address;
+    u_int16_t protocol;
+}
+
+3b) tcpreplay.c
+You will need to edit validate_l2() to process the DLT type as defined by
+pcap-bpf.h which is included with libpcap.  The key here is that tcpreplay
+needs to be able to generate a valid 802.3 ethernet frame.  Basically
+validate_l2() has to make sure that between the existing Layer 2 header (if
+any) and the user supplied arguments (-2, -I, -J, -K and -k) that enough
+information is available.  Generally this means one of:
+    - The DLT already has a valid header
+    - User specified their own complete header via -2
+    - The existing header + user specified MAC addresses are enough
+
+validate_l2() also calcuates the 'maxpacket' which is the maximum size of a
+packet that we can send out of the interface.  Generally this is the length
+of the Layer 2 header + MTU.  You shouldn't need to change anything here.
+
+3c) edit_packet.c
+Next, you'll have to edit rewrite_l2() to add support for rewriting the
+Layer 2 header from your DLT to a standard 802.3 header.  Note that
+do_packets.c will automatically fill out the source/destination MAC address
+if the appropriate flag is used (-I, -J, -K and -k) so there is no need to
+copy those values over here.
+
+3d) tcpprep.c
+Look at process_raw_packets().  Should be painfully obvious what do do here.
+
+3e) dlt_names.h
+Look in dlt_names.h and make sure your DLT type is listed here.  Note that
+this file is generated by scripts/dlt2name.pl.  If it's not listed here,
+your best bet is to edit scripts/dlt2name.pl and list it in the %known hash
+and then run:
+    make dlt_names
+
+Note that editing dlt_names.h is NOT going to work, since it will get 
+overwritten the next time it is regenerated.
+
+4. Hacking tcprewrite
+
+tcprewrite order of execution:
+
+Figure out if input file's DLT is supported
+
+foreach (packet) {
+	Update packet timestamp based on modifier
+	
+	Decide packet path via cache or CIDR lookup
+	
+	if (a Layer 2 header is specified) {
+	    if (existing Layer 2 header) {
+	        strip existing Layer 2 header
+	    }
+	    prepend specified Layer 2 header
+	}
+	
+	if (primary path or single path) {
+	    re-write MAC addresses
+	    re-write IP addresses
+	    re-write Ports
+	} else if (secondary path) {
+	    re-write MAC addresses
+	    re-write IP addresses
+	    re-write Ports
+	}
+	
+	pad or truncate packet
+	
+	fix checksums
+	
+	write packet to outfile
+}

+ 24 - 0
Docs/INSTALL

@@ -0,0 +1,24 @@
+$Id: INSTALL 767 2004-10-06 12:48:49Z aturner $
+
+You'll need:
+
+- libnet 1.1.x (1.1.1 or greater is recommended)
+http://www.packetfactory.net/Projects/libnet/
+
+- libpcap >= 0.6 (0.7 or greater is recommended)
+http://www.tcpdump.org/
+
+- libpcapnav >= 0.4 (Optional. If you want the jump to byte offset feature)
+http://netdude.sf.net/
+
+- tcpdump (Also optional. If you want packet decoding of sent packets)
+http://www.tcpdump.org/
+
+Run:
+./configure ; make
+
+Run as root:
+make test -i    (optional)
+make install
+
+For more detailed information, see the FAQ.

+ 9 - 6
LICENSE

@@ -1,4 +1,7 @@
-Copyright (c) 1999 Anzen Computing. All rights reserved.
+Copyright (c) 2001-2004 Aaron Turner, Matt Bing.  All rights reserved.
+
+Some portions of code are:
+Copyright(c) 1999 Anzen Computing. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
@@ -9,12 +12,12 @@ are met:
 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
+3. Neither the names of the copyright owners nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+4. All advertising materials mentioning features or use of this software
    must display the following acknowledgement:
-      This product includes software developed by Anzen Computing, Inc.
-4. Neither the name of Anzen Computing, Inc. nor the names of its
-   contributors may be used to endorse or promote products derived
-   from this software without specific prior written permission.
+       This product includes software developed by Anzen Computing, Inc.
 
 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

+ 40 - 0
Docs/Makefile

@@ -0,0 +1,40 @@
+MAKEFLAGS=-s
+
+all: images pdf txt ps rmtemp html
+
+images:
+	fig2dev -L eps flowheader.fig flowheader.eps
+
+tex: images
+	lyx -e latex FAQ.lyx
+	lyx -e latex flowreplay.lyx
+
+dvi: tex 
+	texi2dvi FAQ.tex
+	texi2dvi flowreplay.tex
+
+html: tex 
+	latex2html -nonavigation -no_subdir -split 0 -show_section_numbers FAQ.tex
+	latex2html -nonavigation -no_subdir -split 0 -show_section_numbers flowreplay.tex
+
+
+pdf: dvi
+	dvipdfm FAQ.dvi
+	dvipdfm flowreplay.dvi
+
+txt:
+	lyx -e text FAQ.lyx
+	lyx -e text flowreplay.lyx
+
+ps: dvi
+	dvips -o FAQ.ps FAQ.dvi
+	dvips -o flowreplay.ps flowreplay.dvi
+
+rmtemp:
+	rm -f labels.pl *.log *.toc WARNINGS *.aux index.html 
+
+clean: rmtemp
+	rm -f *~
+
+distclean: rmtemp clean
+	rm -f *.html *.pdf *.txt *.ps *.dvi *.tex  *.css images.pl img1.png *.eps

+ 47 - 0
Docs/TODO

@@ -0,0 +1,47 @@
+This is a general list of things which should/could/may be done.
+If any of these features interest you let me know- especially if you're
+willing and able to help code it.
+
+- Look at VLAN packets
+    - others non-vanilla types?
+    - Add tags?  Remove tags?  Change tags?
+
+- Add support for setting the ethernet protocol field so we can use
+    -I, -K to fill out an entire ethernet header w/o using -2
+
+- Add a secondary interface full layer two rewrite option
+
+- Fix MAC rewriting to allow sending packets with a MAC of 00:00:00:00:00:00
+
+- Add support for more linktypes (Prism Monitor, 802.11, etc)
+    - Make it easier for others to add support for others
+
+- Rip out packet munger from tcpreplay and put it into another tool so
+  that tcpreplay can be more optimized
+    - perhaps use libnetdude?
+    - make into a library?
+    - definately put it into a seperate binary
+
+- Improve config file format
+  - better variable names
+  - use "var: value" format
+  - have tcpreplay, tcpprep, tcprewrite sections
+
+- Add support for dual-nic send on one intf, wait for packet, send next.
+  would be really useful for testing the effectiveness of how well an IPS
+  detects and blocks attacks.
+
+- Support fragrouter like features 
+    - basic IP fragmenation
+    - TCP fudging 
+    - then more advanced stuff
+
+- Support connection tracking and generating 3way handshake for connections
+  missing them.
+
+- Bump Syn/Ack numbers by a random or given value so that running 
+  the same pcap will behave as different streams.
+
+- Improve flowreplay so it actually works
+
+- IPv6 support?

+ 9 - 0
Docs/WARNINGS

@@ -0,0 +1,9 @@
+No implementation found for style `pslatex'
+No implementation found for style `fontenc'
+No implementation found for style `geometry'
+No implementation found for style `graphicx'
+
+The flowreplay.aux file was not found, so sections will not be numbered 
+and cross-references will be shown as icons.
+
+? brace missing for \setlength

+ 278 - 0
Docs/flowheader.eps

@@ -0,0 +1,278 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: flowheader.fig
+%%Creator: fig2dev Version 3.2 Patchlevel 5-alpha5
+%%CreationDate: Thu Feb 10 12:32:01 2005
+%%For: aturner@vodka (Aaron Turner,,,)
+%%BoundingBox: 0 0 430 470
+%Magnification: 1.0000
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+newpath 0 470 moveto 0 0 lineto 430 0 lineto 430 470 lineto closepath clip newpath
+-215.3 477.7 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add
+  4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+  bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+  4 -2 roll mul srgb} bind def
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+$F2psBegin
+10 setmiterlimit
+0 slj 0 slc
+ 0.06000 0.06000 sc
+%
+% Fig objects follow
+%
+% 
+% here starts figure with depth 50
+% Polyline
+0 slj
+0 slc
+7.500 slw
+n 6000 3150 m
+ 6000 3450 l gs col0 s gr 
+% Polyline
+n 6000 3450 m
+ 6000 3750 l gs col0 s gr 
+% Polyline
+n 3600 2850 m
+ 8400 2850 l gs col0 s gr 
+% Polyline
+n 3600 3150 m
+ 8400 3150 l gs col0 s gr 
+% Polyline
+n 3600 3450 m
+ 8400 3450 l gs col0 s gr 
+% Polyline
+n 3600 3750 m
+ 8400 3750 l gs col0 s gr 
+% Polyline
+n 3600 2550 m 8400 2550 l 8400 4350 l 3600 4350 l
+ cp gs col0 s gr 
+% Polyline
+n 7200 3150 m
+ 7200 3450 l gs col0 s gr 
+% Polyline
+ [15 45] 45 sd
+n 3600 4050 m
+ 8400 4050 l gs col0 s gr  [] 0 sd
+% Polyline
+n 3600 4950 m 8400 4950 l 8400 5250 l 3600 5250 l
+ cp gs col0 s gr 
+% Polyline
+n 4800 5250 m
+ 4800 5550 l gs col0 s gr 
+% Polyline
+n 3600 5550 m
+ 8400 5550 l gs col0 s gr 
+% Polyline
+n 3600 5250 m 8400 5250 l 8400 6150 l 3600 6150 l
+ cp gs col0 s gr 
+% Polyline
+n 3600 1350 m 8400 1350 l 8400 1950 l 3600 1950 l
+ cp gs col0 s gr 
+% Polyline
+n 3600 1650 m
+ 8400 1650 l gs col0 s gr 
+% Polyline
+ [15 45] 45 sd
+n 3600 6750 m 8400 6750 l 8400 7950 l 3600 7950 l
+ cp gs col0 s gr  [] 0 sd
+% Polyline
+n 3600 6150 m 8400 6150 l 8400 6750 l 3600 6750 l
+ cp gs col0 s gr 
+% Polyline
+ [15 45] 45 sd
+n 3600 6450 m
+ 8400 6450 l gs col0 s gr  [] 0 sd
+% Polyline
+ [15 45] 45 sd
+n 3600 5850 m
+ 8400 5850 l gs col0 s gr  [] 0 sd
+% Polyline
+n 3600 450 m
+ 8400 450 l gs col0 s gr 
+% Polyline
+n 3600 150 m 8400 150 l 8400 750 l 3600 750 l
+ cp gs col0 s gr 
+% Polyline
+n 4800 150 m
+ 4800 450 l gs col0 s gr 
+% Polyline
+n 6000 150 m
+ 6000 450 l gs col0 s gr 
+% Polyline
+n 7200 150 m
+ 7200 450 l gs col0 s gr 
+% Polyline
+n 6000 5250 m
+ 6000 5550 l gs col0 s gr 
+% Polyline
+n 6000 1650 m
+ 6000 1950 l gs col0 s gr 
+/Times-Roman ff 180.00 scf sf
+4350 3375 m
+gs 1 -1 sc (IP Protocol) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+5250 2775 m
+gs 1 -1 sc (Client \(Source\) IP) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+5100 3075 m
+gs 1 -1 sc (Server \(Destination\) IP) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+3900 3675 m
+gs 1 -1 sc (Client Port/ICMP Type) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+6375 3675 m
+gs 1 -1 sc (Server Port/ICMP Code) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+6375 3375 m
+gs 1 -1 sc (Flags) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+7350 3375 m
+gs 1 -1 sc (Instance) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+8625 5100 m
+gs 1 -1 sc (Flag 1: Direction) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+8625 2775 m
+gs 1 -1 sc (Flag 1: Last Index) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+8625 3000 m
+gs 1 -1 sc (Flag 2: Ignore) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+8625 3225 m
+gs 1 -1 sc (Flag 3: Server Socket) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+8625 5325 m
+gs 1 -1 sc (Flag 2: Ignore) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+4950 5175 m
+gs 1 -1 sc (Data Length of This Stream) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+3675 5475 m
+gs 1 -1 sc (Flags) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+4875 3975 m
+gs 1 -1 sc (Offset to First Data Stream) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+8625 5775 m
+gs 1 -1 sc (Flag 4: Urgent Data Exists) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+5400 1575 m
+gs 1 -1 sc (Magic Number) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+5475 7350 m
+gs 1 -1 sc (Data Stream) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+4950 6375 m
+gs 1 -1 sc (Offset to Next Data Segment) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+5475 675 m
+gs 1 -1 sc (32 Bit Word) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+3975 375 m
+gs 1 -1 sc (8 Bits) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+5100 5475 m
+gs 1 -1 sc (Urg Data) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+6825 5475 m
+gs 1 -1 sc (Reserved) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+5625 5775 m
+gs 1 -1 sc (Timestamp) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+5475 6675 m
+gs 1 -1 sc (In This Flow) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+5325 2475 m
+gs 1 -1 sc (Flow Index Entry) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+5250 4875 m
+gs 1 -1 sc (Data Stream Header) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+5250 1275 m
+gs 1 -1 sc (Flowprep File Header) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+8625 5550 m
+gs 1 -1 sc (Flag 3: More Data Streams) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+6900 1875 m
+gs 1 -1 sc (Reserved) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+4575 1875 m
+gs 1 -1 sc (Version) col0 sh gr
+% here ends figure;
+$F2psEnd
+rs
+showpage
+%%Trailer
+%EOF

+ 92 - 0
Docs/flowheader.fig

@@ -0,0 +1,92 @@
+#FIG 3.2
+Landscape
+Center
+Inches
+Letter  
+100.00
+Single
+-2
+1200 2
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 6000 3150 6000 3450
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 6000 3450 6000 3750
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3600 2850 8400 2850
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3600 3150 8400 3150
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3600 3450 8400 3450
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3600 3750 8400 3750
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3600 2550 8400 2550 8400 4350 3600 4350 3600 2550
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 7200 3150 7200 3450
+2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2
+	 3600 4050 8400 4050
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3600 4950 8400 4950 8400 5250 3600 5250 3600 4950
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 4800 5250 4800 5550
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3600 5550 8400 5550
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3600 5250 8400 5250 8400 6150 3600 6150 3600 5250
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3600 1350 8400 1350 8400 1950 3600 1950 3600 1350
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3600 1650 8400 1650
+2 2 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 5
+	 3600 6750 8400 6750 8400 7950 3600 7950 3600 6750
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3600 6150 8400 6150 8400 6750 3600 6750 3600 6150
+2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2
+	 3600 6450 8400 6450
+2 1 2 1 0 7 50 0 -1 3.000 0 0 -1 0 0 2
+	 3600 5850 8400 5850
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 3600 450 8400 450
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+	 3600 150 8400 150 8400 750 3600 750 3600 150
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 4800 150 4800 450
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 6000 150 6000 450
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 7200 150 7200 450
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 6000 5250 6000 5550
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+	 6000 1650 6000 1950
+4 0 0 50 0 0 12 0.0000 4 135 840 4350 3375 IP Protocol\001
+4 0 0 50 0 0 12 0.0000 4 180 1380 5250 2775 Client (Source) IP\001
+4 0 0 50 0 0 12 0.0000 4 180 1785 5100 3075 Server (Destination) IP\001
+4 0 0 50 0 0 12 0.0000 4 180 1725 3900 3675 Client Port/ICMP Type\001
+4 0 0 50 0 0 12 0.0000 4 135 1785 6375 3675 Server Port/ICMP Code\001
+4 0 0 50 0 0 12 0.0000 4 180 420 6375 3375 Flags\001
+4 0 0 50 0 0 12 0.0000 4 135 660 7350 3375 Instance\001
+4 0 0 50 0 0 12 0.0000 4 180 1260 8625 5100 Flag 1: Direction\001
+4 0 0 50 0 0 12 0.0000 4 180 1365 8625 2775 Flag 1: Last Index\001
+4 0 0 50 0 0 12 0.0000 4 180 1035 8625 3000 Flag 2: Ignore\001
+4 0 0 50 0 0 12 0.0000 4 180 1620 8625 3225 Flag 3: Server Socket\001
+4 0 0 50 0 0 12 0.0000 4 180 1035 8625 5325 Flag 2: Ignore\001
+4 0 0 50 0 0 12 0.0000 4 180 2100 4950 5175 Data Length of This Stream\001
+4 0 0 50 0 0 12 0.0000 4 180 420 3675 5475 Flags\001
+4 0 0 50 0 0 12 0.0000 4 135 2100 4875 3975 Offset to First Data Stream\001
+4 0 0 50 0 0 12 0.0000 4 180 2040 8625 5775 Flag 4: Urgent Data Exists\001
+4 0 0 50 0 0 12 0.0000 4 180 1125 5400 1575 Magic Number\001
+4 0 0 50 0 0 12 0.0000 4 135 960 5475 7350 Data Stream\001
+4 0 0 50 0 0 12 0.0000 4 180 2235 4950 6375 Offset to Next Data Segment\001
+4 0 0 50 0 0 12 0.0000 4 135 915 5475 675 32 Bit Word\001
+4 0 0 50 0 0 12 0.0000 4 135 450 3975 375 8 Bits\001
+4 0 0 50 0 0 12 0.0000 4 180 705 5100 5475 Urg Data\001
+4 0 0 50 0 0 12 0.0000 4 135 720 6825 5475 Reserved\001
+4 0 0 50 0 0 12 0.0000 4 180 840 5625 5775 Timestamp\001
+4 0 0 50 0 0 12 0.0000 4 135 945 5475 6675 In This Flow\001
+4 0 0 50 0 0 12 0.0000 4 180 1305 5325 2475 Flow Index Entry\001
+4 0 0 50 0 0 12 0.0000 4 135 1560 5250 4875 Data Stream Header\001
+4 0 0 50 0 0 12 0.0000 4 180 1635 5250 1275 Flowprep File Header\001
+4 0 0 50 0 0 12 0.0000 4 180 2055 8625 5550 Flag 3: More Data Streams\001
+4 0 0 50 0 0 12 0.0000 4 135 720 6900 1875 Reserved\001
+4 0 0 50 0 0 12 0.0000 4 135 600 4575 1875 Version\001

+ 172 - 0
Docs/flowreplay.css

@@ -0,0 +1,172 @@
+/* Century Schoolbook font is very similar to Computer Modern Math: cmmi */
+.MATH    { font-family: "Century Schoolbook", serif; }
+.MATH I  { font-family: "Century Schoolbook", serif; font-style: italic }
+.BOLDMATH { font-family: "Century Schoolbook", serif; font-weight: bold }
+
+/* implement both fixed-size and relative sizes */
+SMALL.XTINY		{ font-size : xx-small }
+SMALL.TINY		{ font-size : x-small  }
+SMALL.SCRIPTSIZE	{ font-size : smaller  }
+SMALL.FOOTNOTESIZE	{ font-size : small    }
+SMALL.SMALL		{  }
+BIG.LARGE		{  }
+BIG.XLARGE		{ font-size : large    }
+BIG.XXLARGE		{ font-size : x-large  }
+BIG.HUGE		{ font-size : larger   }
+BIG.XHUGE		{ font-size : xx-large }
+
+/* heading styles */
+H1		{  }
+H2		{  }
+H3		{  }
+H4		{  }
+H5		{  }
+
+/* mathematics styles */
+DIV.displaymath		{ }	/* math displays */
+TD.eqno			{ }	/* equation-number cells */
+
+
+/* document-specific styles come next */
+DIV.navigation		{   }
+DIV.center		{   }
+DIV.quote		{   }
+SPAN.textit		{ font-style: italic  }
+SPAN.arabic		{   }
+#hue100		{ color: #000000;  }
+#hue102		{ color: #000000;  }
+#hue104		{ color: #000000;  }
+#hue106		{ color: #000000;  }
+#hue108		{ color: #000000;  }
+#hue110		{ color: #000000;  }
+#hue112		{ color: #000000;  }
+#hue114		{ color: #000000;  }
+#hue117		{ color: #000000;  }
+#hue119		{ color: #000000;  }
+#hue121		{ color: #000000;  }
+#hue123		{ color: #000000;  }
+#hue126		{ color: #000000;  }
+#hue128		{ color: #000000;  }
+#hue133		{ color: #000000;  }
+#hue135		{ color: #000000;  }
+#hue139		{ color: #000000;  }
+#hue141		{ color: #000000;  }
+#hue143		{ color: #000000;  }
+#hue146		{ color: #000000;  }
+#hue150		{ color: #000000;  }
+#hue153		{ color: #000000;  }
+#hue157		{ color: #000000;  }
+#hue159		{ color: #000000;  }
+#hue162		{ color: #000000;  }
+#hue164		{ color: #000000;  }
+#hue166		{ color: #000000;  }
+#hue168		{ color: #000000;  }
+#hue170		{ color: #000000;  }
+#hue173		{ color: #000000;  }
+#hue175		{ color: #000000;  }
+#hue177		{ color: #000000;  }
+#hue179		{ color: #000000;  }
+#hue181		{ color: #000000;  }
+#hue184		{ color: #000000;  }
+#hue186		{ color: #000000;  }
+#hue188		{ color: #000000;  }
+#hue190		{ color: #000000;  }
+#hue193		{ color: #000000;  }
+#hue195		{ color: #000000;  }
+#hue197		{ color: #000000;  }
+#hue200		{ color: #000000;  }
+#hue202		{ color: #000000;  }
+#hue204		{ color: #000000;  }
+#hue207		{ color: #000000;  }
+#hue210		{ color: #000000;  }
+#hue212		{ color: #000000;  }
+#hue215		{ color: #000000;  }
+#hue218		{ color: #000000;  }
+#hue220		{ color: #000000;  }
+#hue231		{ color: #000000;  }
+#hue233		{ color: #000000;  }
+#hue238		{ color: #000000;  }
+#hue240		{ color: #000000;  }
+#hue247		{ color: #000000;  }
+#hue250		{ color: #000000;  }
+#hue252		{ color: #000000;  }
+#hue256		{ color: #000000;  }
+#hue258		{ color: #000000;  }
+#hue260		{ color: #000000;  }
+#hue263		{ color: #000000;  }
+#hue265		{ color: #000000;  }
+#hue267		{ color: #000000;  }
+#hue274		{ color: #000000;  }
+#hue276		{ color: #000000;  }
+#hue280		{ color: #000000;  }
+#hue282		{ color: #000000;  }
+#hue284		{ color: #000000;  }
+#hue288		{ color: #000000;  }
+#hue290		{ color: #000000;  }
+#hue292		{ color: #000000;  }
+#hue299		{ color: #000000;  }
+#hue309		{ color: #000000;  }
+#hue311		{ color: #000000;  }
+#hue314		{ color: #000000;  }
+#hue316		{ color: #000000;  }
+#hue318		{ color: #000000;  }
+#hue321		{ color: #000000;  }
+#hue324		{ color: #000000;  }
+#hue326		{ color: #000000;  }
+#hue328		{ color: #000000;  }
+#hue33		{ color: #000000;  }
+#hue330		{ color: #000000;  }
+#hue332		{ color: #000000;  }
+#hue335		{ color: #000000;  }
+#hue338		{ color: #000000;  }
+#hue340		{ color: #000000;  }
+#hue342		{ color: #000000;  }
+#hue344		{ color: #000000;  }
+#hue346		{ color: #000000;  }
+#hue348		{ color: #000000;  }
+#hue35		{ color: #000000;  }
+#hue365		{ color: #000000;  }
+#hue366		{ color: #000000;  }
+#hue37		{ color: #000000;  }
+#hue375		{ color: #000000;  }
+#hue377		{ color: #000000;  }
+#hue379		{ color: #000000;  }
+#hue383		{ color: #000000;  }
+#hue384		{ color: #000000;  }
+#hue385		{ color: #000000;  }
+#hue386		{ color: #000000;  }
+#hue387		{ color: #000000;  }
+#hue389		{ color: #000000;  }
+#hue39		{ color: #000000;  }
+#hue390		{ color: #000000;  }
+#hue392		{ color: #000000;  }
+#hue394		{ color: #000000;  }
+#hue396		{ color: #000000;  }
+#hue397		{ color: #000000;  }
+#hue398		{ color: #000000;  }
+#hue399		{ color: #000000;  }
+#hue41		{ color: #000000;  }
+#hue43		{ color: #000000;  }
+#hue45		{ color: #000000;  }
+#hue47		{ color: #000000;  }
+#hue49		{ color: #000000;  }
+#hue51		{ color: #000000;  }
+#hue53		{ color: #000000;  }
+#hue55		{ color: #000000;  }
+#hue58		{ color: #000000;  }
+#hue60		{ color: #000000;  }
+#hue62		{ color: #000000;  }
+#hue64		{ color: #000000;  }
+#hue66		{ color: #000000;  }
+#hue68		{ color: #000000;  }
+#hue74		{ color: #000000;  }
+#hue77		{ color: #000000;  }
+#hue80		{ color: #000000;  }
+#hue82		{ color: #000000;  }
+#hue84		{ color: #000000;  }
+#hue86		{ color: #000000;  }
+#hue88		{ color: #000000;  }
+#hue90		{ color: #000000;  }
+#hue93		{ color: #000000;  }
+#hue95		{ color: #000000;  }
+#hue97		{ color: #000000;  }

BIN
Docs/flowreplay.dvi


+ 664 - 0
Docs/flowreplay.html

@@ -0,0 +1,664 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<!--Converted with LaTeX2HTML 2002-2-1 (1.70)
+original version by:  Nikos Drakos, CBLU, University of Leeds
+* revised and updated by:  Marcus Hennecke, Ross Moore, Herb Swan
+* with significant contributions from:
+  Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
+<HTML>
+<HEAD>
+<TITLE>Flowreplay Design Notes</TITLE>
+<META NAME="description" CONTENT="Flowreplay Design Notes">
+<META NAME="keywords" CONTENT="flowreplay">
+<META NAME="resource-type" CONTENT="document">
+<META NAME="distribution" CONTENT="global">
+
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+<META NAME="Generator" CONTENT="LaTeX2HTML v2002-2-1">
+<META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">
+
+<LINK REL="STYLESHEET" HREF="flowreplay.css">
+
+</HEAD>
+
+<BODY >
+
+<P>
+
+<P>
+
+<P>
+
+<P>
+<H1 ALIGN="CENTER"><SPAN ID="hue33">Flowreplay Design Notes</SPAN></H1>
+<DIV CLASS="author_info">
+
+<P ALIGN="CENTER"><STRONG><SPAN ID="hue35">Aaron Turner </SPAN></STRONG></P>
+<P ALIGN="CENTER"><I><SPAN ID="hue37">http://synfin.net/</SPAN></I></P>
+<P ALIGN="CENTER"><STRONG><SPAN ID="hue39">Last Edited:</SPAN>
+<BR><SPAN ID="hue41">October 23, 2003</SPAN></STRONG></P>
+</DIV>
+
+<P>
+
+<H1><A NAME="SECTION00010000000000000000">
+<SPAN CLASS="arabic">1</SPAN> <SPAN ID="hue43">Overview</SPAN></A>
+</H1>
+
+<P>
+<SPAN ID="hue45">Tcpreplay</SPAN><A NAME="tex2html1"
+  HREF="#foot362"><SUP><SPAN CLASS="arabic">1</SPAN></SUP></A> <SPAN ID="hue49">was designed to replay traffic previously captured
+in the pcap format back onto the wire for testing NIDS and other passive
+devices. Over time, it was enhanced to be able to test in-line network
+devices. However, a re-occurring feature request for tcpreplay is
+to connect to a server in order to test applications and host TCP/IP
+stacks. It was determined early on, that adding this feature to tcpreplay
+was far too complex, so I decided to create a new tool specifically
+designed for this.</SPAN>
+<P>
+<SPAN ID="hue51">Flowreplay is designed to replay traffic at Layer
+4 or 7 depending on the protocol rather then at Layer 2 like tcpreplay
+does. This allows flowreplay to connect to one or more servers using
+a pcap savefile as the basis of the connections. Hence, flowreplay
+allows the testing of applications running on real servers rather
+then passive devices. </SPAN>
+<P>
+
+<H1><A NAME="SECTION00020000000000000000">
+<SPAN CLASS="arabic">2</SPAN> <SPAN ID="hue53">Features</SPAN></A>
+</H1>
+
+<P>
+
+<H2><A NAME="SECTION00021000000000000000">
+<SPAN CLASS="arabic">2</SPAN>.<SPAN CLASS="arabic">1</SPAN> <SPAN ID="hue55">Requirements</SPAN></A>
+</H2>
+
+<P>
+
+<OL>
+<LI><SPAN ID="hue58">Full TCP/IP support, including IP fragments and
+TCP stream reassembly.</SPAN>
+</LI>
+<LI><SPAN ID="hue60">Support replaying TCP and UDP flows.</SPAN>
+</LI>
+<LI><SPAN ID="hue62">Code should handle each flow/service independently.</SPAN>
+</LI>
+<LI><SPAN ID="hue64">Should be able to connect to the server(s) in the
+pcap file or to a user specified IP address.</SPAN>
+</LI>
+<LI><SPAN ID="hue66">Support a plug-in architecture to allow adding application
+layer intelligence.</SPAN>
+</LI>
+<LI><SPAN ID="hue68">Plug-ins must be able to support multi-flow protocols
+like FTP.</SPAN>
+</LI>
+<LI><SPAN ID="hue365">Ship with a default plug-in which will work ``well
+enough'' for simple single-flow protocols like HTTP and telnet.</SPAN>
+</LI>
+<LI><SPAN ID="hue366">Flows being replayed ``correctly'' is more important
+then performance (Mbps).</SPAN>
+</LI>
+<LI><SPAN ID="hue74">Portable to run on common flavors of Unix and Unix-like
+systems.</SPAN>
+</LI>
+</OL>
+
+<P>
+
+<H2><A NAME="SECTION00022000000000000000">
+<SPAN CLASS="arabic">2</SPAN>.<SPAN CLASS="arabic">2</SPAN> <SPAN ID="hue77">Wishes</SPAN></A>
+</H2>
+
+<P>
+
+<OL>
+<LI><SPAN ID="hue80">Support clients connecting to flowreplay on a limited
+basis. Flowreplay would replay the server side of the connection.</SPAN>
+</LI>
+<LI><SPAN ID="hue82">Support other IP based traffic (ICMP, VRRP, OSPF,
+etc) via plug-ins.</SPAN>
+</LI>
+<LI><SPAN ID="hue84">Support non-IP traffic (ARP, STP, CDP, etc) via
+plug-ins.</SPAN>
+</LI>
+<LI><SPAN ID="hue86">Limit which flows are replayed using user defined
+filters. (bpf filter syntax?)</SPAN>
+</LI>
+<LI><SPAN ID="hue88">Process pcap files directly with no intermediary
+file conversions.</SPAN>
+</LI>
+<LI><SPAN ID="hue90">Should be able to scale to pcap files in the 100's
+of MB in size and 100+ simultaneous flows on a P3 500MHz w/ 256MB
+of RAM.</SPAN>
+</LI>
+</OL>
+
+<P>
+
+<H1><A NAME="SECTION00030000000000000000">
+<SPAN CLASS="arabic">3</SPAN> <SPAN ID="hue93">Design Thoughts</SPAN></A>
+</H1>
+
+<P>
+
+<H2><A NAME="SECTION00031000000000000000">
+<SPAN CLASS="arabic">3</SPAN>.<SPAN CLASS="arabic">1</SPAN> <SPAN ID="hue95">Sending and Receiving traffic</SPAN></A>
+</H2>
+
+<P>
+<SPAN ID="hue97">Flowreplay must be able to process multiple connections
+to one or more devices. There are two options:</SPAN>
+<P>
+
+<OL>
+<LI><SPAN ID="hue100">Use sockets</SPAN><A NAME="tex2html2"
+  HREF="#foot370"><SUP><SPAN CLASS="arabic">2</SPAN></SUP></A> <SPAN ID="hue104">to send and receive data</SPAN>
+</LI>
+<LI><SPAN ID="hue106">Use libpcap</SPAN><A NAME="tex2html3"
+  HREF="#foot371"><SUP><SPAN CLASS="arabic">3</SPAN></SUP></A> <SPAN ID="hue110">to receive packets and libnet</SPAN><A NAME="tex2html4"
+  HREF="#foot372"><SUP><SPAN CLASS="arabic">4</SPAN></SUP></A> <SPAN ID="hue114">to send packets</SPAN>
+</LI>
+</OL>
+<SPAN ID="hue117">Although using libpcap/libnet would allow more simultaneous
+connections and greater flexibility, there would be a very high complexity
+cost associated with it. With that in mind, I've decided to use sockets
+to send and receive data.</SPAN>
+<P>
+
+<H2><A NAME="SECTION00032000000000000000">
+<SPAN CLASS="arabic">3</SPAN>.<SPAN CLASS="arabic">2</SPAN> <SPAN ID="hue119">Handling Multiple Connections</SPAN></A>
+</H2>
+
+<P>
+<SPAN ID="hue121">Because a pcap file can contain multiple simultaneous
+flows, we need to be able to support that too. The biggest problem
+with this is reading packet data in a different order then stored
+in the pcap file. </SPAN>
+<P>
+<SPAN ID="hue123">Reading and writing to multiple sockets is easy
+with select() or poll(), however a pcap file has it's data stored
+serially, but we need to access it randomly. There are a number of
+possible solutions for this such as caching packets in RAM where they
+can be accessed more randomly, creating an index of the packets in
+the pcap file, or converting the pcap file to another format altogether.
+Alternatively, I've started looking at libpcapnav</SPAN><A NAME="tex2html5"
+  HREF="#foot124"><SUP><SPAN CLASS="arabic">5</SPAN></SUP></A> <SPAN ID="hue126">as an alternate means to navigate a pcap file and
+process packets out of order.</SPAN>
+<P>
+
+<H2><A NAME="SECTION00033000000000000000">
+<SPAN CLASS="arabic">3</SPAN>.<SPAN CLASS="arabic">3</SPAN> <SPAN ID="hue128">Data Synchronization</SPAN></A>
+</H2>
+
+<P>
+<SPAN ID="hue375">Knowing when to start sending client traffic in
+response to the server will be &#34;tricky&#34;. Without
+understanding the actual protocol involved, probably the best general
+solution is waiting for a given period of time after no more data
+from the server has been received. Not sure what to do if the client
+traffic doesn't elicit a response from the server (implement some
+kind of timeout?). This will be the basis for the default plug-in.</SPAN>
+<P>
+
+<H2><A NAME="SECTION00034000000000000000">
+<SPAN CLASS="arabic">3</SPAN>.<SPAN CLASS="arabic">4</SPAN> <SPAN ID="hue133">TCP/IP</SPAN></A>
+</H2>
+
+<P>
+<SPAN ID="hue135">Dealing with IP fragmentation and TCP stream reassembly
+will be another really complex problem. We're basically talking about
+implementing a significant portion of a TCP/IP stack. One thought
+is to use libnids</SPAN><A NAME="tex2html6"
+  HREF="#foot403"><SUP><SPAN CLASS="arabic">6</SPAN></SUP></A> <SPAN ID="hue139">which basically implements a Linux 2.0.37 TCP/IP
+stack in user-space. Other solutions include porting a TCP/IP stack
+from Open/Net/FreeBSD or writing our own custom stack from scratch.</SPAN>
+<P>
+
+<H1><A NAME="SECTION00040000000000000000">
+<SPAN CLASS="arabic">4</SPAN> <SPAN ID="hue141">Multiple Independent Flows</SPAN></A>
+</H1>
+
+<P>
+<SPAN ID="hue143">The biggest asynchronous problem, that pcap files
+are serial, has to be solved in a scaleable manner. Not much can be
+assumed about the network traffic contained in a pcap savefile other
+then Murphy's Law will be in effect. This means we'll have to deal
+with:</SPAN>
+<P>
+
+<UL>
+<LI><SPAN ID="hue146">Thousands of small simultaneous flows (captured
+on a busy network)</SPAN>
+</LI>
+<LI><SPAN ID="hue379">Flows which ``hang'' mid-stream (an exploit
+against a server causes it to crash)</SPAN>
+</LI>
+<LI><SPAN ID="hue150">Flows which contain large quantities of data (FTP
+transfers of ISO's for example)</SPAN>
+</LI>
+</UL>
+<SPAN ID="hue153">How we implement parallel processing of the pcap
+savefile will dramatically effect how well we can scale. A few considerations:</SPAN>
+<P>
+
+<UL>
+<LI>Most Unix systems limit the maximum number of open file descriptors
+a single process can have. Generally speaking this shouldn't be a
+problem except for highly parallel pcap's.
+</LI>
+<LI>While RAM isn't limitless, we can use mmap() to get around this.
+</LI>
+<LI>Many Unix systems have enhanced solutions to poll() which will improve
+flow management.
+</LI>
+</UL>
+
+<P>
+
+<H2><A NAME="SECTION00041000000000000000">
+<SPAN CLASS="arabic">4</SPAN>.<SPAN CLASS="arabic">1</SPAN> <SPAN ID="hue157">IP Fragments and TCP Streams</SPAN></A>
+</H2>
+
+<P>
+<SPAN ID="hue159">There are five major complications with flowreplay:</SPAN>
+<P>
+
+<OL>
+<LI><SPAN ID="hue162">The IP datagrams may be fragmented- we won't be
+able to use the standard 5-tuple (src/dst IP, src/dst port, protocol)
+to lookup which flow a packet belongs to.</SPAN>
+</LI>
+<LI><SPAN ID="hue164">IP fragments may arrive out of order which will
+complicate ordering of data to be sent.</SPAN>
+</LI>
+<LI><SPAN ID="hue166">The TCP segments may arrive out of order which will
+complicate ordering of data to be sent.</SPAN>
+</LI>
+<LI><SPAN ID="hue168">Packets may be missing in the pcap file because
+they were dropped during capture.</SPAN>
+</LI>
+<LI><SPAN ID="hue170">There are tools like fragrouter which intentionally
+create non-deterministic situations.</SPAN>
+</LI>
+</OL>
+<SPAN ID="hue173">First off, I've decided, that I'm not going to worry
+about fragrouter or it's cousins. I'll handle non-deterministic situations
+one and only one way, so that the way flowreplay handles the traffic
+will be deterministic. Perhaps, I'll make it easy for others to write
+a plug-in which will change it, but that's not something I'm going
+to concern myself with now.</SPAN>
+<P>
+<SPAN ID="hue175">Missing packets in the pcap file will probably make
+that flow unplayable. There are proabably certain situation where
+we can make an educated guess, but this is far too complex to worry
+about for the first stable release.</SPAN>
+<P>
+<SPAN ID="hue177">That still leaves creating a basic TCP/IP stack
+in user space. The good news it that there is already a library which
+does this called libnids. As of version 1.17, libnids can process
+packets from a pcap savefile (it's not documented in the man page,
+but the code is there).</SPAN>
+<P>
+<SPAN ID="hue179">A potential problem with libnids though is that
+it has to maintain it's own state/cache system. This not only means
+additional overhead, but jumping around in the pcap file as I'm planning
+on doing to handle multiple simultaneous flows is likely to really
+confuse libnids' state engine. Also, libnids is licensed under the
+GPL, but I want flowreplay released under a BSD-like license; I need
+to research if the two are compatible in this way.</SPAN>
+<P>
+<SPAN ID="hue181">Possible solutions:</SPAN>
+<P>
+
+<UL>
+<LI><SPAN ID="hue184">Developing a custom wedge between the capture file
+and libnids which will cause each packet to only be processed a single
+time.</SPAN>
+</LI>
+<LI><SPAN ID="hue186">Use libnids to process the pcap file into a new
+flow-based format, effectively putting the TCP/IP stack into a dedicated
+utility.</SPAN>
+</LI>
+<LI><SPAN ID="hue188">Develop a custom user-space TCP/IP stack, perhaps
+based on a BSD TCP/IP stack, much like libnids is based on Linux 2.0.37.</SPAN>
+</LI>
+<LI><SPAN ID="hue190">Screw it and say that IP fragmentation and out of
+order IP packets/TCP segments are not supported. Not sure if this
+will meet the needs of potential users.</SPAN>
+</LI>
+</UL>
+
+<P>
+
+<H2><A NAME="SECTION00042000000000000000">
+<SPAN CLASS="arabic">4</SPAN>.<SPAN CLASS="arabic">2</SPAN> <SPAN ID="hue193">Blocking</SPAN></A>
+</H2>
+
+<P>
+<SPAN ID="hue195">As earlier stated, one of the main goals of this
+project is to keep things single threaded to make coding plugins easier.
+One caveat of that is that any function which blocks will cause serious
+problems.</SPAN>
+<P>
+<SPAN ID="hue197">There are three major cases where blocking is likely
+to occur:</SPAN>
+<P>
+
+<OL>
+<LI><SPAN ID="hue200">Opening a socket</SPAN>
+</LI>
+<LI><SPAN ID="hue202">Reading from a socket</SPAN>
+</LI>
+<LI><SPAN ID="hue204">Writing to a socket</SPAN>
+</LI>
+</OL>
+<SPAN ID="hue207">Reading from sockets in a non-blocking manner is
+easy to solve for using poll() or select(). Writing to a socket, or
+merely opening a TCP socket via connect() however requires a different
+method:</SPAN>
+<P>
+<BLOCKQUOTE>
+<SPAN ID="hue210">It is possible to do non-blocking IO on sockets
+by setting the O_NONBLOCK flag on a socket file descriptor using
+fcntl(2). Then all operations that would block will (usually) return
+with EAGAIN (operation should be retried later); connect(2) will return
+EINPROGRESS error. The user can then wait for various events via poll(2)
+or select(2).</SPAN><A NAME="tex2html7"
+  HREF="#foot382"><SUP><SPAN CLASS="arabic">7</SPAN></SUP></A>
+</BLOCKQUOTE>
+<SPAN ID="hue215">If connect() returns EINPROGRESS, then we'll just
+have to do something like this:</SPAN>
+<P>
+
+<DL COMPACT>
+<DT>
+<DD><SPAN ID="hue218">int&nbsp;e,&nbsp;len=sizeof(e);</SPAN>
+<P>
+<SPAN ID="hue220">if&nbsp;(getsockopt(conn-&gt;s,&nbsp;SOL_SOCKET,&nbsp;SO_ERROR,&nbsp;&amp;e,&nbsp;&amp;len)&nbsp;&lt;&nbsp;0)&nbsp;{&nbsp;</SPAN>
+<P>
+&nbsp;<SPAN ID="hue383">&nbsp;&nbsp;&nbsp;/*&nbsp;not&nbsp;yet&nbsp;*/</SPAN>
+<P>
+&nbsp;<SPAN ID="hue384">&nbsp;&nbsp;&nbsp;if(errno&nbsp;!=&nbsp;EINPROGRESS){&nbsp;&nbsp;/*&nbsp;yuck.&nbsp;kill&nbsp;it.&nbsp;*/&nbsp;</SPAN>
+<P>
+&nbsp;<SPAN ID="hue385">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log_fn(LOG_DEBUG,&#34;in-progress&nbsp;connect&nbsp;failed.&nbsp;Removing.&#34;);&nbsp;</SPAN>
+<P>
+&nbsp;<SPAN ID="hue231">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;-1;&nbsp;</SPAN>
+<P>
+&nbsp;<SPAN ID="hue233">&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{&nbsp;</SPAN>
+<P>
+&nbsp;<SPAN ID="hue386">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;&nbsp;/*&nbsp;no&nbsp;change,&nbsp;see&nbsp;if&nbsp;next&nbsp;time&nbsp;is&nbsp;better&nbsp;*/&nbsp;</SPAN>
+<P>
+&nbsp;<SPAN ID="hue238">&nbsp;&nbsp;&nbsp;}&nbsp;</SPAN>
+<P>
+<SPAN ID="hue240">}&nbsp;</SPAN>
+<P>
+<SPAN ID="hue387">/*&nbsp;the&nbsp;connect&nbsp;has&nbsp;finished.&nbsp;*/&nbsp;</SPAN>
+</DD>
+</DL><BLOCKQUOTE>
+<SPAN ID="hue247">Note: It may not be totally right, but it works
+ok. (that chunk of code gets called after poll returns the socket
+as writable. if poll returns it as readable, then it's probably because
+of eof, connect fails. You must poll for both.</SPAN>
+</BLOCKQUOTE>
+
+<P>
+
+<H1><A NAME="SECTION00050000000000000000">
+<SPAN CLASS="arabic">5</SPAN> <SPAN ID="hue250">pcap vs flow File Format</SPAN></A>
+</H1>
+
+<P>
+<SPAN ID="hue252">As stated before, the pcap file format really isn't
+well suited for flowreplay because it uses the raw packet as a container
+for data. Flowreplay however isn't interested in packets, it's interested
+in data streams</SPAN><A NAME="tex2html8"
+  HREF="#foot404"><SUP><SPAN CLASS="arabic">8</SPAN></SUP></A> <SPAN ID="hue256">which may span one or more TCP/UDP segments, each
+comprised of an IP datagram which may be comprised of multiple IP
+fragments. Handling all this additional complexity requires a full
+TCP/IP stack in user space which would have additional feature requirements
+specific to flowreplay.</SPAN>
+<P>
+<SPAN ID="hue258">Rather then trying to do that, I've decided to create
+a pcap preprocessor for flowreplay called: flowprep. Flowprep will
+handle all the TCP/IP defragmentation/reassembly and write out a file
+containing the data streams for each flow.</SPAN>
+<P>
+<SPAN ID="hue260">A flow file will contain three sections:</SPAN>
+<P>
+
+<OL>
+<LI><SPAN ID="hue263">A header which identifies this as a flowprep file
+and the file version</SPAN>
+</LI>
+<LI><SPAN ID="hue265">An index of all the flows contained in the file</SPAN>
+</LI>
+<LI><SPAN ID="hue267">The data streams themselves</SPAN>
+</LI>
+</OL>
+<DIV ALIGN="CENTER">
+<SPAN ID="hue390"><IMG
+ WIDTH="668" HEIGHT="748" ALIGN="BOTTOM" BORDER="0"
+ SRC="img1.png"
+ ALT="\includegraphics{flowheader.eps}"></SPAN>
+</DIV>
+
+<P>
+<SPAN ID="hue274">At startup, the file header is validated and the
+data stream indexes are loaded into memory. Then the first data stream
+header from each flow is read. Then each flow and subsequent data
+stream is processed based upon the timestamps and plug-ins.</SPAN>
+<P>
+
+<H1><A NAME="SECTION00060000000000000000">
+<SPAN CLASS="arabic">6</SPAN> <SPAN ID="hue276">Plug-ins</SPAN></A>
+</H1>
+
+<P>
+<SPAN ID="hue392">Plug-ins will provide the ``intelligence'' in
+flowreplay. Flowreplay is designed to be a mere framework for connecting
+captured flows in a flow file with socket file handles. How data is
+processed and what should be done with it will be done via plug-ins.</SPAN>
+<P>
+<SPAN ID="hue280">Plug-ins will allow proper handling of a variety
+of protocols while hopefully keeping things simple. Another part of
+the consideration will be making it easy for others to contribute
+to flowreplay. I don't want to have to write all the protocol logic
+myself.</SPAN>
+<P>
+
+<H2><A NAME="SECTION00061000000000000000">
+<SPAN CLASS="arabic">6</SPAN>.<SPAN CLASS="arabic">1</SPAN> <SPAN ID="hue282">Plug-in Basics</SPAN></A>
+</H2>
+
+<P>
+<SPAN ID="hue284">Each plug-in provides the logic for handling one
+or more services. The main purpose of a plug-in is to decide when
+flowreplay should send data via one or more sockets. The plug-in can
+use any</SPAN> <SPAN ID="hue394"><SPAN  CLASS="textit">non-blocking</SPAN></SPAN> <SPAN ID="hue288">method
+of determining if it appropriate to send data or wait for data to
+received. If necessary, a plug-in can also modify the data sent.</SPAN>
+<P>
+<SPAN ID="hue290">Each time poll() returns, flowreplay calls the plug-ins
+for the flows which either have data waiting or in the case of a timeout,
+those flows which timed out. Afterwords, all the flows are processed
+and poll() is called on those flows which have their state set to
+POLL. And the process repeats until there are no more nodes in the
+tree.</SPAN>
+<P>
+
+<H2><A NAME="SECTION00062000000000000000">
+<SPAN CLASS="arabic">6</SPAN>.<SPAN CLASS="arabic">2</SPAN> <SPAN ID="hue292">The Default Plug-in</SPAN></A>
+</H2>
+
+<P>
+<SPAN ID="hue396">Initially, flowreplay will ship with one basic plug-in
+called ``default''. Any flow which doesn't have a specific plug-in
+defined, will use default. The goal of the default plug-in is to work
+``good enough'' for a majority of single-flow protocols such as
+SMTP, HTTP, and Telnet. Protocols which use encryption (SSL, SSH,
+etc) or multiple flows (FTP, RPC, etc) will never work with the default
+plug-in. Furthermore, the default plug-in will only support connections</SPAN><SPAN ID="hue397"><SPAN  CLASS="textit">to</SPAN></SPAN> <SPAN ID="hue299">a server, it will not
+support accepting connections from clients.</SPAN>
+<P>
+<SPAN ID="hue398">The default plug-in will provide no data level manipulation
+and only a simple method for detecting when it is time to send data
+to the server. Detecting when to send data will be done by a ``no
+more data'' timeout value. Basically, by using the pcap file as a
+means to determine the order of the exchange, anytime it is the servers
+turn to send data, flowreplay will wait for the first byte of data
+and then start the ``no more data'' timer. Every time more data
+is received, the timer is reset. If the timer reaches zero, then flowreplay
+sends the next portion of the client side of the connection. This
+is repeated until the the flow has been completely replayed or a ``server
+hung'' timeout is reached. The server hung timeout is used to detect
+a server which crashed and never starts sending any data which would
+start the ``no more data'' timer.</SPAN>
+<P>
+<SPAN ID="hue399">Both the ``no more data'' and ``server hung''
+timers will be user defined values and global to all flows using the
+default plug-in.</SPAN>
+<P>
+
+<H2><A NAME="SECTION00063000000000000000">
+<SPAN CLASS="arabic">6</SPAN>.<SPAN CLASS="arabic">3</SPAN> <SPAN ID="hue309">Plug-in Details</SPAN></A>
+</H2>
+
+<P>
+<SPAN ID="hue311">Each plug-in will be comprised of the following:</SPAN>
+<P>
+
+<OL>
+<LI><SPAN ID="hue314">An optional global data structure, for intra-flow
+communication</SPAN>
+</LI>
+<LI><SPAN ID="hue316">Per-flow data structure, for tracking flow state
+information</SPAN>
+</LI>
+<LI><SPAN ID="hue318">A list of functions which flow replay will call
+when certain well-defined conditions are met.</SPAN>
+<P>
+
+<UL>
+<LI><SPAN ID="hue321">Required functions:</SPAN>
+<P>
+
+<UL>
+<LI><SPAN ID="hue324">initialize_node() - called when a node in the tree
+created using this plug-in</SPAN>
+</LI>
+<LI><SPAN ID="hue326">post_poll_timeout() - called when the poll() returned
+due to a timeout for this node</SPAN>
+</LI>
+<LI><SPAN ID="hue328">post_poll_read() - called when the poll() returned
+due to the socket being ready</SPAN>
+</LI>
+<LI><SPAN ID="hue330">buffer_full() - called when a the packet buffer
+for this flow is full</SPAN>
+</LI>
+<LI><SPAN ID="hue332">delete_node() - called just prior to the node being
+free()'d</SPAN>
+</LI>
+</UL>
+</LI>
+<LI><SPAN ID="hue335">Optional functions:</SPAN>
+<P>
+
+<UL>
+<LI><SPAN ID="hue338">pre_send_data() - called before data is sent</SPAN>
+</LI>
+<LI><SPAN ID="hue340">post_send_data() - called after data is sent</SPAN>
+</LI>
+<LI><SPAN ID="hue342">pre_poll() - called prior to poll()</SPAN>
+</LI>
+<LI><SPAN ID="hue344">post_poll_default() - called when poll() returns
+and neither the socket was ready or the node timed out </SPAN>
+</LI>
+<LI><SPAN ID="hue346">open_socket() - called after the socket is opened</SPAN>
+</LI>
+<LI><SPAN ID="hue348">close_socket() - called after the socket is closed</SPAN>
+</LI>
+</UL>
+</LI>
+</UL>
+</LI>
+</OL>
+
+<DL COMPACT>
+<DT>
+<DD><P>
+</DD>
+</DL>
+<P>
+
+<H1><A NAME="SECTION00070000000000000000">
+About this document ...</A>
+</H1>
+ <STRONG><SPAN ID="hue33">Flowreplay Design Notes</SPAN></STRONG><P>
+This document was generated using the
+<A HREF="http://www.latex2html.org/"><STRONG>LaTeX</STRONG>2<tt>HTML</tt></A> translator Version 2002-2-1 (1.70)
+<P>
+Copyright &#169; 1993, 1994, 1995, 1996,
+<A HREF="http://cbl.leeds.ac.uk/nikos/personal.html">Nikos Drakos</A>, 
+Computer Based Learning Unit, University of Leeds.
+<BR>
+Copyright &#169; 1997, 1998, 1999,
+<A HREF="http://www.maths.mq.edu.au/~ross/">Ross Moore</A>, 
+Mathematics Department, Macquarie University, Sydney.
+<P>
+The command line arguments were: <BR>
+ <STRONG>latex2html</STRONG> <TT>-nonavigation -no_subdir -split 0 -show_section_numbers flowreplay.tex</TT>
+<P>
+The translation was initiated by Aaron Turner on 2005-02-10
+<BR><HR><H4>Footnotes</H4>
+<DL>
+<DT><A NAME="foot362">...Tcpreplay</A><A
+ HREF="flowreplay.html#tex2html1"><SUP><SPAN CLASS="arabic">1</SPAN></SUP></A></DT>
+<DD><SPAN ID="hue47">http://tcpreplay.sourceforge.net/</SPAN>
+
+</DD>
+<DT><A NAME="foot370">...&nbsp;</A><A
+ HREF="flowreplay.html#tex2html2"><SUP><SPAN CLASS="arabic">2</SPAN></SUP></A></DT>
+<DD><SPAN ID="hue102">socket(2)</SPAN>
+
+</DD>
+<DT><A NAME="foot371">...&nbsp;</A><A
+ HREF="flowreplay.html#tex2html3"><SUP><SPAN CLASS="arabic">3</SPAN></SUP></A></DT>
+<DD><SPAN ID="hue108">http://www.tcpdump.org/</SPAN>
+
+</DD>
+<DT><A NAME="foot372">...&nbsp;</A><A
+ HREF="flowreplay.html#tex2html4"><SUP><SPAN CLASS="arabic">4</SPAN></SUP></A></DT>
+<DD><SPAN ID="hue112">http://www.packetfactory.net/projects/libnet/</SPAN>
+
+</DD>
+<DT><A NAME="foot124">...&nbsp;</A><A
+ HREF="flowreplay.html#tex2html5"><SUP><SPAN CLASS="arabic">5</SPAN></SUP></A></DT>
+<DD>http://netdude.sourceforge.net/
+
+</DD>
+<DT><A NAME="foot403">...&nbsp;</A><A
+ HREF="flowreplay.html#tex2html6"><SUP><SPAN CLASS="arabic">6</SPAN></SUP></A></DT>
+<DD><SPAN ID="hue377">http://www.avet.com.pl/~nergal/libnids/</SPAN>
+
+</DD>
+<DT><A NAME="foot382">...&nbsp;</A><A
+ HREF="flowreplay.html#tex2html7"><SUP><SPAN CLASS="arabic">7</SPAN></SUP></A></DT>
+<DD><SPAN ID="hue212">socket(7)</SPAN>
+
+</DD>
+<DT><A NAME="foot404">...&nbsp;</A><A
+ HREF="flowreplay.html#tex2html8"><SUP><SPAN CLASS="arabic">8</SPAN></SUP></A></DT>
+<DD><SPAN ID="hue389">A ``data stream'' as I call it is a simplex
+communication from the client or server which is a complete query,
+response or message.</SPAN>
+
+</DD>
+</DL>
+<BR><HR>
+<ADDRESS>
+Aaron Turner
+2005-02-10
+</ADDRESS>
+</BODY>
+</HTML>

File diff suppressed because it is too large
+ 1125 - 0
Docs/flowreplay.lyx


BIN
Docs/flowreplay.pdf


File diff suppressed because it is too large
+ 1224 - 0
Docs/flowreplay.ps


+ 520 - 0
Docs/flowreplay.tex

@@ -0,0 +1,520 @@
+%% LyX 1.3 created this file.  For more info, see http://www.lyx.org/.
+%% Do not edit unless you really know what you are doing.
+\documentclass[english]{article}
+\usepackage{pslatex}
+\usepackage[T1]{fontenc}
+\usepackage[latin1]{inputenc}
+\usepackage{geometry}
+\geometry{verbose,letterpaper,tmargin=10mm,bmargin=15mm,lmargin=10mm,rmargin=10mm}
+\setcounter{secnumdepth}{4}
+\setlength\parskip{\medskipamount}
+\setlength\parindent{0pt}
+\usepackage{color}
+\usepackage{graphicx}
+
+\makeatletter
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Textclass specific LaTeX commands.
+ \usepackage{verbatim}
+ \newenvironment{lyxcode}
+   {\begin{list}{}{
+     \setlength{\rightmargin}{\leftmargin}
+     \setlength{\listparindent}{0pt}% needed for AMS classes
+     \raggedright
+     \setlength{\itemsep}{0pt}
+     \setlength{\parsep}{0pt}
+     \normalfont\ttfamily}%
+    \item[]}
+   {\end{list}}
+
+\AtBeginDocument{
+  \renewcommand{\labelitemii}{\(\ast\)}
+  \renewcommand{\labelitemiii}{\normalfont\bfseries{--}}
+}
+
+\usepackage{babel}
+\makeatother
+\begin{document}
+
+\title{\textcolor{black}{Flowreplay Design Notes}}
+
+
+\author{\textcolor{black}{Aaron Turner }\\
+\textcolor{black}{http://synfin.net/}}
+
+
+\date{\textcolor{black}{Last Edited:}\\
+\textcolor{black}{October 23, 2003}}
+
+\maketitle
+
+\newpage
+\section{\textcolor{black}{Overview}}
+
+\textcolor{black}{Tcpreplay}%
+\footnote{\textcolor{black}{http://tcpreplay.sourceforge.net/}%
+} \textcolor{black}{was designed to replay traffic previously captured
+in the pcap format back onto the wire for testing NIDS and other passive
+devices. Over time, it was enhanced to be able to test in-line network
+devices. However, a re-occurring feature request for tcpreplay is
+to connect to a server in order to test applications and host TCP/IP
+stacks. It was determined early on, that adding this feature to tcpreplay
+was far too complex, so I decided to create a new tool specifically
+designed for this.}
+
+\textcolor{black}{Flowreplay is designed to replay traffic at Layer
+4 or 7 depending on the protocol rather then at Layer 2 like tcpreplay
+does. This allows flowreplay to connect to one or more servers using
+a pcap savefile as the basis of the connections. Hence, flowreplay
+allows the testing of applications running on real servers rather
+then passive devices. }
+
+
+\section{\textcolor{black}{Features}}
+
+
+\subsection{\textcolor{black}{Requirements}}
+
+\begin{enumerate}
+\item \textcolor{black}{Full TCP/IP support, including IP fragments and
+TCP stream reassembly.}
+\item \textcolor{black}{Support replaying TCP and UDP flows.}
+\item \textcolor{black}{Code should handle each flow/service independently.}
+\item \textcolor{black}{Should be able to connect to the server(s) in the
+pcap file or to a user specified IP address.}
+\item \textcolor{black}{Support a plug-in architecture to allow adding application
+layer intelligence.}
+\item \textcolor{black}{Plug-ins must be able to support multi-flow protocols
+like FTP.}
+\item \textcolor{black}{Ship with a default plug-in which will work {}``well
+enough'' for simple single-flow protocols like HTTP and telnet.}
+\item \textcolor{black}{Flows being replayed {}``correctly'' is more important
+then performance (Mbps).}
+\item \textcolor{black}{Portable to run on common flavors of Unix and Unix-like
+systems.}
+\end{enumerate}
+
+\subsection{\textcolor{black}{Wishes}}
+
+\begin{enumerate}
+\item \textcolor{black}{Support clients connecting to flowreplay on a limited
+basis. Flowreplay would replay the server side of the connection.}
+\item \textcolor{black}{Support other IP based traffic (ICMP, VRRP, OSPF,
+etc) via plug-ins.}
+\item \textcolor{black}{Support non-IP traffic (ARP, STP, CDP, etc) via
+plug-ins.}
+\item \textcolor{black}{Limit which flows are replayed using user defined
+filters. (bpf filter syntax?)}
+\item \textcolor{black}{Process pcap files directly with no intermediary
+file conversions.}
+\item \textcolor{black}{Should be able to scale to pcap files in the 100's
+of MB in size and 100+ simultaneous flows on a P3 500MHz w/ 256MB
+of RAM.}
+\end{enumerate}
+
+\section{\textcolor{black}{Design Thoughts}}
+
+
+\subsection{\textcolor{black}{Sending and Receiving traffic}}
+
+\textcolor{black}{Flowreplay must be able to process multiple connections
+to one or more devices. There are two options:}
+
+\begin{enumerate}
+\item \textcolor{black}{Use sockets}%
+\footnote{\textcolor{black}{socket(2)}%
+} \textcolor{black}{to send and receive data}
+\item \textcolor{black}{Use libpcap}%
+\footnote{\textcolor{black}{http://www.tcpdump.org/}%
+} \textcolor{black}{to receive packets and libnet}%
+\footnote{\textcolor{black}{http://www.packetfactory.net/projects/libnet/}%
+} \textcolor{black}{to send packets}
+\end{enumerate}
+\textcolor{black}{Although using libpcap/libnet would allow more simultaneous
+connections and greater flexibility, there would be a very high complexity
+cost associated with it. With that in mind, I've decided to use sockets
+to send and receive data.}
+
+
+\subsection{\textcolor{black}{Handling Multiple Connections}}
+
+\textcolor{black}{Because a pcap file can contain multiple simultaneous
+flows, we need to be able to support that too. The biggest problem
+with this is reading packet data in a different order then stored
+in the pcap file. }
+
+\textcolor{black}{Reading and writing to multiple sockets is easy
+with select() or poll(), however a pcap file has it's data stored
+serially, but we need to access it randomly. There are a number of
+possible solutions for this such as caching packets in RAM where they
+can be accessed more randomly, creating an index of the packets in
+the pcap file, or converting the pcap file to another format altogether.
+Alternatively, I've started looking at libpcapnav}%
+\footnote{http://netdude.sourceforge.net/%
+} \textcolor{black}{as an alternate means to navigate a pcap file and
+process packets out of order.}
+
+
+\subsection{\textcolor{black}{Data Synchronization}}
+
+\textcolor{black}{Knowing when to start sending client traffic in
+response to the server will be \char`\"{}tricky\char`\"{}. Without
+understanding the actual protocol involved, probably the best general
+solution is waiting for a given period of time after no more data
+from the server has been received. Not sure what to do if the client
+traffic doesn't elicit a response from the server (implement some
+kind of timeout?). This will be the basis for the default plug-in.}
+
+
+\subsection{\textcolor{black}{TCP/IP}}
+
+\textcolor{black}{Dealing with IP fragmentation and TCP stream reassembly
+will be another really complex problem. We're basically talking about
+implementing a significant portion of a TCP/IP stack. One thought
+is to use libnids}%
+\footnote{\textcolor{black}{http://www.avet.com.pl/\textasciitilde{}nergal/libnids/}%
+} \textcolor{black}{which basically implements a Linux 2.0.37 TCP/IP
+stack in user-space. Other solutions include porting a TCP/IP stack
+from Open/Net/FreeBSD or writing our own custom stack from scratch.}
+
+
+\section{\textcolor{black}{Multiple Independent Flows}}
+
+\textcolor{black}{The biggest asynchronous problem, that pcap files
+are serial, has to be solved in a scaleable manner. Not much can be
+assumed about the network traffic contained in a pcap savefile other
+then Murphy's Law will be in effect. This means we'll have to deal
+with:}
+
+\begin{itemize}
+\item \textcolor{black}{Thousands of small simultaneous flows (captured
+on a busy network)}
+\item \textcolor{black}{Flows which {}``hang'' mid-stream (an exploit
+against a server causes it to crash)}
+\item \textcolor{black}{Flows which contain large quantities of data (FTP
+transfers of ISO's for example)}
+\end{itemize}
+\textcolor{black}{How we implement parallel processing of the pcap
+savefile will dramatically effect how well we can scale. A few considerations:}
+
+\begin{itemize}
+\item Most Unix systems limit the maximum number of open file descriptors
+a single process can have. Generally speaking this shouldn't be a
+problem except for highly parallel pcap's.
+\item While RAM isn't limitless, we can use mmap() to get around this.
+\item Many Unix systems have enhanced solutions to poll() which will improve
+flow management.
+\end{itemize}
+\begin{comment}
+\textcolor{black}{Unix systems implement a maximum limit on the number
+of file descriptors a single process can open. My Linux box for example
+craps out at 1021 (it's really 1024, but 3 are reserved for STDIN,
+STDOUT, STDERR), which seems to be pretty standard for recent Unix's.
+This means we're limited to at most 1020 simultaneous flows if the
+pcap savefile is opened once and half that (510 flows) if the savefile
+is re-opened for each flow.}%
+\footnote{\textcolor{black}{It appears that most Unix-like OS's allow root to
+increase the {}``hard-limit'' beyond 1024. Compiling a list of methods
+to do this for common OS's should be added to the flowreplay documentation.}%
+}
+
+\textcolor{black}{RAM isn't limitless. Caching packets in memory may
+cause problems when one or more flows with a lot of data {}``hang''
+and their packets have to be cached so that other flows can be processed.
+If you work with large pcaps containing malicious traffic (say packet
+captures from DefCon), this sort of thing may be a real problem. Dealing
+with this situation would require complicated buffer limits and error
+handling.}
+
+\textcolor{black}{Jumping around in the pcap file via fgetpos() and
+fsetpos() is probably the most disk I/O intensive solution and may
+effect performance. However, on systems with enough free memory, one
+would hope the system disk cache will provide a dramatic speedup.
+The {}``bookmarks'' used by fgetpos/fsetpos are just 64 bit integers
+which are relatively space efficent compared to other solutions.}
+
+\textcolor{black}{The other typical asynchronous issue is dealing
+with multiple sockets, which we will solve via poll()}%
+\footnote{\textcolor{black}{poll(2)}%
+}\textcolor{black}{. Each flow will define a} \textcolor{black}{\emph{struct
+pollfd}} \textcolor{black}{and the amount of time in ms to timeout.
+Then prior to calling poll() we walk the list of flows and create
+the array of pollfd's and determine the flow(s) with the smallest
+timeout. A list of these flows is saved for when poll() returns. Finally,
+the current time is tucked away and the timeout and array of pollfd's
+is passed to poll().}
+
+\textcolor{black}{When poll() returns, the sockets that returned ready
+have their plug-in called. If no sockets are ready, then the flows
+saved prior to calling poll() are processed.}
+
+\textcolor{black}{Once all flows are processed, all the flows not
+processed have their timeout decremented by the time difference of
+the current time and when poll was last called and we start again.}
+\end{comment}
+
+\subsection{\textcolor{black}{IP Fragments and TCP Streams}}
+
+\textcolor{black}{There are five major complications with flowreplay:}
+
+\begin{enumerate}
+\item \textcolor{black}{The IP datagrams may be fragmented- we won't be
+able to use the standard 5-tuple (src/dst IP, src/dst port, protocol)
+to lookup which flow a packet belongs to.}
+\item \textcolor{black}{IP fragments may arrive out of order which will
+complicate ordering of data to be sent.}
+\item \textcolor{black}{The TCP segments may arrive out of order which will
+complicate ordering of data to be sent.}
+\item \textcolor{black}{Packets may be missing in the pcap file because
+they were dropped during capture.}
+\item \textcolor{black}{There are tools like fragrouter which intentionally
+create non-deterministic situations.}
+\end{enumerate}
+\textcolor{black}{First off, I've decided, that I'm not going to worry
+about fragrouter or it's cousins. I'll handle non-deterministic situations
+one and only one way, so that the way flowreplay handles the traffic
+will be deterministic. Perhaps, I'll make it easy for others to write
+a plug-in which will change it, but that's not something I'm going
+to concern myself with now.}
+
+\textcolor{black}{Missing packets in the pcap file will probably make
+that flow unplayable. There are proabably certain situation where
+we can make an educated guess, but this is far too complex to worry
+about for the first stable release.}
+
+\textcolor{black}{That still leaves creating a basic TCP/IP stack
+in user space. The good news it that there is already a library which
+does this called libnids. As of version 1.17, libnids can process
+packets from a pcap savefile (it's not documented in the man page,
+but the code is there).}
+
+\textcolor{black}{A potential problem with libnids though is that
+it has to maintain it's own state/cache system. This not only means
+additional overhead, but jumping around in the pcap file as I'm planning
+on doing to handle multiple simultaneous flows is likely to really
+confuse libnids' state engine. Also, libnids is licensed under the
+GPL, but I want flowreplay released under a BSD-like license; I need
+to research if the two are compatible in this way.}
+
+\textcolor{black}{Possible solutions:}
+
+\begin{itemize}
+\item \textcolor{black}{Developing a custom wedge between the capture file
+and libnids which will cause each packet to only be processed a single
+time.}
+\item \textcolor{black}{Use libnids to process the pcap file into a new
+flow-based format, effectively putting the TCP/IP stack into a dedicated
+utility.}
+\item \textcolor{black}{Develop a custom user-space TCP/IP stack, perhaps
+based on a BSD TCP/IP stack, much like libnids is based on Linux 2.0.37.}
+\item \textcolor{black}{Screw it and say that IP fragmentation and out of
+order IP packets/TCP segments are not supported. Not sure if this
+will meet the needs of potential users.}
+\end{itemize}
+
+\subsection{\textcolor{black}{Blocking}}
+
+\textcolor{black}{As earlier stated, one of the main goals of this
+project is to keep things single threaded to make coding plugins easier.
+One caveat of that is that any function which blocks will cause serious
+problems.}
+
+\textcolor{black}{There are three major cases where blocking is likely
+to occur:}
+
+\begin{enumerate}
+\item \textcolor{black}{Opening a socket}
+\item \textcolor{black}{Reading from a socket}
+\item \textcolor{black}{Writing to a socket}
+\end{enumerate}
+\textcolor{black}{Reading from sockets in a non-blocking manner is
+easy to solve for using poll() or select(). Writing to a socket, or
+merely opening a TCP socket via connect() however requires a different
+method:}
+
+\begin{quotation}
+\textcolor{black}{It is possible to do non-blocking IO on sockets
+by setting the O\_NONBLOCK flag on a socket file descriptor using
+fcntl(2). Then all operations that would block will (usually) return
+with EAGAIN (operation should be retried later); connect(2) will return
+EINPROGRESS error. The user can then wait for various events via poll(2)
+or select(2).}%
+\footnote{\textcolor{black}{socket(7)}%
+}
+\end{quotation}
+\textcolor{black}{If connect() returns EINPROGRESS, then we'll just
+have to do something like this:}
+
+\begin{lyxcode}
+\textcolor{black}{int~e,~len=sizeof(e);}
+
+\textcolor{black}{if~(getsockopt(conn->s,~SOL\_SOCKET,~SO\_ERROR,~\&e,~\&len)~<~0)~\{~}
+
+~\textcolor{black}{~~~/{*}~not~yet~{*}/}
+
+~\textcolor{black}{~~~if(errno~!=~EINPROGRESS)\{~~/{*}~yuck.~kill~it.~{*}/~}
+
+~\textcolor{black}{~~~~~~log\_fn(LOG\_DEBUG,\char`\"{}in-progress~connect~failed.~Removing.\char`\"{});~}
+
+~\textcolor{black}{~~~~~~return~-1;~}
+
+~\textcolor{black}{~~~\}~else~\{~}
+
+~\textcolor{black}{~~~~~~return~0;~/{*}~no~change,~see~if~next~time~is~better~{*}/~}
+
+~\textcolor{black}{~~~\}~}
+
+\textcolor{black}{\}~}
+
+\textcolor{black}{/{*}~the~connect~has~finished.~{*}/~}
+\end{lyxcode}
+\begin{quote}
+\textcolor{black}{Note: It may not be totally right, but it works
+ok. (that chunk of code gets called after poll returns the socket
+as writable. if poll returns it as readable, then it's probably because
+of eof, connect fails. You must poll for both.}
+\end{quote}
+
+\section{\textcolor{black}{pcap vs flow File Format}}
+
+\textcolor{black}{As stated before, the pcap file format really isn't
+well suited for flowreplay because it uses the raw packet as a container
+for data. Flowreplay however isn't interested in packets, it's interested
+in data streams}%
+\footnote{\textcolor{black}{A {}``data stream'' as I call it is a simplex
+communication from the client or server which is a complete query,
+response or message.}%
+} \textcolor{black}{which may span one or more TCP/UDP segments, each
+comprised of an IP datagram which may be comprised of multiple IP
+fragments. Handling all this additional complexity requires a full
+TCP/IP stack in user space which would have additional feature requirements
+specific to flowreplay.}
+
+\textcolor{black}{Rather then trying to do that, I've decided to create
+a pcap preprocessor for flowreplay called: flowprep. Flowprep will
+handle all the TCP/IP defragmentation/reassembly and write out a file
+containing the data streams for each flow.}
+
+\textcolor{black}{A flow file will contain three sections:}
+
+\begin{enumerate}
+\item \textcolor{black}{A header which identifies this as a flowprep file
+and the file version}
+\item \textcolor{black}{An index of all the flows contained in the file}
+\item \textcolor{black}{The data streams themselves}
+\end{enumerate}
+\begin{center}\textcolor{black}{\includegraphics{flowheader.eps}}\end{center}
+
+\textcolor{black}{At startup, the file header is validated and the
+data stream indexes are loaded into memory. Then the first data stream
+header from each flow is read. Then each flow and subsequent data
+stream is processed based upon the timestamps and plug-ins.}
+
+
+\section{\textcolor{black}{Plug-ins}}
+
+\textcolor{black}{Plug-ins will provide the {}``intelligence'' in
+flowreplay. Flowreplay is designed to be a mere framework for connecting
+captured flows in a flow file with socket file handles. How data is
+processed and what should be done with it will be done via plug-ins.}
+
+\textcolor{black}{Plug-ins will allow proper handling of a variety
+of protocols while hopefully keeping things simple. Another part of
+the consideration will be making it easy for others to contribute
+to flowreplay. I don't want to have to write all the protocol logic
+myself.}
+
+
+\subsection{\textcolor{black}{Plug-in Basics}}
+
+\textcolor{black}{Each plug-in provides the logic for handling one
+or more services. The main purpose of a plug-in is to decide when
+flowreplay should send data via one or more sockets. The plug-in can
+use any} \textcolor{black}{\emph{non-blocking}} \textcolor{black}{method
+of determining if it appropriate to send data or wait for data to
+received. If necessary, a plug-in can also modify the data sent.}
+
+\textcolor{black}{Each time poll() returns, flowreplay calls the plug-ins
+for the flows which either have data waiting or in the case of a timeout,
+those flows which timed out. Afterwords, all the flows are processed
+and poll() is called on those flows which have their state set to
+POLL. And the process repeats until there are no more nodes in the
+tree.}
+
+
+\subsection{\textcolor{black}{The Default Plug-in}}
+
+\textcolor{black}{Initially, flowreplay will ship with one basic plug-in
+called {}``default''. Any flow which doesn't have a specific plug-in
+defined, will use default. The goal of the default plug-in is to work
+{}``good enough'' for a majority of single-flow protocols such as
+SMTP, HTTP, and Telnet. Protocols which use encryption (SSL, SSH,
+etc) or multiple flows (FTP, RPC, etc) will never work with the default
+plug-in. Furthermore, the default plug-in will only support connections}
+\textcolor{black}{\emph{to}} \textcolor{black}{a server, it will not
+support accepting connections from clients.}
+
+\textcolor{black}{The default plug-in will provide no data level manipulation
+and only a simple method for detecting when it is time to send data
+to the server. Detecting when to send data will be done by a {}``no
+more data'' timeout value. Basically, by using the pcap file as a
+means to determine the order of the exchange, anytime it is the servers
+turn to send data, flowreplay will wait for the first byte of data
+and then start the {}``no more data'' timer. Every time more data
+is received, the timer is reset. If the timer reaches zero, then flowreplay
+sends the next portion of the client side of the connection. This
+is repeated until the the flow has been completely replayed or a {}``server
+hung'' timeout is reached. The server hung timeout is used to detect
+a server which crashed and never starts sending any data which would
+start the {}``no more data'' timer.}
+
+\textcolor{black}{Both the {}``no more data'' and {}``server hung''
+timers will be user defined values and global to all flows using the
+default plug-in.}
+
+
+\subsection{\textcolor{black}{Plug-in Details}}
+
+\textcolor{black}{Each plug-in will be comprised of the following:}
+
+\begin{enumerate}
+\item \textcolor{black}{An optional global data structure, for intra-flow
+communication}
+\item \textcolor{black}{Per-flow data structure, for tracking flow state
+information}
+\item \textcolor{black}{A list of functions which flow replay will call
+when certain well-defined conditions are met.}
+
+\begin{itemize}
+\item \textcolor{black}{Required functions:}
+
+\begin{itemize}
+\item \textcolor{black}{initialize\_node() - called when a node in the tree
+created using this plug-in}
+\item \textcolor{black}{post\_poll\_timeout() - called when the poll() returned
+due to a timeout for this node}
+\item \textcolor{black}{post\_poll\_read() - called when the poll() returned
+due to the socket being ready}
+\item \textcolor{black}{buffer\_full() - called when a the packet buffer
+for this flow is full}
+\item \textcolor{black}{delete\_node() - called just prior to the node being
+free()'d}
+\end{itemize}
+\item \textcolor{black}{Optional functions:}
+
+\begin{itemize}
+\item \textcolor{black}{pre\_send\_data() - called before data is sent}
+\item \textcolor{black}{post\_send\_data() - called after data is sent}
+\item \textcolor{black}{pre\_poll() - called prior to poll()}
+\item \textcolor{black}{post\_poll\_default() - called when poll() returns
+and neither the socket was ready or the node timed out }
+\item \textcolor{black}{open\_socket() - called after the socket is opened}
+\item \textcolor{black}{close\_socket() - called after the socket is closed}
+\end{itemize}
+\end{itemize}
+\end{enumerate}
+\begin{lyxcode}
+
+
+\end{lyxcode}
+
+\end{document}

+ 498 - 0
Docs/flowreplay.txt

@@ -0,0 +1,498 @@
+Flowreplay Design Notes
+
+Aaron Turner 
+http://synfin.net/
+
+Last Edited:
+October 23, 2003
+
+ Overview
+
+Tcpreplayhttp://tcpreplay.sourceforge.net/ was designed to replay traffic previously 
+captured in the pcap format back onto the wire for 
+testing NIDS and other passive devices. Over time, it 
+was enhanced to be able to test in-line network 
+devices. However, a re-occurring feature request for 
+tcpreplay is to connect to a server in order to test 
+applications and host TCP/IP stacks. It was determined 
+early on, that adding this feature to tcpreplay was far 
+too complex, so I decided to create a new tool 
+specifically designed for this.
+
+Flowreplay is designed to replay traffic at Layer 4 or 
+7 depending on the protocol rather then at Layer 2 like 
+tcpreplay does. This allows flowreplay to connect to 
+one or more servers using a pcap savefile as the basis 
+of the connections. Hence, flowreplay allows the 
+testing of applications running on real servers rather 
+then passive devices. 
+
+ Features
+
+ Requirements
+
+ Full TCP/IP support, including IP fragments and TCP 
+  stream reassembly.
+
+ Support replaying TCP and UDP flows.
+
+ Code should handle each flow/service independently.
+
+ Should be able to connect to the server(s) in the pcap 
+  file or to a user specified IP address.
+
+ Support a plug-in architecture to allow adding 
+  application layer intelligence.
+
+ Plug-ins must be able to support multi-flow protocols 
+  like FTP.
+
+ Ship with a default plug-in which will work "well enough"
+   for simple single-flow protocols like HTTP and telnet.
+
+ Flows being replayed "correctly" is more important then 
+  performance (Mbps).
+
+ Portable to run on common flavors of Unix and 
+  Unix-like systems.
+
+ Wishes
+
+ Support clients connecting to flowreplay on a limited 
+  basis. Flowreplay would replay the server side of the 
+  connection.
+
+ Support other IP based traffic (ICMP, VRRP, OSPF, etc) 
+  via plug-ins.
+
+ Support non-IP traffic (ARP, STP, CDP, etc) via plug-ins.
+
+ Limit which flows are replayed using user defined 
+  filters. (bpf filter syntax?)
+
+ Process pcap files directly with no intermediary file 
+  conversions.
+
+ Should be able to scale to pcap files in the 100's of 
+  MB in size and 100+ simultaneous flows on a P3 500MHz 
+  w/ 256MB of RAM.
+
+ Design Thoughts
+
+ Sending and Receiving traffic
+
+Flowreplay must be able to process multiple connections 
+to one or more devices. There are two options:
+
+ Use socketssocket(2) to send and receive data
+
+ Use libpcaphttp://www.tcpdump.org/ to receive packets and libnethttp://www.packetfactory.net/projects/libnet/ to send packets
+
+Although using libpcap/libnet would allow more 
+simultaneous connections and greater flexibility, there 
+would be a very high complexity cost associated with 
+it. With that in mind, I've decided to use sockets to 
+send and receive data.
+
+ Handling Multiple Connections
+
+Because a pcap file can contain multiple simultaneous 
+flows, we need to be able to support that too. The 
+biggest problem with this is reading packet data in a 
+different order then stored in the pcap file. 
+
+Reading and writing to multiple sockets is easy with 
+select() or poll(), however a pcap file has it's data 
+stored serially, but we need to access it randomly. 
+There are a number of possible solutions for this such 
+as caching packets in RAM where they can be accessed 
+more randomly, creating an index of the packets in the 
+pcap file, or converting the pcap file to another 
+format altogether. Alternatively, I've started looking 
+at libpcapnavhttp://netdude.sourceforge.net/ as an alternate means to navigate a pcap 
+file and process packets out of order.
+
+ Data Synchronization
+
+Knowing when to start sending client traffic in 
+response to the server will be "tricky". Without 
+understanding the actual protocol involved, probably 
+the best general solution is waiting for a given period 
+of time after no more data from the server has been 
+received. Not sure what to do if the client traffic 
+doesn't elicit a response from the server (implement 
+some kind of timeout?). This will be the basis for the 
+default plug-in.
+
+ TCP/IP
+
+Dealing with IP fragmentation and TCP stream reassembly 
+will be another really complex problem. We're basically 
+talking about implementing a significant portion of a 
+TCP/IP stack. One thought is to use libnidshttp://www.avet.com.pl/~nergal/libnids/ which 
+basically implements a Linux 2.0.37 TCP/IP stack in 
+user-space. Other solutions include porting a TCP/IP 
+stack from Open/Net/FreeBSD or writing our own custom 
+stack from scratch.
+
+ Multiple Independent Flows
+
+The biggest asynchronous problem, that pcap files are 
+serial, has to be solved in a scaleable manner. Not 
+much can be assumed about the network traffic contained 
+in a pcap savefile other then Murphy's Law will be in 
+effect. This means we'll have to deal with:
+
+ Thousands of small simultaneous flows (captured on a 
+  busy network)
+
+ Flows which "hang" mid-stream (an exploit against a 
+  server causes it to crash)
+
+ Flows which contain large quantities of data (FTP 
+  transfers of ISO's for example)
+
+How we implement parallel processing of the pcap 
+savefile will dramatically effect how well we can 
+scale. A few considerations:
+
+ Most Unix systems limit the maximum number of open 
+  file descriptors a single process can have. Generally 
+  speaking this shouldn't be a problem except for 
+  highly parallel pcap's.
+
+ While RAM isn't limitless, we can use mmap() to get 
+  around this.
+
+ Many Unix systems have enhanced solutions to poll() 
+  which will improve flow management.
+
+Unix systems implement a maximum limit on the number of 
+file descriptors a single process can open. My Linux 
+box for example craps out at 1021 (it's really 1024, 
+but 3 are reserved for STDIN, STDOUT, STDERR), which 
+seems to be pretty standard for recent Unix's. This 
+means we're limited to at most 1020 simultaneous flows 
+if the pcap savefile is opened once and half that (510 
+flows) if the savefile is re-opened for each flow.It appears that most Unix-like OS's allow root to 
+increase the "hard-limit" beyond 1024. Compiling a list 
+of methods to do this for common OS's should be added 
+to the flowreplay documentation.
+
+RAM isn't limitless. Caching packets in memory may 
+cause problems when one or more flows with a lot of 
+data "hang" and their packets have to be cached so that 
+other flows can be processed. If you work with large 
+pcaps containing malicious traffic (say packet captures 
+from DefCon), this sort of thing may be a real problem. 
+Dealing with this situation would require complicated 
+buffer limits and error handling.
+
+Jumping around in the pcap file via fgetpos() and 
+fsetpos() is probably the most disk I/O intensive 
+solution and may effect performance. However, on 
+systems with enough free memory, one would hope the 
+system disk cache will provide a dramatic speedup. The "bookmarks"
+ used by fgetpos/fsetpos are just 64 bit integers which 
+are relatively space efficent compared to other solutions.
+
+The other typical asynchronous issue is dealing with 
+multiple sockets, which we will solve via poll()poll(2). Each 
+flow will define a struct pollfd and the amount of time 
+in ms to timeout. Then prior to calling poll() we walk 
+the list of flows and create the array of pollfd's and 
+determine the flow(s) with the smallest timeout. A list 
+of these flows is saved for when poll() returns. 
+Finally, the current time is tucked away and the 
+timeout and array of pollfd's is passed to poll().
+
+When poll() returns, the sockets that returned ready 
+have their plug-in called. If no sockets are ready, 
+then the flows saved prior to calling poll() are processed.
+
+Once all flows are processed, all the flows not 
+processed have their timeout decremented by the time 
+difference of the current time and when poll was last 
+called and we start again.
+
+ IP Fragments and TCP Streams
+
+There are five major complications with flowreplay:
+
+ The IP datagrams may be fragmented- we won't be able 
+  to use the standard 5-tuple (src/dst IP, src/dst 
+  port, protocol) to lookup which flow a packet belongs to.
+
+ IP fragments may arrive out of order which will 
+  complicate ordering of data to be sent.
+
+ The TCP segments may arrive out of order which will 
+  complicate ordering of data to be sent.
+
+ Packets may be missing in the pcap file because they 
+  were dropped during capture.
+
+ There are tools like fragrouter which intentionally 
+  create non-deterministic situations.
+
+First off, I've decided, that I'm not going to worry 
+about fragrouter or it's cousins. I'll handle 
+non-deterministic situations one and only one way, so 
+that the way flowreplay handles the traffic will be 
+deterministic. Perhaps, I'll make it easy for others to 
+write a plug-in which will change it, but that's not 
+something I'm going to concern myself with now.
+
+Missing packets in the pcap file will probably make 
+that flow unplayable. There are proabably certain 
+situation where we can make an educated guess, but this 
+is far too complex to worry about for the first stable release.
+
+That still leaves creating a basic TCP/IP stack in user 
+space. The good news it that there is already a library 
+which does this called libnids. As of version 1.17, 
+libnids can process packets from a pcap savefile (it's 
+not documented in the man page, but the code is there).
+
+A potential problem with libnids though is that it has 
+to maintain it's own state/cache system. This not only 
+means additional overhead, but jumping around in the 
+pcap file as I'm planning on doing to handle multiple 
+simultaneous flows is likely to really confuse libnids' 
+state engine. Also, libnids is licensed under the GPL, 
+but I want flowreplay released under a BSD-like 
+license; I need to research if the two are compatible 
+in this way.
+
+Possible solutions:
+
+ Developing a custom wedge between the capture file and 
+  libnids which will cause each packet to only be 
+  processed a single time.
+
+ Use libnids to process the pcap file into a new 
+  flow-based format, effectively putting the TCP/IP 
+  stack into a dedicated utility.
+
+ Develop a custom user-space TCP/IP stack, perhaps 
+  based on a BSD TCP/IP stack, much like libnids is 
+  based on Linux 2.0.37.
+
+ Screw it and say that IP fragmentation and out of 
+  order IP packets/TCP segments are not supported. Not 
+  sure if this will meet the needs of potential users.
+
+ Blocking
+
+As earlier stated, one of the main goals of this 
+project is to keep things single threaded to make 
+coding plugins easier. One caveat of that is that any 
+function which blocks will cause serious problems.
+
+There are three major cases where blocking is likely to occur:
+
+ Opening a socket
+
+ Reading from a socket
+
+ Writing to a socket
+
+Reading from sockets in a non-blocking manner is easy 
+to solve for using poll() or select(). Writing to a 
+socket, or merely opening a TCP socket via connect() 
+however requires a different method:
+
+It is possible to do non-blocking IO on sockets by 
+setting the O_NONBLOCK flag on a socket file descriptor 
+using fcntl(2). Then all operations that would block 
+will (usually) return with EAGAIN (operation should be 
+retried later); connect(2) will return EINPROGRESS 
+error. The user can then wait for various events via 
+poll(2) or select(2).socket(7)
+
+If connect() returns EINPROGRESS, then we'll just have 
+to do something like this:
+
+int e, len=sizeof(e);
+
+if (getsockopt(conn->s, SOL_SOCKET, SO_ERROR, &e, &len) 
+< 0) { 
+
+    /* not yet */
+
+    if(errno != EINPROGRESS){  /* yuck. kill it. */ 
+
+       log_fn(LOG_DEBUG,"in-progress connect failed. 
+Removing."); 
+
+       return -1; 
+
+    } else { 
+
+       return 0; /* no change, see if next time is 
+better */ 
+
+    } 
+
+} 
+
+/* the connect has finished. */ 
+
+Note: It may not be totally right, but it works ok. 
+(that chunk of code gets called after poll returns the 
+socket as writable. if poll returns it as readable, 
+then it's probably because of eof, connect fails. You 
+must poll for both.
+
+ pcap vs flow File Format
+
+As stated before, the pcap file format really isn't 
+well suited for flowreplay because it uses the raw 
+packet as a container for data. Flowreplay however 
+isn't interested in packets, it's interested in data streamsA "data stream" as I call it is a simplex communication 
+from the client or server which is a complete query, 
+response or message.
+ which may span one or more TCP/UDP segments, each 
+comprised of an IP datagram which may be comprised of 
+multiple IP fragments. Handling all this additional 
+complexity requires a full TCP/IP stack in user space 
+which would have additional feature requirements 
+specific to flowreplay.
+
+Rather then trying to do that, I've decided to create a 
+pcap preprocessor for flowreplay called: flowprep. 
+Flowprep will handle all the TCP/IP 
+defragmentation/reassembly and write out a file 
+containing the data streams for each flow.
+
+A flow file will contain three sections:
+
+ A header which identifies this as a flowprep file and 
+  the file version
+
+ An index of all the flows contained in the file
+
+ The data streams themselves
+
+<Graphics file: flowheader.eps>
+
+
+At startup, the file header is validated and the data 
+stream indexes are loaded into memory. Then the first 
+data stream header from each flow is read. Then each 
+flow and subsequent data stream is processed based upon 
+the timestamps and plug-ins.
+
+ Plug-ins
+
+Plug-ins will provide the "intelligence" in flowreplay. 
+Flowreplay is designed to be a mere framework for 
+connecting captured flows in a flow file with socket 
+file handles. How data is processed and what should be 
+done with it will be done via plug-ins.
+
+Plug-ins will allow proper handling of a variety of 
+protocols while hopefully keeping things simple. 
+Another part of the consideration will be making it 
+easy for others to contribute to flowreplay. I don't 
+want to have to write all the protocol logic myself.
+
+ Plug-in Basics
+
+Each plug-in provides the logic for handling one or 
+more services. The main purpose of a plug-in is to 
+decide when flowreplay should send data via one or more 
+sockets. The plug-in can use any non-blocking method of 
+determining if it appropriate to send data or wait for 
+data to received. If necessary, a plug-in can also 
+modify the data sent.
+
+Each time poll() returns, flowreplay calls the plug-ins 
+for the flows which either have data waiting or in the 
+case of a timeout, those flows which timed out. 
+Afterwords, all the flows are processed and poll() is 
+called on those flows which have their state set to 
+POLL. And the process repeats until there are no more 
+nodes in the tree.
+
+ The Default Plug-in
+
+Initially, flowreplay will ship with one basic plug-in 
+called "default". Any flow which doesn't have a specific 
+plug-in defined, will use default. The goal of the 
+default plug-in is to work "good enough" for a majority 
+of single-flow protocols such as SMTP, HTTP, and 
+Telnet. Protocols which use encryption (SSL, SSH, etc) 
+or multiple flows (FTP, RPC, etc) will never work with 
+the default plug-in. Furthermore, the default plug-in 
+will only support connections to a server, it will not 
+support accepting connections from clients.
+
+The default plug-in will provide no data level 
+manipulation and only a simple method for detecting 
+when it is time to send data to the server. Detecting 
+when to send data will be done by a "no more data" 
+timeout value. Basically, by using the pcap file as a 
+means to determine the order of the exchange, anytime 
+it is the servers turn to send data, flowreplay will 
+wait for the first byte of data and then start the "no 
+more data" timer. Every time more data is received, the 
+timer is reset. If the timer reaches zero, then 
+flowreplay sends the next portion of the client side of 
+the connection. This is repeated until the the flow has 
+been completely replayed or a "server hung" timeout is 
+reached. The server hung timeout is used to detect a 
+server which crashed and never starts sending any data 
+which would start the "no more data" timer.
+
+Both the "no more data" and "server hung" timers will be 
+user defined values and global to all flows using the 
+default plug-in.
+
+ Plug-in Details
+
+Each plug-in will be comprised of the following:
+
+ An optional global data structure, for intra-flow communication
+
+ Per-flow data structure, for tracking flow state information
+
+ A list of functions which flow replay will call when 
+  certain well-defined conditions are met.
+
+   Required functions:
+
+     initialize_node() - called when a node in the tree 
+      created using this plug-in
+
+     post_poll_timeout() - called when the poll() 
+      returned due to a timeout for this node
+
+     post_poll_read() - called when the poll() returned 
+      due to the socket being ready
+
+     buffer_full() - called when a the packet buffer 
+      for this flow is full
+
+     delete_node() - called just prior to the node 
+      being free()'d
+
+   Optional functions:
+
+     pre_send_data() - called before data is sent
+
+     post_send_data() - called after data is sent
+
+     pre_poll() - called prior to poll()
+
+     post_poll_default() - called when poll() returns 
+      and neither the socket was ready or the node 
+      timed out 
+
+     open_socket() - called after the socket is opened
+
+     close_socket() - called after the socket is closed
+
+
+
+

+ 5 - 0
Docs/images.aux

@@ -0,0 +1,5 @@
+\relax 
+\select@language{english}
+\@writefile{toc}{\select@language{english}}
+\@writefile{lof}{\select@language{english}}
+\@writefile{lot}{\select@language{english}}

+ 234 - 0
Docs/images.log

@@ -0,0 +1,234 @@
+This is e-TeX, Version 3.14159-2.1 (Web2C 7.4.5) (format=latex 2005.2.7)  10 FEB 2005 12:32
+entering extended mode
+**./images.tex
+(./images.tex
+LaTeX2e <2001/06/01>
+Babel <v3.7h> and hyphenation patterns for american, french, ngerman, nohyphena
+tion, loaded.
+
+(/usr/share/texmf/tex/latex/base/article.cls
+Document Class: article 2001/04/21 v1.4e Standard LaTeX document class
+(/usr/share/texmf/tex/latex/base/size10.clo
+File: size10.clo 2001/04/21 v1.4e Standard LaTeX file (size option)
+)
+\c@part=\count79
+\c@section=\count80
+\c@subsection=\count81
+\c@subsubsection=\count82
+\c@paragraph=\count83
+\c@subparagraph=\count84
+\c@figure=\count85
+\c@table=\count86
+\abovecaptionskip=\skip41
+\belowcaptionskip=\skip42
+\bibindent=\dimen102
+) (/usr/share/texmf/tex/latex/base/ifthen.sty
+Package: ifthen 2001/05/26 v1.1c Standard LaTeX ifthen package (DPC)
+) (/usr/share/texmf/tex/latex/misc/pslatex.sty
+Package: pslatex 1996/07/24 v1.2 pslatex emulation (DPC)
+LaTeX Font Info:    Redeclaring symbol font `operators' on input line 65.
+LaTeX Font Info:    Overwriting symbol font `operators' in version `normal'
+(Font)                  OT1/cmr/m/n --> OT1/ptmcm/m/n on input line 65.
+LaTeX Font Info:    Overwriting symbol font `operators' in version `bold'
+(Font)                  OT1/cmr/bx/n --> OT1/ptmcm/m/n on input line 65.
+LaTeX Font Info:    Redeclaring symbol font `letters' on input line 66.
+LaTeX Font Info:    Overwriting symbol font `letters' in version `normal'
+(Font)                  OML/cmm/m/it --> OML/ptmcm/m/it on input line 66.
+LaTeX Font Info:    Overwriting symbol font `letters' in version `bold'
+(Font)                  OML/cmm/b/it --> OML/ptmcm/m/it on input line 66.
+LaTeX Font Info:    Redeclaring symbol font `symbols' on input line 67.
+LaTeX Font Info:    Overwriting symbol font `symbols' in version `normal'
+(Font)                  OMS/cmsy/m/n --> OMS/pzccm/m/n on input line 67.
+LaTeX Font Info:    Overwriting symbol font `symbols' in version `bold'
+(Font)                  OMS/cmsy/b/n --> OMS/pzccm/m/n on input line 67.
+LaTeX Font Info:    Redeclaring symbol font `largesymbols' on input line 68.
+LaTeX Font Info:    Overwriting symbol font `largesymbols' in version `normal'
+(Font)                  OMX/cmex/m/n --> OMX/psycm/m/n on input line 68.
+LaTeX Font Info:    Overwriting symbol font `largesymbols' in version `bold'
+(Font)                  OMX/cmex/m/n --> OMX/psycm/m/n on input line 68.
+\symbold=\mathgroup4
+\symitalic=\mathgroup5
+LaTeX Font Info:    Redeclaring math alphabet \mathbf on input line 74.
+LaTeX Font Info:    Overwriting math alphabet `\mathbf' in version `normal'
+(Font)                  OT1/cmr/bx/n --> OT1/ptm/bx/n on input line 74.
+LaTeX Font Info:    Overwriting math alphabet `\mathbf' in version `bold'
+(Font)                  OT1/cmr/bx/n --> OT1/ptm/bx/n on input line 74.
+LaTeX Font Info:    Redeclaring math alphabet \mathit on input line 75.
+LaTeX Font Info:    Overwriting math alphabet `\mathit' in version `normal'
+(Font)                  OT1/cmr/m/it --> OT1/ptm/m/it on input line 75.
+LaTeX Font Info:    Overwriting math alphabet `\mathit' in version `bold'
+(Font)                  OT1/cmr/bx/it --> OT1/ptm/m/it on input line 75.
+) (/usr/share/texmf/tex/latex/base/fontenc.sty
+Package: fontenc 2001/06/05 v1.94 Standard LaTeX package
+(/usr/share/texmf/tex/latex/base/t1enc.def
+File: t1enc.def 2001/06/05 v1.94 Standard LaTeX file
+LaTeX Font Info:    Redeclaring font encoding T1 on input line 38.
+)) (/usr/share/texmf/tex/latex/base/inputenc.sty
+Package: inputenc 2001/07/10 v0.99a Input encoding file 
+(/usr/share/texmf/tex/latex/base/latin1.def
+File: latin1.def 2001/07/10 v0.99a Input encoding file 
+)) (/usr/share/texmf/tex/latex/misc/geometry.sty
+Package: geometry 2002/07/08 v3.2 Page Geometry
+(/usr/share/texmf/tex/latex/graphics/keyval.sty
+Package: keyval 1999/03/16 v1.13 key=value parser (DPC)
+\KV@toks@=\toks14
+)
+\Gm@cnth=\count87
+\Gm@cntv=\count88
+\c@Gm@tempcnt=\count89
+\Gm@bindingoffset=\dimen103
+\Gm@wd@mp=\dimen104
+\Gm@odd@mp=\dimen105
+\Gm@even@mp=\dimen106
+\Gm@dimlist=\toks15
+(/usr/share/texmf/tex/latex/config/geometry.cfg
+File: geometry.cfg 2001/06/05 v1.0 teTeX (uncustomised setup)
+)) (/usr/share/texmf/tex/latex/graphics/color.sty
+Package: color 1999/02/16 v1.0i Standard LaTeX Color (DPC)
+(/usr/share/texmf/tex/latex/config/color.cfg
+File: color.cfg 2001/08/31 v1.1 color configuration of teTeX/TeXLive
+)
+Package color Info: Driver file: dvips.def on input line 125.
+(/usr/share/texmf/tex/latex/graphics/dvips.def
+File: dvips.def 1999/02/16 v3.0i Driver-dependant file (DPC,SPQR)
+) (/usr/share/texmf/tex/latex/graphics/dvipsnam.def
+File: dvipsnam.def 1999/02/16 v3.0i Driver-dependant file (DPC,SPQR)
+)) (/usr/share/texmf/tex/latex/graphics/graphicx.sty
+Package: graphicx 1999/02/16 v1.0f Enhanced LaTeX Graphics (DPC,SPQR)
+(/usr/share/texmf/tex/latex/graphics/graphics.sty
+Package: graphics 2001/07/07 v1.0n Standard LaTeX Graphics (DPC,SPQR)
+(/usr/share/texmf/tex/latex/graphics/trig.sty
+Package: trig 1999/03/16 v1.09 sin cos tan (DPC)
+) (/usr/share/texmf/tex/latex/config/graphics.cfg
+File: graphics.cfg 2001/08/31 v1.1 graphics configuration of teTeX/TeXLive
+)
+Package graphics Info: Driver file: dvips.def on input line 80.
+)
+\Gin@req@height=\dimen107
+\Gin@req@width=\dimen108
+) (/usr/share/texmf/tex/latex/tools/verbatim.sty
+Package: verbatim 2001/03/12 v1.5p LaTeX2e package for verbatim enhancements
+\every@verbatim=\toks16
+\verbatim@line=\toks17
+\verbatim@in@stream=\read1
+) (/usr/share/texmf/tex/generic/babel/babel.sty
+Package: babel 2001/03/01 v3.7h The Babel package
+(/usr/share/texmf/tex/generic/babel/english.ldf
+Language: english 2001/04/15 v3.3l English support from the babel system
+(/usr/share/texmf/tex/generic/babel/babel.def
+File: babel.def 2001/03/01 v3.7h Babel common definitions
+\babel@savecnt=\count90
+\U@D=\dimen109
+)
+\l@canadian = a dialect from \language\l@english 
+))
+\sizebox=\box26
+\lthtmlwrite=\write3
+No file images.aux.
+\openout1 = `images.aux'.
+
+LaTeX Font Info:    Checking defaults for OML/cmm/m/it on input line 146.
+LaTeX Font Info:    ... okay on input line 146.
+LaTeX Font Info:    Checking defaults for T1/cmr/m/n on input line 146.
+LaTeX Font Info:    ... okay on input line 146.
+LaTeX Font Info:    Checking defaults for OT1/cmr/m/n on input line 146.
+LaTeX Font Info:    ... okay on input line 146.
+LaTeX Font Info:    Checking defaults for OMS/pzccm/m/n on input line 146.
+LaTeX Font Info:    Try loading font information for OMS+pzccm on input line 14
+6.
+(/usr/share/texmf/tex/latex/psnfss/omspzccm.fd
+File: omspzccm.fd 2000/01/03 Fontinst v1.801 font definitions for OMS/pzccm.
+)
+LaTeX Font Info:    ... okay on input line 146.
+LaTeX Font Info:    Checking defaults for OMX/cmex/m/n on input line 146.
+LaTeX Font Info:    ... okay on input line 146.
+LaTeX Font Info:    Checking defaults for U/cmr/m/n on input line 146.
+LaTeX Font Info:    ... okay on input line 146.
+
+Package geometry Warning: The marginal notes would fall off the page.
+     Add 47.54726pt and more to the right margin.
+
+-------------------- Geometry parameters
+paper: letterpaper
+landscape: --
+twocolumn: --
+twoside: --
+asymmetric: --
+h-parts: 28.45274pt, 557.38951pt, 28.45274pt
+v-parts: 28.45274pt, 723.83812pt, 42.67912pt
+hmarginratio: --
+vmarginratio: --
+lines: --
+heightrounded: --
+bindingoffset: 0.0pt
+truedimen: --
+includehead: --
+includefoot: --
+includemp: --
+driver: 
+-------------------- Page layout dimensions and switches
+\paperwidth  614.295pt
+\paperheight 794.96999pt
+\textwidth  349.0pt
+\textheight 710.02087pt
+\oddsidemargin  -43.81725pt
+\evensidemargin -43.81725pt
+\topmargin  0.0pt
+\headheight 0.0pt
+\headsep    0.0pt
+\footskip   0.0pt
+\marginparwidth 65.0pt
+\marginparsep   11.0pt
+\columnsep  10.0pt
+\skip\footins  9.0pt plus 4.0pt minus 2.0pt
+\hoffset 0.0pt
+\voffset 0.0pt
+\mag 1000
+
+(1in=72.27pt, 1cm=28.45pt)
+-----------------------
+
+latex2htmlLength hsize=349.0pt
+
+latex2htmlLength vsize=710.02087pt
+
+latex2htmlLength hoffset=0.0pt
+
+latex2htmlLength voffset=0.0pt
+
+latex2htmlLength topmargin=0.0pt
+
+latex2htmlLength topskip=0.00003pt
+
+latex2htmlLength headheight=0.0pt
+
+latex2htmlLength headsep=0.0pt
+
+latex2htmlLength parskip=6.0pt plus 2.0pt minus 2.0pt
+
+latex2htmlLength oddsidemargin=-43.81725pt
+
+latex2htmlLength evensidemargin=-43.81725pt
+
+File: flowheader.eps Graphic file (type eps)
+<flowheader.eps>
+Overfull \hbox (82.61249pt too wide) detected at line 186
+ [] 
+ []
+
+l2hSize :tex2html_wrap933:471.7625pt::0.0pt::349.0pt.
+[1
+
+
+
+] (./images.aux) ) 
+Here is how much of TeX's memory you used:
+ 1868 strings out of 95739
+ 23052 string characters out of 1194636
+ 70830 words of memory out of 1000001
+ 4878 multiletter control sequences out of 10000+50000
+ 5791 words of font info for 16 fonts, out of 500000 for 1000
+ 14 hyphenation exceptions out of 1000
+ 25i,5n,21p,207b,194s stack positions out of 1500i,500n,5000p,200000b,5000s
+
+Output written on images.dvi (1 page, 324 bytes).

+ 12 - 0
Docs/images.pl

@@ -0,0 +1,12 @@
+# LaTeX2HTML 2002-2-1 (1.70)
+# Associate images original text with physical files.
+
+
+$key = q/includegraphics{flowheader.eps};AAT/;
+$cached_env_img{$key} = q|<IMG
+ WIDTH="668" HEIGHT="748" ALIGN="BOTTOM" BORDER="0"
+ SRC="|."$dir".q|img1.png"
+ ALT="\includegraphics{flowheader.eps}">|; 
+
+1;
+

+ 193 - 0
Docs/images.tex

@@ -0,0 +1,193 @@
+\batchmode
+
+\documentclass[english]{article}
+\RequirePackage{ifthen}
+
+
+\usepackage{pslatex}
+\usepackage[T1]{fontenc}
+\usepackage[latin1]{inputenc}
+\usepackage{geometry}
+\geometry{verbose,letterpaper,tmargin=10mm,bmargin=15mm,lmargin=10mm,rmargin=10mm}
+\setcounter{secnumdepth}{4}
+
+\setlength \parskip{\medskipamount}
+
+\setlength \parindent{0pt}
+\usepackage{color}
+\usepackage{graphicx}
+
+
+\makeatletter
+\usepackage{verbatim}
+ 
+%
+\newenvironment{lyxcode}{\begin{list}{}{
+     \setlength{\rightmargin}{\leftmargin}
+     \setlength{\listparindent}{0pt}% needed for AMS classes
+     \raggedright
+     \setlength{\itemsep}{0pt}
+     \setlength{\parsep}{0pt}
+     \normalfont\ttfamily}%
+    \item[]}
+   {\end{list}} 
+
+
+\AtBeginDocument{
+  %
+\renewcommand{\labelitemii}{\(\ast\)}
+  %
+\renewcommand{\labelitemiii}{\normalfont\bfseries{--}}
+}
+
+
+\usepackage{babel}
+\makeatother
+
+
+
+\pagecolor[gray]{.7}
+
+\usepackage[]{inputenc}
+
+
+
+\makeatletter
+
+\makeatletter
+\count@=\the\catcode`\_ \catcode`\_=8 
+\newenvironment{tex2html_wrap}{}{}%
+\catcode`\<=12\catcode`\_=\count@
+\newcommand{\providedcommand}[1]{\expandafter\providecommand\csname #1\endcsname}%
+\newcommand{\renewedcommand}[1]{\expandafter\providecommand\csname #1\endcsname{}%
+  \expandafter\renewcommand\csname #1\endcsname}%
+\newcommand{\newedenvironment}[1]{\newenvironment{#1}{}{}\renewenvironment{#1}}%
+\let\newedcommand\renewedcommand
+\let\renewedenvironment\newedenvironment
+\makeatother
+\let\mathon=$
+\let\mathoff=$
+\ifx\AtBeginDocument\undefined \newcommand{\AtBeginDocument}[1]{}\fi
+\newbox\sizebox
+\setlength{\hoffset}{0pt}\setlength{\voffset}{0pt}
+\addtolength{\textheight}{\footskip}\setlength{\footskip}{0pt}
+\addtolength{\textheight}{\topmargin}\setlength{\topmargin}{0pt}
+\addtolength{\textheight}{\headheight}\setlength{\headheight}{0pt}
+\addtolength{\textheight}{\headsep}\setlength{\headsep}{0pt}
+\setlength{\textwidth}{349pt}
+\newwrite\lthtmlwrite
+\makeatletter
+\let\realnormalsize=\normalsize
+\global\topskip=2sp
+\def\preveqno{}\let\real@float=\@float \let\realend@float=\end@float
+\def\@float{\let\@savefreelist\@freelist\real@float}
+\def\liih@math{\ifmmode$\else\bad@math\fi}
+\def\end@float{\realend@float\global\let\@freelist\@savefreelist}
+\let\real@dbflt=\@dbflt \let\end@dblfloat=\end@float
+\let\@largefloatcheck=\relax
+\let\if@boxedmulticols=\iftrue
+\def\@dbflt{\let\@savefreelist\@freelist\real@dbflt}
+\def\adjustnormalsize{\def\normalsize{\mathsurround=0pt \realnormalsize
+ \parindent=0pt\abovedisplayskip=0pt\belowdisplayskip=0pt}%
+ \def\phantompar{\csname par\endcsname}\normalsize}%
+\def\lthtmltypeout#1{{\let\protect\string \immediate\write\lthtmlwrite{#1}}}%
+\newcommand\lthtmlhboxmathA{\adjustnormalsize\setbox\sizebox=\hbox\bgroup\kern.05em }%
+\newcommand\lthtmlhboxmathB{\adjustnormalsize\setbox\sizebox=\hbox to\hsize\bgroup\hfill }%
+\newcommand\lthtmlvboxmathA{\adjustnormalsize\setbox\sizebox=\vbox\bgroup %
+ \let\ifinner=\iffalse \let\)\liih@math }%
+\newcommand\lthtmlboxmathZ{\@next\next\@currlist{}{\def\next{\voidb@x}}%
+ \expandafter\box\next\egroup}%
+\newcommand\lthtmlmathtype[1]{\gdef\lthtmlmathenv{#1}}%
+\newcommand\lthtmllogmath{\lthtmltypeout{l2hSize %
+:\lthtmlmathenv:\the\ht\sizebox::\the\dp\sizebox::\the\wd\sizebox.\preveqno}}%
+\newcommand\lthtmlfigureA[1]{\let\@savefreelist\@freelist
+       \lthtmlmathtype{#1}\lthtmlvboxmathA}%
+\newcommand\lthtmlpictureA{\bgroup\catcode`\_=8 \lthtmlpictureB}%
+\newcommand\lthtmlpictureB[1]{\lthtmlmathtype{#1}\egroup
+       \let\@savefreelist\@freelist \lthtmlhboxmathB}%
+\newcommand\lthtmlpictureZ[1]{\hfill\lthtmlfigureZ}%
+\newcommand\lthtmlfigureZ{\lthtmlboxmathZ\lthtmllogmath\copy\sizebox
+       \global\let\@freelist\@savefreelist}%
+\newcommand\lthtmldisplayA{\bgroup\catcode`\_=8 \lthtmldisplayAi}%
+\newcommand\lthtmldisplayAi[1]{\lthtmlmathtype{#1}\egroup\lthtmlvboxmathA}%
+\newcommand\lthtmldisplayB[1]{\edef\preveqno{(\theequation)}%
+  \lthtmldisplayA{#1}\let\@eqnnum\relax}%
+\newcommand\lthtmldisplayZ{\lthtmlboxmathZ\lthtmllogmath\lthtmlsetmath}%
+\newcommand\lthtmlinlinemathA{\bgroup\catcode`\_=8 \lthtmlinlinemathB}
+\newcommand\lthtmlinlinemathB[1]{\lthtmlmathtype{#1}\egroup\lthtmlhboxmathA
+  \vrule height1.5ex width0pt }%
+\newcommand\lthtmlinlineA{\bgroup\catcode`\_=8 \lthtmlinlineB}%
+\newcommand\lthtmlinlineB[1]{\lthtmlmathtype{#1}\egroup\lthtmlhboxmathA}%
+\newcommand\lthtmlinlineZ{\egroup\expandafter\ifdim\dp\sizebox>0pt %
+  \expandafter\centerinlinemath\fi\lthtmllogmath\lthtmlsetinline}
+\newcommand\lthtmlinlinemathZ{\egroup\expandafter\ifdim\dp\sizebox>0pt %
+  \expandafter\centerinlinemath\fi\lthtmllogmath\lthtmlsetmath}
+\newcommand\lthtmlindisplaymathZ{\egroup %
+  \centerinlinemath\lthtmllogmath\lthtmlsetmath}
+\def\lthtmlsetinline{\hbox{\vrule width.1em \vtop{\vbox{%
+  \kern.1em\copy\sizebox}\ifdim\dp\sizebox>0pt\kern.1em\else\kern.3pt\fi
+  \ifdim\hsize>\wd\sizebox \hrule depth1pt\fi}}}
+\def\lthtmlsetmath{\hbox{\vrule width.1em\kern-.05em\vtop{\vbox{%
+  \kern.1em\kern0.8 pt\hbox{\hglue.17em\copy\sizebox\hglue0.8 pt}}\kern.3pt%
+  \ifdim\dp\sizebox>0pt\kern.1em\fi \kern0.8 pt%
+  \ifdim\hsize>\wd\sizebox \hrule depth1pt\fi}}}
+\def\centerinlinemath{%
+  \dimen1=\ifdim\ht\sizebox<\dp\sizebox \dp\sizebox\else\ht\sizebox\fi
+  \advance\dimen1by.5pt \vrule width0pt height\dimen1 depth\dimen1 
+ \dp\sizebox=\dimen1\ht\sizebox=\dimen1\relax}
+
+\def\lthtmlcheckvsize{\ifdim\ht\sizebox<\vsize 
+  \ifdim\wd\sizebox<\hsize\expandafter\hfill\fi \expandafter\vfill
+  \else\expandafter\vss\fi}%
+\providecommand{\selectlanguage}[1]{}%
+\makeatletter \tracingstats = 1 
+
+
+\begin{document}
+\pagestyle{empty}\thispagestyle{empty}\lthtmltypeout{}%
+\lthtmltypeout{latex2htmlLength hsize=\the\hsize}\lthtmltypeout{}%
+\lthtmltypeout{latex2htmlLength vsize=\the\vsize}\lthtmltypeout{}%
+\lthtmltypeout{latex2htmlLength hoffset=\the\hoffset}\lthtmltypeout{}%
+\lthtmltypeout{latex2htmlLength voffset=\the\voffset}\lthtmltypeout{}%
+\lthtmltypeout{latex2htmlLength topmargin=\the\topmargin}\lthtmltypeout{}%
+\lthtmltypeout{latex2htmlLength topskip=\the\topskip}\lthtmltypeout{}%
+\lthtmltypeout{latex2htmlLength headheight=\the\headheight}\lthtmltypeout{}%
+\lthtmltypeout{latex2htmlLength headsep=\the\headsep}\lthtmltypeout{}%
+\lthtmltypeout{latex2htmlLength parskip=\the\parskip}\lthtmltypeout{}%
+\lthtmltypeout{latex2htmlLength oddsidemargin=\the\oddsidemargin}\lthtmltypeout{}%
+\makeatletter
+\if@twoside\lthtmltypeout{latex2htmlLength evensidemargin=\the\evensidemargin}%
+\else\lthtmltypeout{latex2htmlLength evensidemargin=\the\oddsidemargin}\fi%
+\lthtmltypeout{}%
+\makeatother
+\setcounter{page}{1}
+\onecolumn
+
+% !!! IMAGES START HERE !!!
+
+\setcounter{secnumdepth}{4}
+\stepcounter{section}
+\stepcounter{section}
+\stepcounter{subsection}
+\stepcounter{subsection}
+\stepcounter{section}
+\stepcounter{subsection}
+\stepcounter{subsection}
+\stepcounter{subsection}
+\stepcounter{subsection}
+\stepcounter{section}
+\stepcounter{subsection}
+\stepcounter{subsection}
+\stepcounter{section}
+{\newpage\clearpage
+\lthtmlpictureA{tex2html_wrap933}%
+\includegraphics{flowheader.eps}%
+\lthtmlpictureZ
+\lthtmlcheckvsize\clearpage}
+
+\stepcounter{section}
+\stepcounter{subsection}
+\stepcounter{subsection}
+\stepcounter{subsection}
+
+\end{document}

BIN
Docs/img1.png


+ 664 - 0
Docs/index.html

@@ -0,0 +1,664 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<!--Converted with LaTeX2HTML 2002-2-1 (1.70)
+original version by:  Nikos Drakos, CBLU, University of Leeds
+* revised and updated by:  Marcus Hennecke, Ross Moore, Herb Swan
+* with significant contributions from:
+  Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
+<HTML>
+<HEAD>
+<TITLE>Flowreplay Design Notes</TITLE>
+<META NAME="description" CONTENT="Flowreplay Design Notes">
+<META NAME="keywords" CONTENT="flowreplay">
+<META NAME="resource-type" CONTENT="document">
+<META NAME="distribution" CONTENT="global">
+
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+<META NAME="Generator" CONTENT="LaTeX2HTML v2002-2-1">
+<META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">
+
+<LINK REL="STYLESHEET" HREF="flowreplay.css">
+
+</HEAD>
+
+<BODY >
+
+<P>
+
+<P>
+
+<P>
+
+<P>
+<H1 ALIGN="CENTER"><SPAN ID="hue33">Flowreplay Design Notes</SPAN></H1>
+<DIV CLASS="author_info">
+
+<P ALIGN="CENTER"><STRONG><SPAN ID="hue35">Aaron Turner </SPAN></STRONG></P>
+<P ALIGN="CENTER"><I><SPAN ID="hue37">http://synfin.net/</SPAN></I></P>
+<P ALIGN="CENTER"><STRONG><SPAN ID="hue39">Last Edited:</SPAN>
+<BR><SPAN ID="hue41">October 23, 2003</SPAN></STRONG></P>
+</DIV>
+
+<P>
+
+<H1><A NAME="SECTION00010000000000000000">
+<SPAN CLASS="arabic">1</SPAN> <SPAN ID="hue43">Overview</SPAN></A>
+</H1>
+
+<P>
+<SPAN ID="hue45">Tcpreplay</SPAN><A NAME="tex2html1"
+  HREF="#foot362"><SUP><SPAN CLASS="arabic">1</SPAN></SUP></A> <SPAN ID="hue49">was designed to replay traffic previously captured
+in the pcap format back onto the wire for testing NIDS and other passive
+devices. Over time, it was enhanced to be able to test in-line network
+devices. However, a re-occurring feature request for tcpreplay is
+to connect to a server in order to test applications and host TCP/IP
+stacks. It was determined early on, that adding this feature to tcpreplay
+was far too complex, so I decided to create a new tool specifically
+designed for this.</SPAN>
+<P>
+<SPAN ID="hue51">Flowreplay is designed to replay traffic at Layer
+4 or 7 depending on the protocol rather then at Layer 2 like tcpreplay
+does. This allows flowreplay to connect to one or more servers using
+a pcap savefile as the basis of the connections. Hence, flowreplay
+allows the testing of applications running on real servers rather
+then passive devices. </SPAN>
+<P>
+
+<H1><A NAME="SECTION00020000000000000000">
+<SPAN CLASS="arabic">2</SPAN> <SPAN ID="hue53">Features</SPAN></A>
+</H1>
+
+<P>
+
+<H2><A NAME="SECTION00021000000000000000">
+<SPAN CLASS="arabic">2</SPAN>.<SPAN CLASS="arabic">1</SPAN> <SPAN ID="hue55">Requirements</SPAN></A>
+</H2>
+
+<P>
+
+<OL>
+<LI><SPAN ID="hue58">Full TCP/IP support, including IP fragments and
+TCP stream reassembly.</SPAN>
+</LI>
+<LI><SPAN ID="hue60">Support replaying TCP and UDP flows.</SPAN>
+</LI>
+<LI><SPAN ID="hue62">Code should handle each flow/service independently.</SPAN>
+</LI>
+<LI><SPAN ID="hue64">Should be able to connect to the server(s) in the
+pcap file or to a user specified IP address.</SPAN>
+</LI>
+<LI><SPAN ID="hue66">Support a plug-in architecture to allow adding application
+layer intelligence.</SPAN>
+</LI>
+<LI><SPAN ID="hue68">Plug-ins must be able to support multi-flow protocols
+like FTP.</SPAN>
+</LI>
+<LI><SPAN ID="hue365">Ship with a default plug-in which will work ``well
+enough'' for simple single-flow protocols like HTTP and telnet.</SPAN>
+</LI>
+<LI><SPAN ID="hue366">Flows being replayed ``correctly'' is more important
+then performance (Mbps).</SPAN>
+</LI>
+<LI><SPAN ID="hue74">Portable to run on common flavors of Unix and Unix-like
+systems.</SPAN>
+</LI>
+</OL>
+
+<P>
+
+<H2><A NAME="SECTION00022000000000000000">
+<SPAN CLASS="arabic">2</SPAN>.<SPAN CLASS="arabic">2</SPAN> <SPAN ID="hue77">Wishes</SPAN></A>
+</H2>
+
+<P>
+
+<OL>
+<LI><SPAN ID="hue80">Support clients connecting to flowreplay on a limited
+basis. Flowreplay would replay the server side of the connection.</SPAN>
+</LI>
+<LI><SPAN ID="hue82">Support other IP based traffic (ICMP, VRRP, OSPF,
+etc) via plug-ins.</SPAN>
+</LI>
+<LI><SPAN ID="hue84">Support non-IP traffic (ARP, STP, CDP, etc) via
+plug-ins.</SPAN>
+</LI>
+<LI><SPAN ID="hue86">Limit which flows are replayed using user defined
+filters. (bpf filter syntax?)</SPAN>
+</LI>
+<LI><SPAN ID="hue88">Process pcap files directly with no intermediary
+file conversions.</SPAN>
+</LI>
+<LI><SPAN ID="hue90">Should be able to scale to pcap files in the 100's
+of MB in size and 100+ simultaneous flows on a P3 500MHz w/ 256MB
+of RAM.</SPAN>
+</LI>
+</OL>
+
+<P>
+
+<H1><A NAME="SECTION00030000000000000000">
+<SPAN CLASS="arabic">3</SPAN> <SPAN ID="hue93">Design Thoughts</SPAN></A>
+</H1>
+
+<P>
+
+<H2><A NAME="SECTION00031000000000000000">
+<SPAN CLASS="arabic">3</SPAN>.<SPAN CLASS="arabic">1</SPAN> <SPAN ID="hue95">Sending and Receiving traffic</SPAN></A>
+</H2>
+
+<P>
+<SPAN ID="hue97">Flowreplay must be able to process multiple connections
+to one or more devices. There are two options:</SPAN>
+<P>
+
+<OL>
+<LI><SPAN ID="hue100">Use sockets</SPAN><A NAME="tex2html2"
+  HREF="#foot370"><SUP><SPAN CLASS="arabic">2</SPAN></SUP></A> <SPAN ID="hue104">to send and receive data</SPAN>
+</LI>
+<LI><SPAN ID="hue106">Use libpcap</SPAN><A NAME="tex2html3"
+  HREF="#foot371"><SUP><SPAN CLASS="arabic">3</SPAN></SUP></A> <SPAN ID="hue110">to receive packets and libnet</SPAN><A NAME="tex2html4"
+  HREF="#foot372"><SUP><SPAN CLASS="arabic">4</SPAN></SUP></A> <SPAN ID="hue114">to send packets</SPAN>
+</LI>
+</OL>
+<SPAN ID="hue117">Although using libpcap/libnet would allow more simultaneous
+connections and greater flexibility, there would be a very high complexity
+cost associated with it. With that in mind, I've decided to use sockets
+to send and receive data.</SPAN>
+<P>
+
+<H2><A NAME="SECTION00032000000000000000">
+<SPAN CLASS="arabic">3</SPAN>.<SPAN CLASS="arabic">2</SPAN> <SPAN ID="hue119">Handling Multiple Connections</SPAN></A>
+</H2>
+
+<P>
+<SPAN ID="hue121">Because a pcap file can contain multiple simultaneous
+flows, we need to be able to support that too. The biggest problem
+with this is reading packet data in a different order then stored
+in the pcap file. </SPAN>
+<P>
+<SPAN ID="hue123">Reading and writing to multiple sockets is easy
+with select() or poll(), however a pcap file has it's data stored
+serially, but we need to access it randomly. There are a number of
+possible solutions for this such as caching packets in RAM where they
+can be accessed more randomly, creating an index of the packets in
+the pcap file, or converting the pcap file to another format altogether.
+Alternatively, I've started looking at libpcapnav</SPAN><A NAME="tex2html5"
+  HREF="#foot124"><SUP><SPAN CLASS="arabic">5</SPAN></SUP></A> <SPAN ID="hue126">as an alternate means to navigate a pcap file and
+process packets out of order.</SPAN>
+<P>
+
+<H2><A NAME="SECTION00033000000000000000">
+<SPAN CLASS="arabic">3</SPAN>.<SPAN CLASS="arabic">3</SPAN> <SPAN ID="hue128">Data Synchronization</SPAN></A>
+</H2>
+
+<P>
+<SPAN ID="hue375">Knowing when to start sending client traffic in
+response to the server will be &#34;tricky&#34;. Without
+understanding the actual protocol involved, probably the best general
+solution is waiting for a given period of time after no more data
+from the server has been received. Not sure what to do if the client
+traffic doesn't elicit a response from the server (implement some
+kind of timeout?). This will be the basis for the default plug-in.</SPAN>
+<P>
+
+<H2><A NAME="SECTION00034000000000000000">
+<SPAN CLASS="arabic">3</SPAN>.<SPAN CLASS="arabic">4</SPAN> <SPAN ID="hue133">TCP/IP</SPAN></A>
+</H2>
+
+<P>
+<SPAN ID="hue135">Dealing with IP fragmentation and TCP stream reassembly
+will be another really complex problem. We're basically talking about
+implementing a significant portion of a TCP/IP stack. One thought
+is to use libnids</SPAN><A NAME="tex2html6"
+  HREF="#foot403"><SUP><SPAN CLASS="arabic">6</SPAN></SUP></A> <SPAN ID="hue139">which basically implements a Linux 2.0.37 TCP/IP
+stack in user-space. Other solutions include porting a TCP/IP stack
+from Open/Net/FreeBSD or writing our own custom stack from scratch.</SPAN>
+<P>
+
+<H1><A NAME="SECTION00040000000000000000">
+<SPAN CLASS="arabic">4</SPAN> <SPAN ID="hue141">Multiple Independent Flows</SPAN></A>
+</H1>
+
+<P>
+<SPAN ID="hue143">The biggest asynchronous problem, that pcap files
+are serial, has to be solved in a scaleable manner. Not much can be
+assumed about the network traffic contained in a pcap savefile other
+then Murphy's Law will be in effect. This means we'll have to deal
+with:</SPAN>
+<P>
+
+<UL>
+<LI><SPAN ID="hue146">Thousands of small simultaneous flows (captured
+on a busy network)</SPAN>
+</LI>
+<LI><SPAN ID="hue379">Flows which ``hang'' mid-stream (an exploit
+against a server causes it to crash)</SPAN>
+</LI>
+<LI><SPAN ID="hue150">Flows which contain large quantities of data (FTP
+transfers of ISO's for example)</SPAN>
+</LI>
+</UL>
+<SPAN ID="hue153">How we implement parallel processing of the pcap
+savefile will dramatically effect how well we can scale. A few considerations:</SPAN>
+<P>
+
+<UL>
+<LI>Most Unix systems limit the maximum number of open file descriptors
+a single process can have. Generally speaking this shouldn't be a
+problem except for highly parallel pcap's.
+</LI>
+<LI>While RAM isn't limitless, we can use mmap() to get around this.
+</LI>
+<LI>Many Unix systems have enhanced solutions to poll() which will improve
+flow management.
+</LI>
+</UL>
+
+<P>
+
+<H2><A NAME="SECTION00041000000000000000">
+<SPAN CLASS="arabic">4</SPAN>.<SPAN CLASS="arabic">1</SPAN> <SPAN ID="hue157">IP Fragments and TCP Streams</SPAN></A>
+</H2>
+
+<P>
+<SPAN ID="hue159">There are five major complications with flowreplay:</SPAN>
+<P>
+
+<OL>
+<LI><SPAN ID="hue162">The IP datagrams may be fragmented- we won't be
+able to use the standard 5-tuple (src/dst IP, src/dst port, protocol)
+to lookup which flow a packet belongs to.</SPAN>
+</LI>
+<LI><SPAN ID="hue164">IP fragments may arrive out of order which will
+complicate ordering of data to be sent.</SPAN>
+</LI>
+<LI><SPAN ID="hue166">The TCP segments may arrive out of order which will
+complicate ordering of data to be sent.</SPAN>
+</LI>
+<LI><SPAN ID="hue168">Packets may be missing in the pcap file because
+they were dropped during capture.</SPAN>
+</LI>
+<LI><SPAN ID="hue170">There are tools like fragrouter which intentionally
+create non-deterministic situations.</SPAN>
+</LI>
+</OL>
+<SPAN ID="hue173">First off, I've decided, that I'm not going to worry
+about fragrouter or it's cousins. I'll handle non-deterministic situations
+one and only one way, so that the way flowreplay handles the traffic
+will be deterministic. Perhaps, I'll make it easy for others to write
+a plug-in which will change it, but that's not something I'm going
+to concern myself with now.</SPAN>
+<P>
+<SPAN ID="hue175">Missing packets in the pcap file will probably make
+that flow unplayable. There are proabably certain situation where
+we can make an educated guess, but this is far too complex to worry
+about for the first stable release.</SPAN>
+<P>
+<SPAN ID="hue177">That still leaves creating a basic TCP/IP stack
+in user space. The good news it that there is already a library which
+does this called libnids. As of version 1.17, libnids can process
+packets from a pcap savefile (it's not documented in the man page,
+but the code is there).</SPAN>
+<P>
+<SPAN ID="hue179">A potential problem with libnids though is that
+it has to maintain it's own state/cache system. This not only means
+additional overhead, but jumping around in the pcap file as I'm planning
+on doing to handle multiple simultaneous flows is likely to really
+confuse libnids' state engine. Also, libnids is licensed under the
+GPL, but I want flowreplay released under a BSD-like license; I need
+to research if the two are compatible in this way.</SPAN>
+<P>
+<SPAN ID="hue181">Possible solutions:</SPAN>
+<P>
+
+<UL>
+<LI><SPAN ID="hue184">Developing a custom wedge between the capture file
+and libnids which will cause each packet to only be processed a single
+time.</SPAN>
+</LI>
+<LI><SPAN ID="hue186">Use libnids to process the pcap file into a new
+flow-based format, effectively putting the TCP/IP stack into a dedicated
+utility.</SPAN>
+</LI>
+<LI><SPAN ID="hue188">Develop a custom user-space TCP/IP stack, perhaps
+based on a BSD TCP/IP stack, much like libnids is based on Linux 2.0.37.</SPAN>
+</LI>
+<LI><SPAN ID="hue190">Screw it and say that IP fragmentation and out of
+order IP packets/TCP segments are not supported. Not sure if this
+will meet the needs of potential users.</SPAN>
+</LI>
+</UL>
+
+<P>
+
+<H2><A NAME="SECTION00042000000000000000">
+<SPAN CLASS="arabic">4</SPAN>.<SPAN CLASS="arabic">2</SPAN> <SPAN ID="hue193">Blocking</SPAN></A>
+</H2>
+
+<P>
+<SPAN ID="hue195">As earlier stated, one of the main goals of this
+project is to keep things single threaded to make coding plugins easier.
+One caveat of that is that any function which blocks will cause serious
+problems.</SPAN>
+<P>
+<SPAN ID="hue197">There are three major cases where blocking is likely
+to occur:</SPAN>
+<P>
+
+<OL>
+<LI><SPAN ID="hue200">Opening a socket</SPAN>
+</LI>
+<LI><SPAN ID="hue202">Reading from a socket</SPAN>
+</LI>
+<LI><SPAN ID="hue204">Writing to a socket</SPAN>
+</LI>
+</OL>
+<SPAN ID="hue207">Reading from sockets in a non-blocking manner is
+easy to solve for using poll() or select(). Writing to a socket, or
+merely opening a TCP socket via connect() however requires a different
+method:</SPAN>
+<P>
+<BLOCKQUOTE>
+<SPAN ID="hue210">It is possible to do non-blocking IO on sockets
+by setting the O_NONBLOCK flag on a socket file descriptor using
+fcntl(2). Then all operations that would block will (usually) return
+with EAGAIN (operation should be retried later); connect(2) will return
+EINPROGRESS error. The user can then wait for various events via poll(2)
+or select(2).</SPAN><A NAME="tex2html7"
+  HREF="#foot382"><SUP><SPAN CLASS="arabic">7</SPAN></SUP></A>
+</BLOCKQUOTE>
+<SPAN ID="hue215">If connect() returns EINPROGRESS, then we'll just
+have to do something like this:</SPAN>
+<P>
+
+<DL COMPACT>
+<DT>
+<DD><SPAN ID="hue218">int&nbsp;e,&nbsp;len=sizeof(e);</SPAN>
+<P>
+<SPAN ID="hue220">if&nbsp;(getsockopt(conn-&gt;s,&nbsp;SOL_SOCKET,&nbsp;SO_ERROR,&nbsp;&amp;e,&nbsp;&amp;len)&nbsp;&lt;&nbsp;0)&nbsp;{&nbsp;</SPAN>
+<P>
+&nbsp;<SPAN ID="hue383">&nbsp;&nbsp;&nbsp;/*&nbsp;not&nbsp;yet&nbsp;*/</SPAN>
+<P>
+&nbsp;<SPAN ID="hue384">&nbsp;&nbsp;&nbsp;if(errno&nbsp;!=&nbsp;EINPROGRESS){&nbsp;&nbsp;/*&nbsp;yuck.&nbsp;kill&nbsp;it.&nbsp;*/&nbsp;</SPAN>
+<P>
+&nbsp;<SPAN ID="hue385">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log_fn(LOG_DEBUG,&#34;in-progress&nbsp;connect&nbsp;failed.&nbsp;Removing.&#34;);&nbsp;</SPAN>
+<P>
+&nbsp;<SPAN ID="hue231">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;-1;&nbsp;</SPAN>
+<P>
+&nbsp;<SPAN ID="hue233">&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{&nbsp;</SPAN>
+<P>
+&nbsp;<SPAN ID="hue386">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;&nbsp;/*&nbsp;no&nbsp;change,&nbsp;see&nbsp;if&nbsp;next&nbsp;time&nbsp;is&nbsp;better&nbsp;*/&nbsp;</SPAN>
+<P>
+&nbsp;<SPAN ID="hue238">&nbsp;&nbsp;&nbsp;}&nbsp;</SPAN>
+<P>
+<SPAN ID="hue240">}&nbsp;</SPAN>
+<P>
+<SPAN ID="hue387">/*&nbsp;the&nbsp;connect&nbsp;has&nbsp;finished.&nbsp;*/&nbsp;</SPAN>
+</DD>
+</DL><BLOCKQUOTE>
+<SPAN ID="hue247">Note: It may not be totally right, but it works
+ok. (that chunk of code gets called after poll returns the socket
+as writable. if poll returns it as readable, then it's probably because
+of eof, connect fails. You must poll for both.</SPAN>
+</BLOCKQUOTE>
+
+<P>
+
+<H1><A NAME="SECTION00050000000000000000">
+<SPAN CLASS="arabic">5</SPAN> <SPAN ID="hue250">pcap vs flow File Format</SPAN></A>
+</H1>
+
+<P>
+<SPAN ID="hue252">As stated before, the pcap file format really isn't
+well suited for flowreplay because it uses the raw packet as a container
+for data. Flowreplay however isn't interested in packets, it's interested
+in data streams</SPAN><A NAME="tex2html8"
+  HREF="#foot404"><SUP><SPAN CLASS="arabic">8</SPAN></SUP></A> <SPAN ID="hue256">which may span one or more TCP/UDP segments, each
+comprised of an IP datagram which may be comprised of multiple IP
+fragments. Handling all this additional complexity requires a full
+TCP/IP stack in user space which would have additional feature requirements
+specific to flowreplay.</SPAN>
+<P>
+<SPAN ID="hue258">Rather then trying to do that, I've decided to create
+a pcap preprocessor for flowreplay called: flowprep. Flowprep will
+handle all the TCP/IP defragmentation/reassembly and write out a file
+containing the data streams for each flow.</SPAN>
+<P>
+<SPAN ID="hue260">A flow file will contain three sections:</SPAN>
+<P>
+
+<OL>
+<LI><SPAN ID="hue263">A header which identifies this as a flowprep file
+and the file version</SPAN>
+</LI>
+<LI><SPAN ID="hue265">An index of all the flows contained in the file</SPAN>
+</LI>
+<LI><SPAN ID="hue267">The data streams themselves</SPAN>
+</LI>
+</OL>
+<DIV ALIGN="CENTER">
+<SPAN ID="hue390"><IMG
+ WIDTH="668" HEIGHT="748" ALIGN="BOTTOM" BORDER="0"
+ SRC="img1.png"
+ ALT="\includegraphics{flowheader.eps}"></SPAN>
+</DIV>
+
+<P>
+<SPAN ID="hue274">At startup, the file header is validated and the
+data stream indexes are loaded into memory. Then the first data stream
+header from each flow is read. Then each flow and subsequent data
+stream is processed based upon the timestamps and plug-ins.</SPAN>
+<P>
+
+<H1><A NAME="SECTION00060000000000000000">
+<SPAN CLASS="arabic">6</SPAN> <SPAN ID="hue276">Plug-ins</SPAN></A>
+</H1>
+
+<P>
+<SPAN ID="hue392">Plug-ins will provide the ``intelligence'' in
+flowreplay. Flowreplay is designed to be a mere framework for connecting
+captured flows in a flow file with socket file handles. How data is
+processed and what should be done with it will be done via plug-ins.</SPAN>
+<P>
+<SPAN ID="hue280">Plug-ins will allow proper handling of a variety
+of protocols while hopefully keeping things simple. Another part of
+the consideration will be making it easy for others to contribute
+to flowreplay. I don't want to have to write all the protocol logic
+myself.</SPAN>
+<P>
+
+<H2><A NAME="SECTION00061000000000000000">
+<SPAN CLASS="arabic">6</SPAN>.<SPAN CLASS="arabic">1</SPAN> <SPAN ID="hue282">Plug-in Basics</SPAN></A>
+</H2>
+
+<P>
+<SPAN ID="hue284">Each plug-in provides the logic for handling one
+or more services. The main purpose of a plug-in is to decide when
+flowreplay should send data via one or more sockets. The plug-in can
+use any</SPAN> <SPAN ID="hue394"><SPAN  CLASS="textit">non-blocking</SPAN></SPAN> <SPAN ID="hue288">method
+of determining if it appropriate to send data or wait for data to
+received. If necessary, a plug-in can also modify the data sent.</SPAN>
+<P>
+<SPAN ID="hue290">Each time poll() returns, flowreplay calls the plug-ins
+for the flows which either have data waiting or in the case of a timeout,
+those flows which timed out. Afterwords, all the flows are processed
+and poll() is called on those flows which have their state set to
+POLL. And the process repeats until there are no more nodes in the
+tree.</SPAN>
+<P>
+
+<H2><A NAME="SECTION00062000000000000000">
+<SPAN CLASS="arabic">6</SPAN>.<SPAN CLASS="arabic">2</SPAN> <SPAN ID="hue292">The Default Plug-in</SPAN></A>
+</H2>
+
+<P>
+<SPAN ID="hue396">Initially, flowreplay will ship with one basic plug-in
+called ``default''. Any flow which doesn't have a specific plug-in
+defined, will use default. The goal of the default plug-in is to work
+``good enough'' for a majority of single-flow protocols such as
+SMTP, HTTP, and Telnet. Protocols which use encryption (SSL, SSH,
+etc) or multiple flows (FTP, RPC, etc) will never work with the default
+plug-in. Furthermore, the default plug-in will only support connections</SPAN><SPAN ID="hue397"><SPAN  CLASS="textit">to</SPAN></SPAN> <SPAN ID="hue299">a server, it will not
+support accepting connections from clients.</SPAN>
+<P>
+<SPAN ID="hue398">The default plug-in will provide no data level manipulation
+and only a simple method for detecting when it is time to send data
+to the server. Detecting when to send data will be done by a ``no
+more data'' timeout value. Basically, by using the pcap file as a
+means to determine the order of the exchange, anytime it is the servers
+turn to send data, flowreplay will wait for the first byte of data
+and then start the ``no more data'' timer. Every time more data
+is received, the timer is reset. If the timer reaches zero, then flowreplay
+sends the next portion of the client side of the connection. This
+is repeated until the the flow has been completely replayed or a ``server
+hung'' timeout is reached. The server hung timeout is used to detect
+a server which crashed and never starts sending any data which would
+start the ``no more data'' timer.</SPAN>
+<P>
+<SPAN ID="hue399">Both the ``no more data'' and ``server hung''
+timers will be user defined values and global to all flows using the
+default plug-in.</SPAN>
+<P>
+
+<H2><A NAME="SECTION00063000000000000000">
+<SPAN CLASS="arabic">6</SPAN>.<SPAN CLASS="arabic">3</SPAN> <SPAN ID="hue309">Plug-in Details</SPAN></A>
+</H2>
+
+<P>
+<SPAN ID="hue311">Each plug-in will be comprised of the following:</SPAN>
+<P>
+
+<OL>
+<LI><SPAN ID="hue314">An optional global data structure, for intra-flow
+communication</SPAN>
+</LI>
+<LI><SPAN ID="hue316">Per-flow data structure, for tracking flow state
+information</SPAN>
+</LI>
+<LI><SPAN ID="hue318">A list of functions which flow replay will call
+when certain well-defined conditions are met.</SPAN>
+<P>
+
+<UL>
+<LI><SPAN ID="hue321">Required functions:</SPAN>
+<P>
+
+<UL>
+<LI><SPAN ID="hue324">initialize_node() - called when a node in the tree
+created using this plug-in</SPAN>
+</LI>
+<LI><SPAN ID="hue326">post_poll_timeout() - called when the poll() returned
+due to a timeout for this node</SPAN>
+</LI>
+<LI><SPAN ID="hue328">post_poll_read() - called when the poll() returned
+due to the socket being ready</SPAN>
+</LI>
+<LI><SPAN ID="hue330">buffer_full() - called when a the packet buffer
+for this flow is full</SPAN>
+</LI>
+<LI><SPAN ID="hue332">delete_node() - called just prior to the node being
+free()'d</SPAN>
+</LI>
+</UL>
+</LI>
+<LI><SPAN ID="hue335">Optional functions:</SPAN>
+<P>
+
+<UL>
+<LI><SPAN ID="hue338">pre_send_data() - called before data is sent</SPAN>
+</LI>
+<LI><SPAN ID="hue340">post_send_data() - called after data is sent</SPAN>
+</LI>
+<LI><SPAN ID="hue342">pre_poll() - called prior to poll()</SPAN>
+</LI>
+<LI><SPAN ID="hue344">post_poll_default() - called when poll() returns
+and neither the socket was ready or the node timed out </SPAN>
+</LI>
+<LI><SPAN ID="hue346">open_socket() - called after the socket is opened</SPAN>
+</LI>
+<LI><SPAN ID="hue348">close_socket() - called after the socket is closed</SPAN>
+</LI>
+</UL>
+</LI>
+</UL>
+</LI>
+</OL>
+
+<DL COMPACT>
+<DT>
+<DD><P>
+</DD>
+</DL>
+<P>
+
+<H1><A NAME="SECTION00070000000000000000">
+About this document ...</A>
+</H1>
+ <STRONG><SPAN ID="hue33">Flowreplay Design Notes</SPAN></STRONG><P>
+This document was generated using the
+<A HREF="http://www.latex2html.org/"><STRONG>LaTeX</STRONG>2<tt>HTML</tt></A> translator Version 2002-2-1 (1.70)
+<P>
+Copyright &#169; 1993, 1994, 1995, 1996,
+<A HREF="http://cbl.leeds.ac.uk/nikos/personal.html">Nikos Drakos</A>, 
+Computer Based Learning Unit, University of Leeds.
+<BR>
+Copyright &#169; 1997, 1998, 1999,
+<A HREF="http://www.maths.mq.edu.au/~ross/">Ross Moore</A>, 
+Mathematics Department, Macquarie University, Sydney.
+<P>
+The command line arguments were: <BR>
+ <STRONG>latex2html</STRONG> <TT>-nonavigation -no_subdir -split 0 -show_section_numbers flowreplay.tex</TT>
+<P>
+The translation was initiated by Aaron Turner on 2005-02-10
+<BR><HR><H4>Footnotes</H4>
+<DL>
+<DT><A NAME="foot362">...Tcpreplay</A><A
+ HREF="flowreplay.html#tex2html1"><SUP><SPAN CLASS="arabic">1</SPAN></SUP></A></DT>
+<DD><SPAN ID="hue47">http://tcpreplay.sourceforge.net/</SPAN>
+
+</DD>
+<DT><A NAME="foot370">...&nbsp;</A><A
+ HREF="flowreplay.html#tex2html2"><SUP><SPAN CLASS="arabic">2</SPAN></SUP></A></DT>
+<DD><SPAN ID="hue102">socket(2)</SPAN>
+
+</DD>
+<DT><A NAME="foot371">...&nbsp;</A><A
+ HREF="flowreplay.html#tex2html3"><SUP><SPAN CLASS="arabic">3</SPAN></SUP></A></DT>
+<DD><SPAN ID="hue108">http://www.tcpdump.org/</SPAN>
+
+</DD>
+<DT><A NAME="foot372">...&nbsp;</A><A
+ HREF="flowreplay.html#tex2html4"><SUP><SPAN CLASS="arabic">4</SPAN></SUP></A></DT>
+<DD><SPAN ID="hue112">http://www.packetfactory.net/projects/libnet/</SPAN>
+
+</DD>
+<DT><A NAME="foot124">...&nbsp;</A><A
+ HREF="flowreplay.html#tex2html5"><SUP><SPAN CLASS="arabic">5</SPAN></SUP></A></DT>
+<DD>http://netdude.sourceforge.net/
+
+</DD>
+<DT><A NAME="foot403">...&nbsp;</A><A
+ HREF="flowreplay.html#tex2html6"><SUP><SPAN CLASS="arabic">6</SPAN></SUP></A></DT>
+<DD><SPAN ID="hue377">http://www.avet.com.pl/~nergal/libnids/</SPAN>
+
+</DD>
+<DT><A NAME="foot382">...&nbsp;</A><A
+ HREF="flowreplay.html#tex2html7"><SUP><SPAN CLASS="arabic">7</SPAN></SUP></A></DT>
+<DD><SPAN ID="hue212">socket(7)</SPAN>
+
+</DD>
+<DT><A NAME="foot404">...&nbsp;</A><A
+ HREF="flowreplay.html#tex2html8"><SUP><SPAN CLASS="arabic">8</SPAN></SUP></A></DT>
+<DD><SPAN ID="hue389">A ``data stream'' as I call it is a simplex
+communication from the client or server which is a complete query,
+response or message.</SPAN>
+
+</DD>
+</DL>
+<BR><HR>
+<ADDRESS>
+Aaron Turner
+2005-02-10
+</ADDRESS>
+</BODY>
+</HTML>

+ 13 - 0
Docs/labels.pl

@@ -0,0 +1,13 @@
+# LaTeX2HTML 2002-2-1 (1.70)
+# Associate labels original text with physical files.
+
+
+1;
+
+
+# LaTeX2HTML 2002-2-1 (1.70)
+# labels from external_latex_labels array.
+
+
+1;
+

+ 0 - 45
INSTALL

@@ -1,45 +0,0 @@
-
-Building tcpreplay
--------------------
-
-To build tcpreplay on a supported platform:
-
-	% ./configure ; make
-
-If you get it to work on a platform not listed above, please let us
-know!
-
-Installing tcpreplay
----------------------
-
-To install tcpreplay, as root:
-
-	# make install
-
-This will install the tcpreplay binary and man page (by default,
-/usr/local/sbin/tcpreplay and /usr/local/man/man8/tcpreplay.8).
-
-On BSD-based systems, kernel modifications are required to correctly
-forge outgoing Ethernet source MACs. See the libnet documentation for
-details on how to do this.
-
-Running tcpreplay
-------------------
-
-See the tcpreplay manpage for details.
-
-Known Problems
---------------
-
-Tcpreplay can only replay traffic as fast as your hardware allows. If
-you find you can't hit that 80 Mbps traffic rate you want, build a
-faster machine (disk I/O seems to account for a lot of the overhead).
-
-Troubleshooting
----------------
-
-Trouble? What trouble? :-)
-
-
----
-$Id: INSTALL,v 1.3 1999/05/13 15:02:10 dugsong Exp $

+ 125 - 35
Makefile.in

@@ -1,59 +1,149 @@
-# Makefile for tcpreplay.
-#
-# dugsong@anzen.com
+# $Id: Makefile.in 767 2004-10-06 12:48:49Z aturner $
 
-PREFIX		= @prefix@
-SBINDIR		= $(PREFIX)/sbin
-MANDIR		= $(PREFIX)/man/man8
+prefix		= @prefix@
+BINDIR		= ${prefix}/bin
+SBINDIR		= ${prefix}/sbin
+MAN8DIR		= @mandir@/man8
+MAN1DIR		= @mandir@/man1
+VERSION		= @TCPREPLAY_VERSION@
+RELEASEDIR	= tcpreplay-$(VERSION)
 
 CC		= @CC@
 CFLAGS		= @CFLAGS@
 LDFLAGS		= @LDFLAGS@
 DEFS		= @DEFS@
-INCS		= $(LNETINCS) $(PCAPINCS)
-LIBS		= @LIBS@ $(LNETLIBS) $(PCAPLIBS)
+INCS		= -I. @LNETINC@ @LPCAPINC@
+LIBS		= @LIBS@ @LNETLIB@ @LPCAPLIB@
+LNAVLIB		= @LNAVLIB@
+LNAV_CFLAGS	= @LNAV_CFLAGS@
 
 INSTALL		= @INSTALL@
-INSTALL_PROGRAM	= @INSTALL_PROGRAM@
 
-PCAPDIR		= libpcap-0.4
-PCAPINCS	= -I$(PCAPDIR)
-PCAPLIBS	= -L$(PCAPDIR) -lpcap
-PCAPDEP		= $(PCAPDIR)/pcap.h $(PCAPDIR)/libpcap.a
+BINARIES	= tcpreplay capinfo pcapmerge tcpprep flowreplay
 
-LNETDIR		= Libnet-0.99
-LNETINCS	= -I$(LNETDIR)/include
-LNETLIBS	= -L$(LNETDIR)/lib -lnet
-LNETDEP		= $(LNETDIR)/include/libnet.h $(LNETDIR)/libnet.a
 
-PROGRAMS	= tcpreplay
+TSRCS		= tcpreplay.c timer.c cache.c cidr.c do_packets.c list.c xX.c err.c signal_handler.c edit_packet.c replay_live.c fakepoll.c utils.c fakepcapnav.c tcpdump.c portmap.c fakepcap.c
+TOBJS		= $(TSRCS:.c=.o)
 
-all: $(PROGRAMS)
+CSRCS		= capinfo.c libpcap.c snoop.c timer.c err.c fakepcap.c
+COBJS		= $(CSRCS:.c=.o)
 
-tcpreplay: $(PCAPDEP) $(LNETDEP) tcpreplay.c
-	-rm -f tcpreplay
-	$(CC) $(CFLAGS) $(DEFS) $(INCS) -o $@ tcpreplay.c $(LDFLAGS) $(LIBS)
+PSRCS		= tcpprep.c cidr.c tree.c cache.c list.c xX.c err.c utils.c services.c fakepcap.c
+POBJS		= $(PSRCS:.c=.o)
 
-$(PCAPDIR)/libpcap.a:
-	cd $(PCAPDIR) ; $(MAKE)
+MSRCS		= pcapmerge.c err.c
+MOBJS		= $(MSRCS:.c=.o)
 
-$(LNETDIR)/libnet.a:
-	cd $(LNETDIR) ; $(MAKE)
+FSRCS		= flowreplay.c flowkey.c flownode.c flowstate.c flowbuff.c cidr.c timer.c err.c utils.c
+FOBJS		= $(FSRCS:.c=.o)
+
+.c.o:
+	$(CC) $(CFLAGS) $(DEFS) $(INCS) -c $*.c
+
+.PHONY: test
+
+all: $(BINARIES) 
+
+tags:
+	etags *.h *.c
+
+tcpprep: $(POBJS)
+	$(CC) $(CFLAGS) $(DEFS) $(INCS) -o $@ $(POBJS) $(LDFLAGS) $(LIBS)
+
+tcpreplay: $(TOBJS)
+	$(CC) $(CFLAGS) $(LNAV_CFLAGS) $(DEFS) $(INCS) -o $@ $(TOBJS) $(LDFLAGS) $(LIBS) $(LNAVLIB)
+
+capinfo: $(COBJS)
+	$(CC) $(CFLAGS) $(DEFS) $(INCS) -o $@ $(COBJS) $(LDFLAGS) $(LIBS)
+
+pcapmerge: $(MOBJS)
+	$(CC) $(CFLAGS) $(DEFS) -o $@ $(MOBJS) $(LDFLAGS) $(LIBS)
+
+flowreplay: $(FOBJS)
+	$(CC) $(CFLAGS) $(DEFS) -o $@ $(FOBJS) $(LDFLAGS) $(LIBS)
+
+dlt_names:
+	cat /usr/include/net/bpf.h | ./scripts/dlt2name.pl
 
 clean:
-	cd $(PCAPDIR) ; $(MAKE) clean
-	cd $(LNETDIR) ; $(MAKE) clean
-	rm -f *~ *.o *core $(PROGRAMS)
+	-rm -f *.o *core $(BINARIES)
+	-cd test && make clean
+	-cd Docs && make clean
 
 distclean: clean
-	cd $(PCAPDIR) ; $(MAKE) distclean
-	cd $(LNETDIR) ; $(MAKE) distclean
-	rm -f Makefile config.h config.status config.cache config.log
+	-rm -rf autom4te-2.??.cache autom4te.cache TAGS
+	-rm -f Makefile config.h config.status config.cache config.log *~
+	-rm -f tcpreplay.spec confdefs.h man/*~ scripts/*~
+	-cd test && make distclean
+	-cd Docs && make distclean
 
 install: 
-	$(INSTALL_PROGRAM) -m 755 tcpreplay $(SBINDIR)
-	$(INSTALL) -m 644 tcpreplay.8 $(MANDIR)
+	test -d $(SBINDIR) || $(INSTALL) -d $(SBINDIR)
+	test -d $(BINDIR) || $(INSTALL) -d $(BINDIR)
+	test -d $(MAN8DIR) || $(INSTALL) -d $(MAN8DIR)
+	test -d $(MAN1DIR) || $(INSTALL) -d $(MAN1DIR)
+	$(INSTALL) -m 755 tcpreplay $(SBINDIR)
+	$(INSTALL) -m 755 capinfo $(BINDIR)
+	$(INSTALL) -m 755 tcpprep $(BINDIR)
+	$(INSTALL) -m 755 pcapmerge $(BINDIR)
+	$(INSTALL) -m 755 flowreplay $(BINDIR)
+	$(INSTALL) -m 644 man/tcpreplay.8 $(MAN8DIR)
+	$(INSTALL) -m 644 man/capinfo.1 $(MAN1DIR)
+	$(INSTALL) -m 644 man/tcpprep.1 $(MAN1DIR)
+	$(INSTALL) -m 644 man/pcapmerge.1 $(MAN1DIR)
+	$(INSTALL) -m 644 man/flowreplay.1 $(MAN1DIR)
 
 uninstall:
 	rm -f $(SBINDIR)/tcpreplay
-	rm -f $(MANDIR)/tcpreplay.8
+	rm -f $(MAN8DIR)/tcpreplay.8
+	rm -f $(BINDIR)/capinfo
+	rm -f $(MAN1DIR)/capinfo.1
+	rm -f $(BINDIR)/tcpprep
+	rm -f $(MAN1DIR)/tcpprep.1
+	rm -f $(BINDIR)/pcapmerge
+	rm -f $(MAN1DIR)/pcapmerge.1
+	rm -f $(BINDIR)/flowreplay
+	rm -f $(MAN8DIR)/flowreplay.8
+
+pretty:
+	indent -br -brs -ts4 -ncdw -nce -ncs -npcs -nprs -l80 -lc80 -lp -psl -i4 -nut *.c *.h
+
+test:
+	cd test && make
+
+docs:
+	cd Docs && make
+
+webdocs:
+	scp Docs/FAQ.html Docs/FAQ.pdf Docs/CHANGELOG shell.sf.net:htdocs/
+
+release:
+	mkdir ../$(RELEASEDIR)
+	cp -r * ../$(RELEASEDIR)/
+	cd ../$(RELEASEDIR) && make distclean
+	-cd ../$(RELEASEDIR)/Docs && make
+	rm -rf ../$(RELEASEDIR)/CVS ../$(RELEASEDIR)/test/CVS 
+	rm -rf ../$(RELEASEDIR)/Docs/CVS ../$(RELEASEDIR)/man/CVS
+	cd .. && tar zcvf $(RELEASEDIR).tar.gz $(RELEASEDIR)/*
+
+
+rerelease:
+	-rm -rf ../$(RELEASEDIR)  ../$(RELEASEDIR).tar.gz
+	mkdir ../$(RELEASEDIR)
+	cp -r * ../$(RELEASEDIR)/
+	cd ../$(RELEASEDIR) && make distclean
+	-cd ../$(RELEASEDIR)/Docs && make
+	rm -rf ../$(RELEASEDIR)/CVS ../$(RELEASEDIR)/test/CVS
+	rm -rf ../$(RELEASEDIR)/Docs/CVS ../$(RELEASEDIR)/man/CVS
+	cd .. && tar zcvf $(RELEASEDIR).tar.gz $(RELEASEDIR)/*
+
+srpm:
+	-rm -rf ../$(RELEASEDIR)  ../$(RELEASEDIR).tar.gz
+	mkdir ../$(RELEASEDIR)
+	cp -r * ../$(RELEASEDIR)/
+	cd ../$(RELEASEDIR) && mv tcpreplay.spec tcpreplay.SPEC
+	cd ../$(RELEASEDIR) && make distclean
+	cd ../$(RELEASEDIR) && mv tcpreplay.SPEC tcpreplay.spec
+	-cd ../$(RELEASEDIR)/Docs && make
+	cd .. && tar zcvf $(RELEASEDIR).tar.gz $(RELEASEDIR)/*
+	rpm -ts ../$(RELEASEDIR).tar.gz  --nodeps

+ 1 - 54
README

@@ -1,54 +1 @@
-
-			    ===============
-
-			    tcpreplay-1.0.1
-
-			    ===============
-
-What is tcpreplay?
--------------------
-
-Tcpreplay is a tool to replay saved tcpdump files at arbitrary speeds.
-
-This program was written in the hopes that a more precise testing
-methodology might be applied to the area of network intrusion
-detection, which is still a black art at best. 
-
-Many NIDSs fare poorly when looking for attacks on heavily-loaded
-networks. Tcpreplay allows you to recreate real network traffic from a
-real network for use in testing.
-
-What systems does tcpreplay support?
--------------------------------------
-
-Tcpreplay is fairly portable, relying on libpcap and libnet for
-packet capture and raw IP packet construction.
-
-Tcpreplay has been successfully tested on
-
-	- OpenBSD 2.x
-	- FreeBSD 3.x
-	- BSD/OS 3.x
-	- Redhat Linux 5.x
-	- Solaris 2.x
-
-Who can use tcpreplay?
------------------------
-
-Tcpreplay is licensed under a BSD-style license, as in the included
-LICENSE file. Please read the license to make sure it's okay to use it
-in your circumstances.
-
-Contact info?
--------------
-
-The primary tcpreplay site is 
-
-	http://www.anzen.com/research/nidsbench/
-
-Please send bug reports, comments, or questions about this software to
-<nidsbench@anzen.com>.
-
-
----
-$Id: README,v 1.5 1999/05/19 20:05:01 dugsong Exp $
+All the documentation, licensing information, etc is now in the Docs directory

+ 0 - 1
VERSION

@@ -1 +0,0 @@
-1.0.1

+ 108 - 0
aclocal.m4

@@ -0,0 +1,108 @@
+AC_DEFUN([AC_PATH_GENERIC],
+[dnl
+dnl we're going to need uppercase, lowercase and user-friendly versions of the
+dnl string `LIBRARY'
+pushdef([UP], translit([$1], [a-z], [A-Z]))dnl
+pushdef([DOWN], translit([$1], [A-Z], [a-z]))dnl
+
+dnl
+dnl Get the cflags and libraries from the LIBRARY-config script
+dnl
+AC_ARG_WITH(DOWN-prefix,[  --with-]DOWN[-prefix=PFX       Prefix where $1 is installed (optional)],
+        DOWN[]_config_prefix="$withval", DOWN[]_config_prefix="")
+AC_ARG_WITH(DOWN-exec-prefix,[  --with-]DOWN[-exec-prefix=PFX Exec prefix where $1 is installed (optional)],
+        DOWN[]_config_exec_prefix="$withval", DOWN[]_config_exec_prefix="")
+
+  if test x$DOWN[]_config_exec_prefix != x ; then
+     DOWN[]_config_args="$DOWN[]_config_args --exec-prefix=$DOWN[]_config_exec_prefix"
+     if test x${UP[]_CONFIG+set} != xset ; then
+       UP[]_CONFIG=$DOWN[]_config_exec_prefix/bin/DOWN-config
+     fi
+  fi
+  if test x$DOWN[]_config_prefix != x ; then
+     DOWN[]_config_args="$DOWN[]_config_args --prefix=$DOWN[]_config_prefix"
+     if test x${UP[]_CONFIG+set} != xset ; then
+       UP[]_CONFIG=$DOWN[]_config_prefix/bin/DOWN-config
+     fi
+  fi
+
+  AC_PATH_PROG(UP[]_CONFIG, DOWN-config, no)
+  ifelse([$2], ,
+     AC_MSG_CHECKING(for $1),
+     AC_MSG_CHECKING(for $1 - version >= $2)
+  )
+  no_[]DOWN=""
+  if test "$UP[]_CONFIG" = "no" ; then
+     no_[]DOWN=yes
+  else
+     UP[]_CFLAGS="`$UP[]_CONFIG $DOWN[]_config_args --cflags`"
+     UP[]_LIBS="`$UP[]_CONFIG $DOWN[]_config_args --libs`"
+     ifelse([$2], , ,[
+        DOWN[]_config_major_version=`$UP[]_CONFIG $DOWN[]_config_args \
+         --version | sed 's/[[^0-9]]*\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+        DOWN[]_config_minor_version=`$UP[]_CONFIG $DOWN[]_config_args \
+         --version | sed 's/[[^0-9]]*\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+        DOWN[]_config_micro_version=`$UP[]_CONFIG $DOWN[]_config_args \
+         --version | sed 's/[[^0-9]]*\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+        DOWN[]_wanted_major_version="regexp($2, [\<\([0-9]*\)], [\1])"
+        DOWN[]_wanted_minor_version="regexp($2, [\<\([0-9]*\)\.\([0-9]*\)], [\2])"
+        DOWN[]_wanted_micro_version="regexp($2, [\<\([0-9]*\).\([0-9]*\).\([0-9]*\)], [\3])"
+
+        # Compare wanted version to what config script returned.
+        # If I knew what library was being run, i'd probably also compile
+        # a test program at this point (which also extracted and tested
+        # the version in some library-specific way)
+        if test "$DOWN[]_config_major_version" -lt \
+                        "$DOWN[]_wanted_major_version" \
+          -o \( "$DOWN[]_config_major_version" -eq \
+                        "$DOWN[]_wanted_major_version" \
+            -a "$DOWN[]_config_minor_version" -lt \
+                        "$DOWN[]_wanted_minor_version" \) \
+          -o \( "$DOWN[]_config_major_version" -eq \
+                        "$DOWN[]_wanted_major_version" \
+            -a "$DOWN[]_config_minor_version" -eq \
+                        "$DOWN[]_wanted_minor_version" \
+            -a "$DOWN[]_config_micro_version" -lt \
+                        "$DOWN[]_wanted_micro_version" \) ; then
+          # older version found
+          no_[]DOWN=yes
+          echo -n "*** An old version of $1 "
+          echo -n "($DOWN[]_config_major_version"
+          echo -n ".$DOWN[]_config_minor_version"
+          echo    ".$DOWN[]_config_micro_version) was found."
+          echo -n "*** You need a version of $1 newer than "
+          echo -n "$DOWN[]_wanted_major_version"
+          echo -n ".$DOWN[]_wanted_minor_version"
+          echo    ".$DOWN[]_wanted_micro_version."
+          echo "***"
+          echo "*** If you have already installed a sufficiently new version, this error"
+          echo "*** probably means that the wrong copy of the DOWN-config shell script is"
+          echo "*** being found. The easiest way to fix this is to remove the old version"
+          echo "*** of $1, but you can also set the UP[]_CONFIG environment to point to the"
+          echo "*** correct copy of DOWN-config. (In this case, you will have to"
+          echo "*** modify your LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf"
+          echo "*** so that the correct libraries are found at run-time)"
+        fi
+     ])
+  fi
+  if test "x$no_[]DOWN" = x ; then
+     AC_MSG_RESULT(yes)
+     ifelse([$3], , :, [$3])
+  else
+     AC_MSG_RESULT(no)
+     if test "$UP[]_CONFIG" = "no" ; then
+       echo "*** The DOWN-config script installed by $1 could not be found"
+       echo "*** If $1 was installed in PREFIX, make sure PREFIX/bin is in"
+       echo "*** your path, or set the UP[]_CONFIG environment variable to the"
+       echo "*** full path to DOWN-config."
+     fi
+     UP[]_CFLAGS=""
+     UP[]_LIBS=""
+     ifelse([$4], , :, [$4])
+  fi
+  AC_SUBST(UP[]_CFLAGS)
+  AC_SUBST(UP[]_LIBS)
+
+  popdef([UP])
+  popdef([DOWN])
+])

+ 375 - 0
cache.c

@@ -0,0 +1,375 @@
+/* $Id: cache.c 767 2004-10-06 12:48:49Z aturner $ */
+
+/*
+ * Copyright (c) 2001-2004 Aaron Turner.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of the copyright owners nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "config.h"
+#include "cache.h"
+#include "tcpreplay.h"
+#include "err.h"
+
+#ifdef DEBUG
+extern int debug;
+#endif
+
+extern struct options options;
+static CACHE *new_cache();
+
+/*
+ * Takes a single char and returns a ptr to a string representation of the
+ * 8 bits that make up that char.  Use BIT_STR() to print it out
+ */
+#ifdef DEBUG
+static char *
+byte2bits(char byte, char *bitstring) {
+    int i = 1, j = 7;
+
+    for (i = 1; i <= 255; i = i << 1) {
+        if (byte & i)
+            bitstring[j] = '\061';
+        j--;
+    }
+
+    return bitstring;
+}
+#endif
+
+/*
+ * simple function to read in a cache file created with tcpprep this let's us
+ * be really damn fast in picking an interface to send the packet out returns
+ * number of cache entries read
+ * 
+ * now also checks for the cache magic and version
+ */
+
+u_int64_t
+read_cache(char **cachedata, char *cachefile)
+{
+    int cachefd, cnt;
+    CACHE_HEADER header;
+    ssize_t read_size = 0;
+    u_int64_t cache_size = 0;
+
+    /* open the file or abort */
+    cachefd = open(cachefile, O_RDONLY);
+    if (cachefd == -1)
+        err(1, "open %s", cachefile);
+
+    /* read the cache header and determine compatibility */
+    if ((cnt = read(cachefd, &header, sizeof(CACHE_HEADER))) < 0)
+        err(1, "read %s,", cachefile);
+
+    if (cnt < sizeof(CACHE_HEADER))
+        errx(1, "Cache file %s too small", cachefile);
+
+
+    /* verify our magic: tcpprep\0 */
+    if (memcmp(header.magic, CACHEMAGIC, sizeof(CACHEMAGIC)) != 0)
+        errx(1, "Unable to process %s: not a tcpprep cache file", cachefile);
+
+    /* verify version */
+    if (atoi(header.version) != atoi(CACHEVERSION))
+        errx(1, "Unable to process %s: cache file version missmatch",
+             cachefile);
+
+    /* read the comment */
+    header.comment_len = ntohs(header.comment_len);
+    if ((options.tcpprep_comment = (char *)malloc(header.comment_len)) == NULL)
+        errx(1, "Unable to malloc() tcpprep comment buffer");
+
+    read_size = read(cachefd, options.tcpprep_comment, header.comment_len);
+    if (read_size != header.comment_len)
+        errx(1, "Unable to read %d bytes of data for the comment (%d) %s", 
+             header.comment_len, read_size, read_size == -1 ? strerror(read_size) : "");
+
+    dbg(1, "Cache file comment: %s", options.tcpprep_comment);
+
+    /* malloc our cache block */
+    header.num_packets = ntohll(header.num_packets);
+    header.packets_per_byte = ntohs(header.packets_per_byte);
+    cache_size = header.num_packets / header.packets_per_byte;
+
+    /* deal with any remainder, becuase above divsion is integer */
+    if (header.num_packets % header.packets_per_byte)
+      cache_size ++;
+
+    dbg(1, "Cache file contains %lld packets in %ld bytes",
+        header.num_packets, cache_size);
+    dbg(1, "Cache uses %d packets per byte", header.packets_per_byte);
+
+    if ((*cachedata = (char *)malloc(cache_size)) == NULL)
+        errx(1, "Unable to malloc() our cache data");
+
+    memset(*cachedata, '\0', cache_size);
+
+    /* read in the cache */
+    read_size = read(cachefd, *cachedata, cache_size);
+    if (read_size != cache_size)
+        errx(1,
+             "Cache data length (%ld bytes) doesn't match cache header (%ld bytes)",
+             read_size, cache_size);
+
+    dbg(1, "Loaded in %llu packets from cache.", header.num_packets);
+
+    close(cachefd);
+    return (header.num_packets);
+}
+
+
+/*
+ * writes out the cache file header, comment and then the
+ * contents of *cachedata to out_file and then returns the number 
+ * of cache entries written
+ */
+u_int64_t
+write_cache(CACHE * cachedata, const int out_file, u_int64_t numpackets)
+{
+    CACHE *mycache = NULL;
+    CACHE_HEADER *cache_header = NULL;
+    u_int32_t chars, last = 0;
+    u_int64_t packets = 0;
+    ssize_t written = 0;
+
+    /* write a header to our file */
+    cache_header = (CACHE_HEADER *) malloc(sizeof(CACHE_HEADER));
+    memset(cache_header, 0, sizeof(CACHE_HEADER));
+    strncpy(cache_header->magic, CACHEMAGIC, strlen(CACHEMAGIC));
+    strncpy(cache_header->version, CACHEVERSION, strlen(CACHEMAGIC));
+    cache_header->packets_per_byte = htons(CACHE_PACKETS_PER_BYTE);
+    cache_header->num_packets = htonll(numpackets);
+
+    /* we can't strlen(NULL) so ... */
+    if (options.tcpprep_comment != NULL) {
+        cache_header->comment_len = htons((u_int16_t)strlen(options.tcpprep_comment));
+    } else {
+        cache_header->comment_len = 0;
+    }
+
+    written = write(out_file, cache_header, sizeof(CACHE_HEADER));
+    dbg(1, "Wrote %d bytes of cache file header", written);
+
+    if (written != sizeof(CACHE_HEADER))
+        errx(1, "Only wrote %d of %d bytes of the cache file header!\n%s",
+             written, sizeof(CACHE_HEADER),
+             written == -1 ? strerror(errno) : "");
+
+    /* don't write comment if there is none */
+    if (options.tcpprep_comment != NULL) {
+        written = write(out_file, options.tcpprep_comment, strlen(options.tcpprep_comment));
+        dbg(1, "Wrote %d bytes of comment", written);
+        
+        if (written != strlen(options.tcpprep_comment))
+            errx(1, "Only wrote %d of %d bytes of the comment!\n%s",
+                 written, strlen(options.tcpprep_comment), 
+                 written == -1 ? strerror(errno) : "");
+    }
+
+    mycache = cachedata;
+
+    while (!last) {
+        /* increment total packets */
+        packets += mycache->packets;
+
+        /* calculate how many chars to write */
+        chars = mycache->packets / CACHE_PACKETS_PER_BYTE;
+        if (mycache->packets % CACHE_PACKETS_PER_BYTE) {
+            chars++;
+            dbg(1, "Bumping up to the next byte: %d %% %d", mycache->packets,
+                CACHE_PACKETS_PER_BYTE);
+        }
+
+        /* write to file, and verify it wrote properly */
+        written = write(out_file, mycache->data, chars);
+        dbg(1, "Wrote %i bytes of cache data", written);
+        if (written != chars)
+            errx(1, "Only wrote %i of %i bytes to cache file!", written, chars);
+
+        /*
+         * if that was the last, stop processing, otherwise wash,
+         * rinse, repeat
+         */
+        if (mycache->next != NULL) {
+            mycache = mycache->next;
+        }
+        else {
+            last = 1;
+        }
+    }
+    /* return number of packets written */
+    return (packets);
+}
+
+/*
+ * mallocs a new CACHE struct all pre-set to sane defaults
+ */
+
+CACHE *
+new_cache()
+{
+    CACHE *newcache;
+
+    /* malloc mem */
+    newcache = (CACHE *) malloc(sizeof(CACHE));
+    if (newcache == NULL)
+        err(1, "malloc");
+
+    /* set mem to \0 and set bits stored to 0 */
+    memset(newcache, '\0', sizeof(CACHE));
+    newcache->packets = 0;
+    return (newcache);
+}
+
+/*
+ * adds the cache data for a packet to the given cachedata
+ * CIDR * cidrdata
+ */
+
+void
+add_cache(CACHE ** cachedata, const int send, const int interface)
+{
+    CACHE *lastcache = NULL;
+    u_char *byte = NULL;
+    int bit;
+    unsigned long index;
+#ifdef DEBUG
+    char bitstring[9] = EIGHT_ZEROS;
+#endif
+
+    /* first run?  malloc our first entry, set bit count to 0 */
+    if (*cachedata == NULL) {
+        *cachedata = new_cache();
+        lastcache = *cachedata;
+    }
+    else {
+        lastcache = *cachedata;
+        /* existing cache, go to last entry */
+        while (lastcache->next != NULL) {
+            lastcache = lastcache->next;
+        }
+
+        /* check to see if this is the last bit in this struct */
+        if ((lastcache->packets + 1) > (CACHEDATASIZE * CACHE_PACKETS_PER_BYTE)) {
+            /*
+             * if so, we have to malloc a new one and set bit to
+             * 0
+             */
+            dbg(1, "Adding to cachedata linked list");
+            lastcache->next = new_cache();
+            lastcache = lastcache->next;
+        }
+    }
+
+    /* always increment our bit count */
+    lastcache->packets++;
+    dbg(1, "Cache array packet %d", lastcache->packets);
+
+    /* send packet ? */
+    if (send) {
+        index = (lastcache->packets - 1) / CACHE_PACKETS_PER_BYTE;
+        bit = (((lastcache->packets - 1) % CACHE_PACKETS_PER_BYTE) * 
+               CACHE_BITS_PER_PACKET) + 1;
+        dbg(3, "Bit: %d", bit);
+
+        byte = (u_char *) & lastcache->data[index];
+        *byte += (u_char) (1 << bit);
+
+        dbg(2, "set send bit: byte %d = 0x%x", index, *byte);
+
+        /* if true, set low order bit. else, do squat */
+        if (interface) {
+            *byte += (u_char)(1 << (bit - 1));
+
+            dbg(2, "set interface bit: byte %d = 0x%x", index, *byte);
+
+        }
+        else {
+            dbg(2, "don't set interface bit: byte %d = 0x%x", index, *byte);
+        }
+        dbg(3, "Current cache byte: %c%c%c%c%c%c%c%c",
+
+            /* 
+             * only build the byte string when not in debug mode since
+             * the calculation is a bit expensive
+             */
+#ifdef DEBUG
+            BIT_STR(byte2bits(*byte, bitstring))
+#else
+            EIGHT_ZEROS
+#endif
+            );
+    }
+    else {
+        dbg(1, "not setting send bit");
+    }
+  
+}
+
+
+/*
+ * returns the action for a given packet based on the CACHE
+ */
+int
+check_cache(char *cachedata, unsigned long packetid)
+{
+    u_int32_t bit;
+    unsigned long index = 0;
+
+
+    index = (packetid - 1) / CACHE_PACKETS_PER_BYTE;
+    bit =
+        (((packetid - 1) % CACHE_PACKETS_PER_BYTE) * CACHE_BITS_PER_PACKET) + 1;
+
+    dbg(3, "Index: %ld\tBit: %d\tByte: %hhu\tMask: %hhu", index, bit,
+        cachedata[index], (cachedata[index] & (char)(1 << bit)));
+
+    if (!(cachedata[index] & (char)(1 << bit))) {
+        return CACHE_NOSEND;
+    }
+
+    /* go back a bit to get the interface */
+    bit--;
+    if (cachedata[index] & (char)(1 << bit)) {
+        return CACHE_PRIMARY;
+    }
+    else {
+        return CACHE_SECONDARY;
+    }
+
+    return CACHE_ERROR;
+}

+ 103 - 0
cache.h

@@ -0,0 +1,103 @@
+/* $Id: cache.h 767 2004-10-06 12:48:49Z aturner $ */
+
+/*
+ * Copyright (c) 2001-2004 Aaron Turner.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of the copyright owners nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __CACHE_H__
+#define __CACHE_H__
+
+#define CACHEMAGIC "tcpprep"
+#define CACHEVERSION "04"
+#define CACHEDATASIZE 255
+#define CACHE_PACKETS_PER_BYTE 4    /* number of packets / byte */
+#define CACHE_BITS_PER_PACKET 2     /* number of bits / packet */
+
+/* 
+ * CACHEVERSION History:
+ * 01 - Inital release.  1 bit of data/packet (primary or secondary nic)
+ * 02 - 2 bits of data/packet (drop/send & primary or secondary nic)
+ * 03 - Write integers in network-byte order
+ * 04 - Increase num_packets from 32 to 64 bit integer
+ */
+
+struct cache_type {
+    char data[CACHEDATASIZE];
+    unsigned int packets;       /* number of packets tracked in data */
+    struct cache_type *next;
+};
+
+
+/*
+ * Each byte in cache_type.data represents CACHE_PACKETS_PER_BYTE (4) number of packets
+ * Each packet has CACHE_BITS_PER_PACKETS (2) bits of data.
+ * High Bit: 1 = send, 0 = don't send
+ * Low Bit: 1 = primary interface, 0 = secondary interface
+*/
+
+/*
+ * cache_file_header Data structure defining a file as a tcpprep cache file
+ * and it's version
+ * 
+ * If you need to enhance this struct, do so AFTER the version field and be sure
+ * to increment  CACHEVERSION
+ */
+struct cache_file_header {
+    char magic[8];
+    char version[4];
+    /* begin version 2 features */
+    /* version 3 puts everything in network-byte order */
+    /* version 4 makes num_packets a 64 bit int */
+    u_int64_t num_packets;      /* total # of packets in file */
+    u_int16_t packets_per_byte;
+    u_int16_t comment_len;      /* how long is the user comment? */
+};
+
+typedef struct cache_type CACHE;
+typedef struct cache_file_header CACHE_HEADER;
+
+u_int64_t write_cache(CACHE *, const int, u_int64_t);
+void add_cache(CACHE **, const int, const int);
+u_int64_t read_cache(char **, char *);
+int check_cache(char *, unsigned long);
+
+/* return values for check_cache */
+#define CACHE_ERROR -1
+#define CACHE_NOSEND 0
+#define CACHE_PRIMARY 1
+#define CACHE_SECONDARY 2
+
+/* macro to change a bitstring to 8 bits */
+#define BIT_STR(x) x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7]
+
+/* string of 8 zeros */
+#define EIGHT_ZEROS "\060\060\060\060\060\060\060\060"
+
+#endif
+

+ 152 - 0
capinfo.c

@@ -0,0 +1,152 @@
+/* $Id: capinfo.c 767 2004-10-06 12:48:49Z aturner $ */
+
+/*
+ * Copyright (c) 2001-2004 Aaron Turner, Matt Bing.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of the copyright owners nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "config.h"
+#include "err.h"
+#include "capinfo.h"
+#include "libpcap.h"
+#include "snoop.h"
+
+void print_pcap(struct pcap_info *);
+void print_snoop(struct snoop_info *);
+void usage();
+
+#ifdef DEBUG
+int debug = 0;
+#endif
+
+int
+main(int argc, char *argv[])
+{
+    struct pcap_info p;
+    struct snoop_info s;
+    int i, fd, flag;
+
+    if (argc == 0)
+        usage();
+
+    for (i = 1; i < argc; i++) {
+        flag = 0;
+
+        if ((fd = open(argv[i], O_RDONLY, 0)) < 0) {
+            warn("could not open");
+            continue;
+        }
+
+        if (is_pcap(fd)) {
+            stat_pcap(fd, &p);
+            flag = 1;
+            printf("%s pcap file\n", argv[1]);
+            print_pcap(&p);
+            return 0;
+        }
+
+        /* rewind */
+        if (lseek(fd, 0, SEEK_SET) != 0)
+            err(1, "lseek");
+
+        if (is_snoop(fd)) {
+            stat_snoop(fd, &s);
+            printf("%s snoop file\n", argv[1]);
+            print_snoop(&s);
+            return 0;
+        }
+
+        warnx("unknown format");
+        (void)printf("\n");
+    }
+
+    return 0;
+}
+
+void
+print_pcap(struct pcap_info *p)
+{
+    char *start, *finish;
+
+    printf("\tpcap (%s%s)\n", (p->modified ? "modified, " : ""), p->swapped);
+
+    (void)printf("\tversion: %d.%d\n", p->phdr.version_major,
+                 p->phdr.version_minor);
+    (void)printf("\tzone: %d\n", p->phdr.thiszone);
+    (void)printf("\tsig figs: %d\n", p->phdr.sigfigs);
+    (void)printf("\tsnaplen: %d\n", p->phdr.snaplen);
+
+    (void)printf("\tlinktype: %s\n", p->linktype);
+    (void)printf("\t%d packets, %d bytes\n", p->cnt, p->bytes);
+    if (p->trunc > 0)
+        (void)printf("\t%d packets truncated (larger than snaplen)\n",
+                     p->trunc);
+
+    if (p->cnt > 0) {
+        start = ctime(&p->start_tm.tv_sec);
+        (void)printf("\tfirst packet: %s", start);
+        finish = ctime(&p->finish_tm.tv_sec);
+        (void)printf("\tlast  packet: %s", finish);
+    }
+
+}
+
+void
+print_snoop(struct snoop_info *s)
+{
+    char *start, *finish;
+
+    (void)printf("\tversion: %d\n", s->version);
+    (void)printf("\tlinktype: %s\n", s->linktype);
+    (void)printf("\t%d packets, %d bytes\n", s->cnt, s->bytes);
+    if (s->trunc > 0)
+        (void)printf("\t%d packets truncated (larger than snaplen)\n",
+                     s->trunc);
+
+    if (s->cnt > 0) {
+        start = ctime(&s->start_tm.tv_sec);
+        (void)printf("\tfirst packet: %s", start);
+        finish = ctime(&s->finish_tm.tv_sec);
+        (void)printf("\tlast  packet: %s", finish);
+    }
+
+}
+
+void
+usage()
+{
+    (void)fprintf(stderr, "capinfo <files>\n");
+    exit(1);
+}

+ 46 - 0
capinfo.h

@@ -0,0 +1,46 @@
+/* $Id: capinfo.h 767 2004-10-06 12:48:49Z aturner $ */
+
+/*
+ * Copyright (c) 2001-2004 Aaron Turner, Matt Bing.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of the copyright owners nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _CAPINFO_H_
+#define _CAPINFO_H_
+
+#include "tcpreplay.h"
+
+/* internal representation of a packet, used in libpcap.c & snoop.c */
+struct packet {
+    char data[MAXPACKET];       /* pointer to packet contents */
+    int len;                    /* length of data (snaplen) */
+    int actual_len;             /* actual length of the packet */
+    struct timeval ts;          /* timestamp */
+};
+
+#endif

+ 504 - 0
cidr.c

@@ -0,0 +1,504 @@
+/* $Id: cidr.c 767 2004-10-06 12:48:49Z aturner $ */
+
+/*
+ * Copyright (c) 2001-2004 Aaron Turner.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of the copyright owners nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <libnet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+/* required for inet_aton() */
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "config.h"
+#include "tcpreplay.h"
+#include "cidr.h"
+#include "err.h"
+
+#ifdef DEBUG
+extern int debug;
+#endif
+
+static CIDR *cidr2CIDR(char *);
+
+/*
+ * prints to the given fd all the entries in mycidr
+ */
+void
+print_cidr(CIDR * mycidr)
+{
+    CIDR *cidr_ptr;
+
+    fprintf(stderr, "Cidr List: ");
+
+    cidr_ptr = mycidr;
+    while (cidr_ptr != NULL) {
+        /* print it */
+        fprintf(stderr, "%s/%d, ",
+                libnet_addr2name4(cidr_ptr->network, RESOLVE),
+                cidr_ptr->masklen);
+
+        /* go to the next */
+        if (cidr_ptr->next != NULL) {
+            cidr_ptr = cidr_ptr->next;
+        }
+        else {
+            break;
+        }
+    }
+    fprintf(stderr, "\n");
+}
+
+/*
+ * deletes all entries in a cidr and destroys the datastructure
+ */
+void
+destroy_cidr(CIDR * cidr)
+{
+
+    if (cidr != NULL)
+        if (cidr->next != NULL)
+            destroy_cidr(cidr->next);
+
+    free(cidr);
+    return;
+
+}
+
+/*
+ * adds a new CIDR entry to cidrdata
+ */
+void
+add_cidr(CIDR * cidrdata, CIDR ** newcidr)
+{
+    CIDR *cidr_ptr;
+
+    if (cidrdata == NULL) {
+        cidrdata = *newcidr;
+    }
+    else {
+        cidr_ptr = cidrdata;
+
+        while (cidr_ptr->next != NULL) {
+            cidr_ptr = cidr_ptr->next;
+        }
+
+        cidr_ptr->next = *newcidr;
+    }
+}
+
+/*
+ * takes in an IP and masklen, and returns a string in
+ * cidr format: x.x.x.x/y.  This malloc's memory.
+ */
+u_char *
+ip2cidr(const unsigned long ip, const int masklen)
+{
+    u_char *network;
+    char mask[3];
+
+    if ((network = (u_char *) malloc(20)) == NULL)
+        err(1, "malloc");
+
+    strncpy((char *)network, (char *)libnet_addr2name4(ip, LIBNET_DONT_RESOLVE),
+            19);
+
+    strcat((char *)network, "/");
+    if (masklen < 10) {
+        snprintf(mask, 1, "%d", masklen);
+        strncat((char *)network, mask, 1);
+    }
+    else {
+        snprintf(mask, 2, "%d", masklen);
+        strncat((char *)network, mask, 2);
+    }
+
+    return (network);
+}
+
+/*
+ * Mallocs and sets to sane defaults a CIDR structure
+ */
+
+CIDR *
+new_cidr(void)
+{
+    CIDR *newcidr;
+
+    newcidr = (CIDR *) malloc(sizeof(CIDR));
+    if (newcidr == NULL)
+        err(1, "unable to malloc memory for new_cidr()");
+
+    memset(newcidr, '\0', sizeof(CIDR));
+    newcidr->masklen = 99;
+    newcidr->next = NULL;
+
+    return (newcidr);
+}
+
+CIDRMAP *
+new_cidr_map(void)
+{
+    CIDRMAP *new;
+
+    new = (CIDRMAP *)malloc(sizeof(CIDRMAP));
+    if (new == NULL)
+        err(1, "unable to malloc memory for new_cidr()");
+
+    memset(new, '\0', sizeof(CIDRMAP));
+    new->next = NULL;
+
+    return (new);
+}
+
+
+/*
+ * Converts a single cidr (string) in the form of x.x.x.x/y into a
+ * CIDR structure.  Will malloc the CIDR structure.
+ */
+
+static CIDR *
+cidr2CIDR(char *cidr)
+{
+    int count = 0;
+    unsigned int octets[4];     /* used in sscanf */
+    CIDR *newcidr;
+    char networkip[16], tempoctet[4], ebuf[EBUF_SIZE];
+
+    if ((cidr == NULL) || (strlen(cidr) > EBUF_SIZE))
+        errx(1, "Error parsing: %s", cidr);
+
+    newcidr = new_cidr();
+
+    /*
+     * scan it, and make sure it scanned correctly, also copy over the
+     * masklen
+     */
+    count = sscanf(cidr, "%u.%u.%u.%u/%d", &octets[0], &octets[1],
+                   &octets[2], &octets[3], &newcidr->masklen);
+    if (count == 4) {
+        newcidr->masklen = 32;
+    } else if (count != 5) {
+        goto error;
+    }
+
+    /* masklen better be 0 =< masklen <= 32 */
+    if (newcidr->masklen > 32)
+        goto error;
+
+    /* copy in the ip address */
+    memset(networkip, '\0', 16);
+    for (count = 0; count < 4; count++) {
+        if (octets[count] > 255)
+            goto error;
+
+        snprintf(tempoctet, sizeof(octets[count]), "%d", octets[count]);
+        strcat(networkip, tempoctet);
+        /* we don't want a '.' at the end of the last octet */
+        if (count < 3)
+            strcat(networkip, ".");
+    }
+
+    /* copy over the network address and return */
+#ifdef INET_ATON
+    inet_aton(networkip, (struct in_addr *)&newcidr->network);
+#elif INET_ADDR
+    newcidr->network = inet_addr(networkip);
+#endif
+
+    return (newcidr);
+
+    /* we only get here on error parsing input */
+  error:
+    memset(ebuf, '\0', EBUF_SIZE);
+    strncpy(ebuf, "Unable to parse as a vaild CIDR: ", 34);
+    strncat(ebuf, cidr, (EBUF_SIZE - strlen(ebuf) - 1));
+    errx(1, "%s", ebuf);
+    return NULL;
+}
+
+/*
+ * parses a list of CIDR's input from the user which should be in the form
+ * of x.x.x.x/y,x.x.x.x/y...
+ * returns 1 for success, or fails to return on failure (exit 1)
+ * since we use strtok to process cidr, it gets zeroed out.
+ */
+
+int
+parse_cidr(CIDR ** cidrdata, char *cidrin, char *delim)
+{
+    CIDR *cidr_ptr;             /* ptr to current cidr record */
+    char *network = NULL;
+    char *token = NULL;
+
+    /* first itteration of input using strtok */
+    network = strtok_r(cidrin, delim, &token);
+
+    *cidrdata = cidr2CIDR(network);
+    cidr_ptr = *cidrdata;
+
+    /* do the same with the rest of the input */
+    while (1) {
+        network = strtok_r(NULL, delim, &token);
+        /* if that was the last CIDR, then kickout */
+        if (network == NULL)
+            break;
+
+        /* next record */
+        cidr_ptr->next = cidr2CIDR(network);
+        cidr_ptr = cidr_ptr->next;
+    }
+    return 1;
+
+}
+
+/*
+ * parses a pair of IP addresses: <IP1>:<IP2> and processes it like:
+ * -N 0.0.0.0/0:<IP1> -N 0.0.0.0/0:<IP2>
+ * returns 1 for success or returns 0 on failure
+ * since we use strtok to process optarg, it gets zeroed out
+ */
+int
+parse_endpoints(CIDRMAP ** cidrmap1, CIDRMAP ** cidrmap2, char *optarg)
+{
+#define NEWMAP 32
+    char *map = NULL, newmap[NEWMAP];
+    char *token = NULL;
+
+    memset(newmap, '\0', NEWMAP);
+    map = strtok_r(optarg, ":", &token);
+
+    strcpy(newmap, "0.0.0.0/0:");
+    strncat(newmap, map, NEWMAP - 1);
+    if (! parse_cidr_map(cidrmap1, newmap))
+        return 0;
+    
+    /* do again with the second IP */
+    memset(newmap, '\0', NEWMAP);
+    map = strtok_r(NULL, ":", &token);
+    
+    strcpy(newmap, "0.0.0.0/0:");
+    strncat(newmap, map, NEWMAP - 1);
+    if (! parse_cidr_map(cidrmap2, newmap))
+        return 0;
+    
+    return 1; /* success */
+}
+
+
+/*
+ * parses a list of CIDRMAP's input from the user which should be in the form
+ * of x.x.x.x/y:x.x.x.x/y,...
+ * returns 1 for success, or returns 0 on failure
+ * since we use strtok to process optarg, it gets zeroed out.
+ */
+int
+parse_cidr_map(CIDRMAP **cidrmap, char *optarg)
+{
+    CIDR *cidr = NULL;
+    char *map = NULL;
+    char *token = NULL;
+    CIDRMAP *ptr;
+
+    /* first iteration */
+    map = strtok_r(optarg, ",", &token);
+    if (! parse_cidr(&cidr, map, ":"))
+        return 0;
+
+    /* must return a linked list of two */
+    if (cidr->next == NULL)
+        return 0;
+
+    /* copy over */
+    *cidrmap = new_cidr_map();
+    ptr = *cidrmap;
+
+    ptr->from = cidr;
+    ptr->to = cidr->next;
+    ptr->from->next = NULL;
+
+    /* do the same with the reset of the input */
+    while(1) {
+        map = strtok_r(NULL, ",", &token);
+        if (map == NULL)
+            break;
+
+        if (! parse_cidr(&cidr, map, ":"))
+            return 0;
+
+        /* must return a linked list of two */
+        if (cidr->next == NULL)
+            return 0;
+
+        /* copy over */
+        ptr->next = new_cidr_map();
+        ptr = ptr->next;
+        ptr->from = cidr;
+        ptr->to = cidr->next;
+        ptr->from->next = NULL;
+
+    }
+    return 1; /* success */
+}
+
+/*
+ * checks to see if the ip address is in the cidr
+ * returns 1 for true, 0 for false
+ */
+
+int
+ip_in_cidr(const CIDR * mycidr, const unsigned long ip)
+{
+    unsigned long ipaddr = 0, network = 0, mask = 0;
+
+    /* always return 1 if 0.0.0.0/0 */
+    if (mycidr->masklen == 0 && mycidr->network == 0)
+        return 1;
+
+    mask = ~0;                  /* turn on all the bits */
+
+    /* shift over by the correct number of bits */
+    mask = mask << (32 - mycidr->masklen);
+
+    /* apply the mask to the network and ip */
+    ipaddr = ntohl(ip) & mask;
+
+    network = htonl(mycidr->network) & mask;
+
+    /* if they're the same, then ip is in network */
+    if (network == ipaddr) {
+
+        dbg(1, "The ip %s is inside of %s/%d",
+            libnet_addr2name4(ip, RESOLVE),
+            libnet_addr2name4(htonl(network), RESOLVE), mycidr->masklen);
+
+        return 1;
+    }
+    else {
+
+        dbg(1, "The ip %s is not inside of %s/%d",
+            libnet_addr2name4(ip, RESOLVE),
+            libnet_addr2name4(htonl(network), RESOLVE), mycidr->masklen);
+
+        return 0;
+    }
+
+}
+
+/*
+ * iterates over cidrdata to find if a given ip matches
+ * returns 1 for true, 0 for false
+ */
+
+int
+check_ip_CIDR(CIDR * cidrdata, const unsigned long ip)
+{
+    CIDR *mycidr;
+
+    /* if we have no cidrdata, of course it isn't in there */
+    if (cidrdata == NULL)
+        return 0;
+
+    mycidr = cidrdata;
+
+    /* loop through cidr */
+    while (1) {
+
+        /* if match, return 1 */
+        if (ip_in_cidr(mycidr, ip)) {
+            return 1;
+        }
+        /* check for next record */
+        if (mycidr->next != NULL) {
+            mycidr = mycidr->next;
+        }
+        else {
+            break;
+        }
+    }
+
+    /* if we get here, no match */
+    return 0;
+}
+
+
+/*
+ * cidr2ip takes a CIDR and a delimiter
+ * and returns a string which lists all the IP addresses in the cidr
+ * deliminated by the given char
+ */
+char *
+cidr2iplist(CIDR * cidr, char delim)
+{
+    char *list = NULL;
+    char ipaddr[16];
+    unsigned long size, i;
+    unsigned long first, last, numips;
+    struct in_addr in;
+
+    /* 
+     * 16 bytes per IP + delim
+     * # of IP's = 2^(32-masklen)
+     */
+    numips = 2;
+    for (i = 2; i <= (32 - cidr->masklen); i++) {
+        numips *= 2;
+    }
+    size = 16 * numips;
+
+    if ((list = (char *)malloc(size)) == NULL)
+        errx(1, "Unable to malloc %d bytes!  Aborting...", size);
+
+    memset(list, 0, size);
+
+    /* first and last should not include network or broadcast */
+    first = ntohl(cidr->network) + 1;
+    last = first + numips - 3;
+
+    dbg(1, "First: %u\t\tLast: %u", first, last);
+
+    /* loop through all but the last one */
+    for (i = first; i < last; i++) {
+        in.s_addr = htonl(i);
+        snprintf(ipaddr, 17, "%s%c", inet_ntoa(in), delim);
+        dbg(2, "%s", ipaddr);
+        strncat(list, ipaddr, size);
+    }
+
+    /* last is a special case, end in \0 */
+    in.s_addr = htonl(i);
+    snprintf(ipaddr, 16, "%s", inet_ntoa(in));
+    strncat(list, ipaddr, size);
+
+    return list;
+}

+ 63 - 0
cidr.h

@@ -0,0 +1,63 @@
+/* $Id: cidr.h 767 2004-10-06 12:48:49Z aturner $ */
+
+/*
+ * Copyright (c) 2001-2004 Aaron Turner.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of the copyright owners nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __CIDR_H__
+#define __CIDR_H__
+
+struct cidr_type {
+    unsigned long network;
+    int masklen;
+    struct cidr_type *next;
+};
+
+typedef struct cidr_type CIDR;
+
+struct cidr_map {
+    CIDR *from;
+    CIDR *to;
+    struct cidr_map *next;
+};
+typedef struct cidr_map CIDRMAP;
+
+int ip_in_cidr(const CIDR *, const unsigned long);
+int check_ip_CIDR(CIDR *, const unsigned long);
+int parse_cidr(CIDR **, char *, char *delim);
+int parse_cidr_map(CIDRMAP **, char *);
+int parse_endpoints(CIDRMAP **, CIDRMAP **, char *);
+u_char *ip2cidr(const unsigned long, const int);
+void add_cidr(CIDR *, CIDR **);
+CIDR *new_cidr(void);
+CIDRMAP *new_cidr_map(void);
+void destroy_cidr(CIDR *);
+void print_cidr(CIDR *);
+char *cidr2iplist(CIDR *, char);
+#endif

File diff suppressed because it is too large
+ 1354 - 0
config.guess


+ 63 - 9
config.h.in

@@ -1,13 +1,67 @@
-/* config.h.in.  Generated automatically from configure.in by autoheader.  */
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
 
-/* Define if you have the ANSI C header files.  */
-#undef STDC_HEADERS
+/* Our code version */
+#undef VERSION
 
-/* Define if you can safely include both <sys/time.h> and <time.h>.  */
-#undef TIME_WITH_SYS_TIME
+/* Version of libpcapnav we were compiled against */
+#undef PCAPNAV_VERSION
 
-/* Define if you have the gettimeofday function.  */
-#undef HAVE_GETTIMEOFDAY
+/* Are we big endian? */
+#undef WORDS_BIGENDIAN
 
-/* Define if you have the <sys/time.h> header file.  */
-#undef HAVE_SYS_TIME_H
+/* Define to 'uint8_t' if <sys/types.h> doesn't define. */
+#undef u_int8_t
+
+/* Define to 'uint16_t' if <sys/types.h> doesn't define. */
+#undef u_int16_t
+
+/* Define to 'uint32_t' if <sys/types.h> doesn't define. */
+#undef u_int32_t
+
+/* Define to 'uint64_t' if <sys/types.h> doesn't define. */
+#undef u_int64_t
+
+/* Define to enable debugging code and -d flag */
+#undef DEBUG
+
+/* Do we have the new inet_aton ? */
+#undef INET_ATON
+
+/* do we have the old inet_addr ? */
+#undef INET_ADDR
+
+/* do we have to force strict byte alignment? */
+#undef FORCE_ALIGN
+
+/* Large file support */
+#ifndef _FILE_OFFSET_BITS
+#undef _FILE_OFFSET_BITS
+#endif
+#undef _LARGE_FILES
+#undef _LARGEFILE_SOURCE
+
+/* Various functions */
+#undef HAVE_FSEEKO
+#undef HAVE_STRNCPY
+
+/* We need fakepoll if poll.h and sys/poll.h don't exist */
+#undef HAVE_POLL_H
+#undef HAVE_SYS_POLL_H
+
+#undef HAVE_UNISTD_H
+#undef HAVE_STRING_H
+
+/* Is libpcapnav available? */
+#undef HAVE_PCAPNAV
+
+/* Is tcpdump available? */
+#undef HAVE_TCPDUMP
+
+/* if so, where is it located? */
+#undef TCPDUMP_BINARY
+
+/* does libpcap come with pcap_datalink_val_to_description() */
+#undef HAVE_DLT_VAL_TO_DESC
+
+#endif /* __CONFIG_H__ */

File diff suppressed because it is too large
+ 1460 - 0
config.sub


File diff suppressed because it is too large
+ 11731 - 1177
configure


+ 531 - 15
configure.in

@@ -1,35 +1,551 @@
-dnl tcpreplay configure script.
-dnl dugsong@anzen.com
-
+dnl $Id: configure.in 1037 2004-12-03 23:51:38Z aturner $
 AC_INIT(tcpreplay.c)
+AC_CONFIG_HEADER(config.h)
+
+dnl Set version info here!
+MAJOR_VERSION=2
+MINOR_VERSION=3
+MICRO_VERSION=3
+TCPREPLAY_VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION
+
+dnl Release is only used for the RPM spec file
+TCPREPLAY_RELEASE=1
+
+
+AC_DEFINE_UNQUOTED(VERSION, "$TCPREPLAY_VERSION")
+AC_SUBST(TCPREPLAY_VERSION)
+AC_SUBST(TCPREPLAY_RELEASE)
+
+
+dnl Initialize prefix.
+if test "$prefix" = "NONE"; then
+	prefix="/usr/local"
+fi
+
+dnl Determine OS
+AC_CANONICAL_BUILD
+AC_CANONICAL_HOST
+AC_CANONICAL_TARGET
+AC_SUBST(host)
+AC_SUBST(build)
+AC_SUBST(target)
+AC_C_BIGENDIAN
 
 dnl Checks for programs.
 AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_CPP
+AC_PROG_LN_S
+AC_PROG_RANLIB
+AC_PROG_AWK
 AC_PROG_INSTALL
 AC_PROG_MAKE_SET
+AC_PATH_PROG(PRINTF, printf)
+AC_SUBST(PRINTF)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+AC_C_CONST
+AC_C_INLINE
+AC_SYS_LARGEFILE
+
+dnl Check for functions
+AC_FUNC_FSEEKO
+
+dnl Enable debugging in code/compiler options
+debug=no
+AC_MSG_CHECKING(for debug enabled)
+AC_ARG_WITH(debug,
+[  --with-debug            Enable debugging code and support for the -d option],
+[ debug=yes
+ AC_DEFINE(DEBUG) 
+ AC_MSG_RESULT(yes)], 
+AC_MSG_RESULT(no))
+
+dnl Use a debug flag during make test if debug is enabled
+if test $debug = yes ; then
+	debug_flag="-d 3"
+	AC_SUBST(debug_flag)
+fi
+
+dnl Enable Efense
+efence=no
+AC_MSG_CHECKING(for efence enabled)
+AC_ARG_WITH(efence,
+[  --with-efence           Enable Electric Fence memory debugger],
+[ efence=yes
+  AC_DEFINE(EFENCE)
+  AC_MSG_RESULT(yes)],
+  AC_MSG_RESULT(no)
+  )
+
+dnl Enable Gprof
+gprof=no
+AC_MSG_CHECKING(for gprof enabled)
+AC_ARG_WITH(gprof,
+[  --with-gprof            Enable GNU Profiler],
+[ gprof=yes
+  AC_DEFINE(GPROF)
+  AC_MSG_RESULT(yes)],
+  AC_MSG_RESULT(no)
+  )
+
 
 dnl Use these compiler flags if we have gcc.
-dnl
-if test $ac_cv_prog_gcc = yes; then
-    CCOPTS='-O3 -pipe -Wall'
+if test $ac_cv_prog_gcc = yes -a $debug = no ; then
+    CCOPTS="-pipe -Wall -O3 -funroll-loops"
     CFLAGS="$CCOPTS"
+else
+	CCOPTS="-pipe -Wall -ggdb -pedantic"
+	CFLAGS="$CCOPTS"
+fi
+
+dnl Gprof requires -ggdb
+if test $gprof = yes -a $debug = yes ; then
+	CCOPTS="$CCOPTS -pg" 
+	CFLAGS="$CCOPTS"
+elif test $gprof = yes -a $debug = no ; then
+	CCOPTS="-pipe -Wall -pg -ggdb"
+	CFLAGS="$CCOPTS"
+fi
+
+dnl Electric Fence
+if test $efence = yes ; then
+	CCOPTS="$CCOPTS -lefence"
+	CFLAGS="$CCOPTS"
+fi
+
+dnl gprof
+if test $gprof = yes ; then
+        CCOPTS="$CCOPTS -fprofile-arcs"
+        CFLAGS="$CCOPTS"
 fi
 
+dnl Check for types.
+AC_CHECK_TYPE(u_int8_t, uint8_t)
+AC_CHECK_TYPE(u_int16_t, uint16_t)
+AC_CHECK_TYPE(u_int32_t, uint32_t)
+AC_CHECK_TYPE(u_int64_t, uint64_t)
+
+dnl Check for other header files
+AC_CHECK_HEADERS([fcntl.h stddef.h sys/socket.h  arpa/inet.h sys/time.h signal.h string.h strings.h sys/types.h sys/select.h netinet/in.h poll.h sys/poll.h unistd.h])
+
 dnl Checks for libraries.
 AC_CHECK_LIB(socket, socket)
 AC_CHECK_LIB(nsl, gethostbyname)
+AC_CHECK_LIB(rt, nanosleep)
 
-dnl Checks for header files.
-AC_HEADER_STDC
-AC_CHECK_HEADERS(sys/time.h)
+dnl Checks for library functions.
+AC_FUNC_MALLOC
+AC_FUNC_MEMCMP
+AC_TYPE_SIGNAL
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS([gettimeofday ctime memset regcomp strdup strerror strtol strncpy strtoull poll])
 
-dnl Checks for typedefs, structures, and compiler characteristics.
-AC_HEADER_TIME
+dnl Check for inet_aton and inet_addr
+AC_CHECK_FUNC(inet_aton, AC_DEFINE(INET_ATON) inet_aton=yes, inet_aton=no)
+AC_CHECK_FUNC(inet_addr, AC_DEFINE(INET_ADDR) inet_addr=yes, inet_addr=no)
 
-dnl Checks for library functions.
-AC_CHECK_FUNCS(gettimeofday)
+if test $inet_aton = no -a $inet_addr = no ; then
+	AC_MSG_ERROR("We need either inet_aton or inet_addr")
+fi
+dnl ##################################################
+dnl Checks for libnet (shamelessly horked from dsniff)
+dnl ##################################################
+foundnet=no
+trynetdir=/usr/local
+AC_MSG_CHECKING(for libnet)
+AC_ARG_WITH([libnet],
+    AC_HELP_STRING([--with-libnet=DIR], [Use libnet in DIR]),
+    [trynetdir=$withval])
 
-AC_CONFIG_SUBDIRS(Libnet-0.99 libpcap-0.4)
+for testdir in $trynetdir /usr/local /usr ; do
+    if test -f "${testdir}/include/libnet.h" -a $foundnet = no ; then
+        LNETINC="-I${testdir}/include"
+        LNETINCDIR="$testdir/include"
+        LNETLIB="-L${testdir}/lib -lnet"
+        foundnet=$testdir
+    fi
+done
+
+if test $foundnet = no ; then
+    AC_MSG_RESULT(no)
+    AC_ERROR(libnet not found)
+else
+    AC_MSG_RESULT($foundnet)
+fi
+
+AC_SUBST(LNETINC)
+AC_SUBST(LNETLIB)
+
+OLDLIBS="$LIBS"
+LIBS="$LNETLIB"
+
+dnl Check to see what version of libnet
+dnl this code has been reduced a lot, but probably still could be
+dnl reduced quite a bit more if we chose too
+AC_MSG_CHECKING(for libnet version)
+
+AC_TRY_RUN([
+#include <string.h>
+#define LIBNET_LIL_ENDIAN 1
+#include "$LNETINCDIR/libnet.h"
+#define LIB_TEST "1.0"
+/* 
+ * simple proggy to test the version of libnet
+ * returns zero if it's 1.0.x 
+ * or one otherwise
+ */
+int
+main (int argc, char *argv[])
+{
+	if (strncmp(LIB_TEST, LIBNET_VERSION, 3) == 0)
+		exit(0);
+	exit(1);
+}],
+	libnet_ver_10=yes
+	AC_MSG_RESULT(1.0.x), 
+	libnet_ver_10=no,
+	libnet_ver_10=no
+	)
+
+AC_TRY_RUN([
+#include <string.h>
+#include "$LNETINCDIR/libnet.h"
+#define LIB_TEST "1.1"
+/* 
+ * simple proggy to test the version of libnet
+ * returns zero if it's 1.0.x 
+ * or one otherwise
+ */
+int
+main (int argc, char *argv[])
+{
+	if (strncmp(LIB_TEST, LIBNET_VERSION, 3) == 0)
+		exit(0);
+	exit(1);
+}],
+	libnet_ver_11=yes
+	AC_MSG_RESULT(1.1.x), 
+	libnet_ver_11=no,
+	libnet_ver_11=no
+	)
+
+
+if test $libnet_ver_10 = no -a $libnet_ver_11 = no ; then
+	AC_MSG_RESULT(unknown)
+	AC_MSG_ERROR(Unable to determine version of libnet)
+fi
+
+if test $libnet_ver_10 = yes ; then
+	  AC_MSG_ERROR(Libnet version 1.0.x is no longer supported.
+		Please upgrade to 1.1.0 or better)
+fi
+dnl restore LIBS
+LIBS="$OLDLIBS"
+
+dnl #####################################################
+dnl Checks for libpcap
+dnl #####################################################
+foundpcap=no
+trypcapdir=/usr/local
+AC_MSG_CHECKING(for libpcap)
+AC_ARG_WITH([libpcap],
+    AC_HELP_STRING([--with-libpcap=DIR], [Use libpcap in DIR]),
+    [trypcapdir=$withval])
+
+for testdir in $trypcapdir /usr/local /usr ; do
+    if test -f "${testdir}/include/pcap.h" -a $foundpcap = no ; then
+       LPCAPINC="-I${testdir}/include"
+       LPCAPINCDIR="${testdir}/include"
+       LPCAPLIB="-L${testdir}/lib -lpcap"
+       foundpcap=$testdir
+    fi
+done
+
+if test $foundpcap = no ; then
+   AC_MSG_RESULT(no)
+   AC_ERROR(libpcap not found) 
+else
+   AC_MSG_RESULT($foundpcap)
+fi
+
+
+AC_SUBST(LPCAPINC)
+AC_SUBST(LPCAPLIB)
+
+dnl Checks to see what version of libpcap we've got
+OLDLIBS="$LIBS"
+LIBS="$LPCAPLIB"
+
+dnl Check to see what version of libpcap
+dnl this code has been reduced a lot, but probably still could be
+dnl reduced quite a bit more if we chose too
+AC_MSG_CHECKING(for libpcap version)
+
+AC_TRY_RUN([
+#include <string.h>
+#include "$LPCAPINCDIR/pcap.h"
+#define PCAP_TEST "0.6"
+/* 
+ * simple proggy to test the version of libpcap
+ * returns zero if version >= 0.6
+ * or one otherwise
+ */
+extern char pcap_version[];
+int
+main (int argc, char *argv[])
+{
+	if (strncmp(pcap_version, PCAP_TEST, 3) >= 0)
+		exit(0);
+	exit(1);
+}],
+	libpcap_ver=yes
+	AC_MSG_RESULT(>= 0.6),
+	libpcap_ver=no
+	AC_MSG_RESULT(< 0.6),
+	libpcap_ver=no
+	)
+
+
+if test $libpcap_ver = no ; then
+	AC_MSG_ERROR(Libpcap versions < 0.6 are no longer supported.
+	Please upgrade to version 0.6 or better)
+fi
+
+dnl Check to see if we've got pcap_datalink_val_to_name()
+AC_MSG_CHECKING(for pcap_datalink_val_to_description)
+AC_TRY_RUN([
+#include <stdio.h>
+#include "$LPCAPINCDIR/pcap.h"
+int 
+main(int argc, char *argv[]) {
+    char name[100];
+    strncpy(name, pcap_datalink_val_to_description(1), 99);
+    exit(0);
+} 
+],
+    have_dlt_to_desc=yes 
+    AC_MSG_RESULT(yes), 
+    have_dlt_to_desc=no
+    AC_MSG_RESULT(no),
+    have_dlt_to_desc=no
+    )
+
+if test $have_dlt_to_desc = yes ; then
+    AC_DEFINE(HAVE_DLT_VAL_TO_DESC)
+fi
+
+dnl restore LIBS
+LIBS="$OLDLIBS"
+
+
+
+dnl ##################################################
+dnl # Check for pcapnav
+dnl ##################################################
+pcapnav_ver=no
+pcncfg=no
+AC_ARG_WITH(pcapnav-config,
+    AC_HELP_STRING([--with-pcapnav-config=FILE], [Use given pcapnav-config]),
+    [pcncfg=$withval],
+    [ AC_PATH_PROG(pcncfg,[pcapnav-config], [] ) ])
+
+
+if test $pcncfg = no ; then
+    AC_MSG_RESULT(Cannot find pcapnav-config: Disabling offset jump feature.)
+else
+    AC_MSG_RESULT($pcncfg)
+    LNAVLIB=`$pcncfg --libs`
+    LNAV_CFLAGS=`$pcncfg --cflags`
+    PCAPNAV_VERSION=`$pcncfg --version`
+    AC_SUBST(LNAVLIB)
+    AC_SUBST(LNAV_CFLAGS)
+    AC_DEFINE_UNQUOTED(PCAPNAV_VERSION, "$PCAPNAV_VERSION")
+
+dnl Check to see what version of libpcapnav
+dnl this code has been reduced a lot, but probably still could be
+dnl reduced quite a bit more if we chose too
+        AC_MSG_CHECKING(for libpcapnav version)
+        AC_TRY_RUN([
+#include <string.h>
+#define PCAPNAV_TEST "0.4"
+/* 
+ * simple proggy to test the version of libpcapnav
+ * returns zero if version >= 0.4
+ * or one otherwise
+ */
+
+int
+main (int argc, char *argv[])
+{
+	if (strncmp(PCAPNAV_VERSION, PCAPNAV_TEST, 3) >= 0)
+		exit(0);
+	exit(1);
+}],
+     	libpcapnav_ver=yes
+       	AC_MSG_RESULT(>= 0.4),
+       	libpcapnav_ver=no
+       	AC_MSG_RESULT(< 0.4),
+       	libpcapnav_ver=no
+       	)
+
+
+if test $libpcapnav_ver = no ; then
+     	AC_MSG_WARN([Libpcapnav versions < 0.4 are not supported.
+    Please upgrade to version 0.4 or better.
+    Disabling offset jump feature.])
+else
+    AC_DEFINE(HAVE_PCAPNAV)
+fi
+
+fi # checking pcapnav version
+
+dnl (shamelessly ripped off from libpcap)
+dnl Checks to see if unaligned memory accesses fail
+dnl
+dnl     FORCE_ALIGN (DEFINED)
+dnl
+AC_MSG_CHECKING(for requires strict byte alignment)
+AC_CACHE_VAL(unaligned_fail,
+        [case "$host_cpu" in
+
+        # XXX: should also check that they don't do weird things (like on arm)
+        alpha*|arm*|hp*|mips*|sparc*|ia64)
+                unaligned_fail=yes
+                ;;
+
+        *)
+                cat >conftest.c <<EOF
+		#include <sys/types.h>
+		#include <sys/wait.h>
+		#include <stdio.h>
+                unsigned char a[[5]] = { 1, 2, 3, 4, 5 };
+                main() {
+                unsigned int i;
+                pid_t pid;
+                int status;
+                /* avoid "core dumped" message */
+                pid = fork();
+                if (pid <  0)
+                        exit(2);
+                if (pid > 0) {
+                        /* parent */
+                        pid = waitpid(pid, &status, 0);
+                        if (pid < 0)
+                                exit(3);
+                        exit(!WIFEXITED(status));
+                }
+                /* child */
+                i = *(unsigned int *)&a[[1]];
+                printf("%d\n", i);
+                exit(0);
+                }
+EOF
+                ${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS \
+                    conftest.c $LIBS >/dev/null 2>&1
+                if test ! -x conftest ; then
+                        dnl failed to compile for some reason
+                        unaligned_fail=yes
+                else
+                        ./conftest >conftest.out
+                        if test ! -s conftest.out ; then
+                                unaligned_fail=yes
+                        else
+                                unaligned_fail=no
+                        fi
+                fi
+                rm -f conftest* core core.conftest
+                ;;
+        esac])
+    AC_MSG_RESULT($unaligned_fail)
+    if test $unaligned_fail = yes ; then
+            AC_DEFINE(FORCE_ALIGN,1,[if unaligned access fails])
+    fi
+
+dnl ##################################################
+dnl # Check for tcpdump.
+dnl ##################################################
+
+AC_ARG_WITH(tcpdump,
+   AC_HELP_STRING([--with-tcpdump=FILE],[Path to tcpdump binary]),
+   [td=$withval],
+   [td=no])
+
+AC_PATH_PROG(td, tcpdump, "no",[$PATH:/usr/sbin:/sbin:/usr/local/sbin])
+if test $td = no ; then
+    AC_MSG_WARN([Unable to find tcpdump.  Please specify --with-tcpdump.
+                 Disabling verbose reporting.])
+else
+    AC_MSG_RESULT([Using tcpdump in $td.])
+    AC_DEFINE(HAVE_TCPDUMP)
+    AC_DEFINE_UNQUOTED(TCPDUMP_BINARY, "$td", [The tcpdump binary initially used])
+fi
+
+dnl No 'make test' when cross compile
+
+AC_MSG_CHECKING( for 'make test' profile)
+if test "$host" != "$build" ; then
+	AC_MSG_WARN(Unable to do tests when cross-compiling)
+fi
+
+dnl Allows user to choose which nic to use for testing purposes
+AC_ARG_WITH(testnic,
+    AC_HELP_STRING([--with-testnic=NIC], [Select which network card to use for testing]),
+    [nic1=$withval
+     nic2=$withval
+    AC_MSG_RESULT([Using --with-testnic=$withval])],
+    [
+dnl these need to be dynamic based on OS
+case $host in
+	*-*-linux*)
+	nic1=eth0
+	nic2=eth0
+	AC_MSG_RESULT(Linux)
+	;;
+
+	*-*-solaris*)
+	nic1=hme0
+	nic2=hme0
+	AC_MSG_RESULT(Solaris)
+	;;
+
+	*-*-sunos*)
+	nic1=hme0
+	nic2=hme0
+	AC_MSG_RESULT(SunOS)
+	;;
+
+	powerpc-apple-darwin*)
+	nic1=en0
+	nic2=en0
+	AC_MSG_RESULT(Apple OSX)
+	;;
+
+    *-*-openbsd*)
+    nic1=xl0
+    nic2=xl0
+    AC_MSG_RESULT(OpenBSD)
+    ;;
+
+	*)
+	AC_MSG_RESULT([$host is unknown!  
+	Please use --with-nictest to select an interface for 'make test'])
+	;;
+esac])
+
+
+AC_ARG_WITH(testnic2,
+    AC_HELP_STRING([--with-testnic2=NIC2], [Select an optional 2nd network card to use for testing]),
+    [nic2=$withval])
+
+AC_MSG_NOTICE(Using $nic1 for 1st test network interface card)
+AC_MSG_NOTICE(Using $nic2 for 2nd test network interface card)
+AC_SUBST(nic1)
+AC_SUBST(nic2)
 
-AC_CONFIG_HEADER(config.h)
 AC_OUTPUT(Makefile)
+AC_OUTPUT(test/Makefile)
+AC_OUTPUT(test/config)
+AC_OUTPUT(tcpreplay.spec)

+ 0 - 0
dlt.h


Some files were not shown because too many files changed in this diff