Ethereal-dev: Re: [Ethereal-dev] tcp reassembly design thought

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: "Ronnie Sahlberg" <rsahlber@xxxxxxxxxxxxxx>
Date: Wed, 27 Jun 2001 20:27:02 +1000
Hi,

----- Original Message -----
From: "Guy Harris"
To: "Ronnie Sahlberg"


> On Tue, Jun 26, 2001 at 04:45:32PM +1000, Ronnie Sahlberg wrote:
> > The tcp-dissector would process packet 1 and since it is not associated
with
> > any reassembly requests it would
> > call dissect-rpc. dissect-rpc would se that this packet only contains 10
> > bytes, but the rpc header says that the entire
> > command is 30 bytes,
>
> If by "RPC" you mean ONC RPC, RPC headers don't say things such as that
> - instead, they say "here's a fragment that contains XXX bytes", and
> possibly say "this is the last fragment".

Yes, but you get the picture:
As the IPv4 reassembly routine (which I am not happy with) copy all segments
to temporary buffers and keep them
lying aroung until we know we have a complete packet. Then it malloc()s an
even bigger chunk and copy everything once again into
this buffer. TCP reassembly could work conceptually very similar to ip
reassembly.

>
> Perhaps most of the type an RPC request or reply consists of only one
> fragment, but it'd be nice to be able to handle requests or replies that
> don't.

Most RPC requests/replies consists of only one segment, yes.
Except say NFSoverTCP and similar protocols.
Mount your NFS server over TCP and produce a capture.
Most packets in your capture will be non-first segments from
NFSoverRPCoverTCP.


>
> Note also that some TCP reassembly might not be byte-count based -
> consider, for example, a text-based protocol such as FTP or SMTP or HTTP
> or...; a line in a message might cross a TCP segment boundary.

Yes this design flawed as it definitively is will at least solve the problem
with
RPCoverTCP. Other areas where tcp reassembly is required would need a
different approach.



This is not a perfect solution to the general problem which I am confident
you have noticed.
Topic for a different discussion:
I am more and more convinced that the only sufficiently powerful and generic
solution would be changing ethereal
to do stateful packet handling. I.e. remembering packet content and tvbuffs
between packets.
This is not how ethereal works now and it would have certain drawbacks which
would make it "difficult" to get into
CVS.


real question:
Right now ethereal ethereal only keeps most tvbuff's and their data around
for the duration of dissecting one single packet.
When the next packet is dissected/parsed the previous packet is forgotten.
(When capturing from a live interface, the captured packets are also written
to a temporary capture file?)
Whenever a packet is rescanned the packet will be reread from the capture
file and redissected?

Would behaviour, performance and run-time memory footprint of ethereal
really be very different if say the capturefile was
mmap()ed instead of using fread()/fwrite() ?
By memory mapping this capture file it would be perfectly possible to keep
the tvbuff's and its associated data (pointers into the
mmap()ed file) hanging around even between packets.
This could make stateful operations such as reassembly of (out of order?)
tcpsegments much much easier, infact it would be almost trivial.
Also nice features as searchable fault like
tcp.segment.overlap.conflict==TRUE  would be extremely easy to implement if
dissect-tcp() knew of every single previous tcp packet it dissected.

Would mmap()ing (instead of fread()/fwrite())the capture file in ethereal be
an option considered for future versions?