Ethereal-dev: Re: [ethereal-dev] Packet defragmentation thoughts

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

From: Guy Harris <gharris@xxxxxxxxxxxx>
Date: Wed, 8 Sep 1999 20:35:23 -0700
> I've been thinking about how to best approach packet defragmentation.
> We need to be able to defragment ("unfragment"?) packets from multiple
> protocols at the same time. I'd like to re-assemble fragmented IP packets,
> as well as TCP transmissions, and send those reassembled packets back
> through the protocol decoders.
> 
> Say we have this trace:
> 
> packet 1:  IPX packet
> packet 2:  IP frag #0
> packet 3:  IP frag #1
> packet 4:  IPX packet
> packet 5:  IP frag #2 (final)
> 
> Upon defragmenting at the IP level, I'd like to see:
> 
> packet 1:  IPX packet
> packet 4:  IPX packet
> packet 5:  UDP (a combination of IP frags #0, #1, and #2).

I could imagine wanting to see, in the summary display:

	packet 1:  IPX packet
	packet 2:  IP frag #0
	packet 3:  IP frag #1
	packet 4:  IPX packet
	packet 5:  IP frag #2 (final)

but, when I open packet 2, see

	Frame (XXX on wire, XXX captured)
	Ethernet II
	Internet Protocol
	User Datagram Protocol
	ONC RPC
	NFS

and, when I open up NFS, see a decode of all fields that are
completely inside the first fragment, plus any field that starts in the
first fragment, and, when I open packet 3, see, for example

	Frame (XXX on wire, XXX captured)
	Ethernet II
	Internet Protocol
	User Datagram Protocol
	ONC RPC
	NFS

and, when I open up "User Datagram Protocol", see

	Continued from packet 2

(as there's no UDP header in packet 3) and, when I open up NFS, perhaps
see any field that started in packet 2 but continued into packet 3, plus
all fields completely contained in packet 3, plus any field that starts
in packet 3, and so on.  This might be useful if you want to see when
the pieces of a particular "higher-level" packet were sent or received.

In addition, however, I could also imagine wanting to see

	packet 1:  IPX packet
	packet 4:  IPX packet
	packet 5:  UDP (a combination of IP frags #0, #1, and #2).

with some indication in packet 5 that it's composed of frames 2, 3, and
5, and *some* indication of the common part of the IP headers (source
and destination IP address), with the entire NFS request or reply shown.

So some way of seeing either a frame-based or a
higher-level-packet-based display (perhaps controlled by something under
the "Display" menu) might be useful.

In addition, consider an NFS-over-TCP request that, for some reason,
happened to include TCP segments inside fragmented IP datagrams (you're
not *supposed* to send out TCP segments inside fragmented IP datagrams -
unlike UDP datagrams, you're not prevented from chopping TCP streams up
as you desire - but it's not impossible to get them), in which case one
view might be

	packet 1:  IPX packet
	packet 2:  IP frag #0
	packet 3:  IP frag #1 (final)
	packet 4:  IPX packet
	packet 5:  IP packet

and another view might be

	packet 1:  IPX packet
	packet 3:  TCP (a combination of IP frags #0 and #1).
	packet 4:  IPX packet
	packet 5:  IP packet

and another view might be

	packet 1:  IPX packet
	packet 4:  IPX packet
	packet 5:  ONC RPC "fragment" made up of the TCP segments in
		   packets 3 and 5

(and, as "fragment" might suggest, you could have multiple ONC RPC
"fragments" inside a single ONC RPC-over-TCP message, which could well
introduce *another* level of packet accumulation).

I'd been thinking that, to do this, one might have macros to extract
data of a given size from a reassembled packet; if the data is entirely
within a frame, they act like "p{n,le}toh{l,s}", but would otherwise
call a routine that could reassemble them *if* all the data is
available, and fail if it's not all available (because we don't have all
the pieces of the reassembled packet, or because the capture length was
too short to capture all the data, or because the reassembled packet was
too short for the data - i.e., if whoever sent the data didn't send it
all) - we'd probably want that failure to cause, when building a
protocol tree, a line to be stuck into the protocol tree saying why it
failed.

(Note that this would be used even if you don't have a reassembled
packet, just a single frame - you still want the length checking....)

The routine might be handed a data structure a list of pointers and
lengths for the data that makes up the packet; it might be handed an
offset, or a pointer to an entry in that list and an offset from the
beginning of that entry.

Alternatively, if we're dealing with a reassembled packet, rather than a
packet contained entirely within a frame, we could copy the data in the
packet to a separate buffer.

The former involves less copying, but is somewhat of a pain if we don't
have the file (or a region of it) mapped into memory, and requires more
work to extract values split across frames; the latter involves copying
data.

Taking the first (NFS-over-RPC-over-UDP) example, if you clicked on
frame 2 in the un-reassembled summary display, "dissect_eth()" would
build a normal tree, and "dissect_ip()" would build a normal tree, but
would see, from some data structure, that this frame needs to be
combined with frames 3 and 5; it'd do that, and then hand the
reassembled frame to "dissect_udp()", which would do a normal dissection
- but the routines to add entries to the tree would check whether the
entry being added had any data at all in frame 2, and wouldn't add an
entry to the tree if it didn't.

If you clicked in packet 5 in the reassembled summary, it would,
somehow, probably avoid calling "dissect_eth()" at all, and might or
might not call "dissect_ip()"; the entry for packet 5 might already have
a list of the pieces of data that make up the UDP datagram, and might
directly hand that to "dissect_udp()", and, in this case, all the
entries would have data in the reassembled packet, and would be added to
the tree.

I'd have to think some more about how we'd build the summary lines (I
want to send this off now, just in case the thunderstorm crashes either
PG&E, my Internet connection, or my computer...).