On Jul 13, 2007, at 1:09 PM, Jon Andersen wrote:
I'm working on a protocol dissector for several layered protocols on
top of TCP and have a general dissection issue for which I'd like
some advice or wizardry.
I have a packeted connection protocol on top of TCP, which itself
contains packets of another protocol:
TCP
P1
P2
The issue is that the packets of P2 may be split up into multiple
packets of P1, and P1 may be split up into multiple packets by TCP.
This makes the reassembly and dissection tricky (-;
tcp_dissect_pdus() works beautifully for handling fragmented P1
packets. However, it doesn't help with the recursive problem of P2
packets being fragmented.
It's not supposed to. The information about the fragmentation of P2
packets into multiple P1 packets is either known to the P1 dissector
(see, for example, IP fragmentation) or the P2 dissector.
Thus, either the P1 dissector should be handling the reassembly, or
the P2 dissector should be handling the reassembly, possibly with the
help of the P1 dissector.
There's no master general reassembly mechanism in Wireshark, because
there's no single scheme used by all protocols for fragmentation.
There are helper routines in epan/reassemble.c for dissectors to use,
and the reassembly code in a particular dissector might consist only
of a few calls to those helper routines, which do the vast majority of
the work - but different dissectors need to call different routines,
as their protocols do fragmentation differently.
tcp_dissect_pdus() is only a small part of the TCP reassembly
mechanism; it's just a wrapper for certain types of protocols, but
other protocols, such as HTTP, do the reassembly differently, as HTTP
requests and responses don't have a message length in a header near
the beginning of the message (the HTTP header is terminated by a blank
line, so you have to keep grabbing data until you find the blank line;
the HTTP body might have its length specified by the Content-Length
field of the header, or it might run until the connection closes).
The TCP reassembly mechanism is, by design and intent designed to
handle only the reassembly of messages that cross TCP segment
boundaries. It involves both the TCP dissector and the dissector
above it, as the service TCP provides is a byte stream, with no
message boundaries, so only the dissector above TCP knows what the
message boundaries are. tcp_dissect_pdus() is a wrapper that
1) handles multiple messages in a single segment
and
2) handles the details of telling the TCP dissector that more data is
needed for messages that cross segment boundaries.
Burdening the TCP reassembly mechanism with handling reassembly for
other protocols would complicate that code - and it's already
complicated, and has some known bugs that need to be fixed.
Think about what happens when a P2 packet is split across two P1
packets, and each of the P1 packets is encapsulated in a different
TCP packet.
Think about what happens when a TDS packet is split across multiple
NETLIB packets. See packet-tds.c for an example of a set of protocols
that work the way your P1 and P2 protocols work.
What is needed is a fancier or more general implementation of
tcp_dissect_pdus, updated to handle new-style dissectors.
No, what is needed is dissectors for P1 and P2 that do the reassembly
of P2 packets fragmented over multiple P1 packets. Again, see packet-
tds.c.