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
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 modification, are permitted provided that the following conditions
@@ -9,12 +12,12 @@ are met:
 2. Redistributions in binary form must reproduce the above copyright
 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
    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:
    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
 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 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@
 CC		= @CC@
 CFLAGS		= @CFLAGS@
 CFLAGS		= @CFLAGS@
 LDFLAGS		= @LDFLAGS@
 LDFLAGS		= @LDFLAGS@
 DEFS		= @DEFS@
 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		= @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:
 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
 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: 
-	$(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:
 uninstall:
 	rm -f $(SBINDIR)/tcpreplay
 	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_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.
 dnl Checks for programs.
 AC_PROG_CC
 AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_CPP
+AC_PROG_LN_S
+AC_PROG_RANLIB
+AC_PROG_AWK
 AC_PROG_INSTALL
 AC_PROG_INSTALL
 AC_PROG_MAKE_SET
 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 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"
     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
 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.
 dnl Checks for libraries.
 AC_CHECK_LIB(socket, socket)
 AC_CHECK_LIB(socket, socket)
 AC_CHECK_LIB(nsl, gethostbyname)
 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(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