I. Summary

The TCP Stream Reassembly plugin allows one to reconstruct the tcp
streams between two hosts based on the observed packets going between
them.  This is necessary as it is quite easy to ellude snort's current
incarnation by writing a program to send attack code 1 byte at a time.
The victim's tcp stack will correctly reassemble this data and pass it
on to the process listening at the designated port.  Snort which only
does content matching from packets will never see a thing. The author
has demonstrated this quite satisfactorily to himself and will not be
distributing the (trivial) code to do so. :-)


II. TCP Streams

A little on the design philosophy here (yes there is a philosophy of
sorts).  TCP is designed to insure correct and sequential delivery of
data betwen two hosts even over noisy links.  To achieve this, each
host (A and B) pick a (in theory) random number representing the first
byte of data being sent by that host (this is the initial sequence
number).  Each chunk of data in the stream is sent with a sequence
number which indicates where in the stream this particular bit of data
starts at.  The use of SEQ numbers allows TCP to meet the ordered
requirement placed on it.  A receiving host can take an individual
packet of data and determine where within the stream the data belongs.

To acheive correct delivery of data, when a packet is being sent from
A to B, A computes a checksum and places it in the TCP packet.  Upon
receiving the packet, B computes the checksum and if they match it, it
is correct.  The next time B sends data to A, it acknowledges that it
has received correct data up to and including a given sequence number.
This is the purpose of the ACK field.  It allows host B to tell host A
that all of A's data represented by sequence numbers up to ACK are
okay.

Each host has a window size indicating the amount of unacknowledged it
will buffer.  When host A has sent host B's maximum amount of data, it
_must_ wait until some of that data has been acknowledged before
sending any new data.  It may however resend data that has not yet
been acknowledged.  In fact this is the mechanism by which TCP decides
to retransmit.  If you haven't seen ACKs of any new data for a set
amount of time, you should probably resend.


III. tcp_stream preprocessor

So, there are two ways we could handle data buffering on the plugin.
We could either make the data available as soon as we see it, although
this does not insure that the data was correctly received by the
destination.  Or, we could buffer all data we see but only make it
available to users when we see an ACK of that data.  I chose the later
course, which _should_ mean that the only data that can get out of my
buffers is that which is seen by the destination host.  So, new data
from A -> B is only made available by an ACK packet from B -> A.  This
can cause a few headaches as will be explained later.

Now that we are getting ordered data into our buffers, the plugin will
read data out of the buffer and generate a new _correct_ packet based
on one of two conditions:

   a) The last data ACKed contains a return character (0x0d or 0x0a). 
      Since the plugin searches from the end to the begining of the 
      queue, the first return character seen (the last ACKed) will 
      generate a packet of all the data in the buffer up to that point.

   b) The plugin has 'maxbytes' ACKed in its buffer.  In this case, the
      packet will contain the first maxbytes of data in the buffer.

IV. Usage
   
preprocessor stream: <arg set 1>, <arg set 2>, ...

Arguments:  one or more of the following separated by commas

timeout <timeout value>

ports <port 1> ... <port N>

maxbytes <maxbytes>

<timeout>  - the max time in seconds for which a stream will be 
             kept alive if we haven't seen a packet for it
<port x>   - a server port to monitor.  we don't want to monitor 
             all tcp streams (do we?)
<maxbytes> - maximum bytes in our reconstructed packets

example: 
  preprocessor stream: timeout 5, ports 21 23 80 8080, maxbytes 16384


V. Author info, etc.

The tcp_stream preprocessor was written by Christopher E. Cramer
<cec@ee.duke.edu>.  Please direct any comments, suggestions, bug
reports or fixes to him.  I would like to thank Marty, and everyone
else who has been working on Snort for producing such a fine program.
