This is a static archive of our old Q&A Site. Please post any new questions and answers at ask.wireshark.org.

Defragmenting TCP Stream Fragments

0

Greetings,

I am working on a plugin that dissects TCP streams generated between systems that communicate with each other using Visage Standard Messaging Format (VSMF). I am using the Conversation API to track the streams because its follow-on packets could be either compressed or uncompressed. I am also using a technique similar to this question for reassembling the fragments because, if not, my decompressing as well as my dissecting won't work.

So far, I've been successful except I seem to be experiencing the same issues @hudac ran into in his question above, and it doesn't appear that he had his question answered. By that, I mean he was told what was happening, but no method to circumvent it was mentioned.

If using tcp_dissect_pdus(), which makes the protocol run atop TCP, means that there is no guarantee that packet boundaries for your protocol will correspond to TCP segment boundaries, then what method can I use to allow my plugin to run under TCP in order for it to reassemble the fragments into a complete segment for my plugin? I'm almost certain that I may not be able to use PDU to assist in reassembly because I don't know that there is a size value in the first bytes of each PDU (according to SYN-bit who mentions it here).

Thanks in advanced.

asked 13 Apr '16, 19:11

coloncm's gravatar image

coloncm
7681115
accept rate: 66%

edited 13 Apr '16, 19:53


One Answer:

1

So problem is that you'd like to use tcp_dissect_pdus() (because your protocol runs over TCP and thus the PDUs may not align with TCP segment boundaries) but you don't know (or think?) that there's a message length at the beginning of the packet?

First, I'd make sure there's no message length towards the beginning of the packet: if there is your life will be much easier.

If not then you'll have to tell Wireshark when to do desegmentation; look in README.dissector for information about desegment_len (and possibly look at some other dissectors for examples).

Note that it is possible to use tcp_dissect_pdus() together with manually setting desegment_len; for example the Diameter dissector uses DESEGMENT_ONE_MORE_SEGMENT when tcp_dissect_pdus() doesn't give it enough data to determine if the data is really Diameter or not.

answered 14 Apr '16, 06:39

JeffMorriss's gravatar image

JeffMorriss ♦
6.2k572
accept rate: 27%

edited 14 Apr '16, 12:28

@JeffMorriss, thank you for your input.

After reading the portion of the README.dissector you suggested, I discovered that reassembling a PDU is not my issue, but the dissection of multiple PDUs across a single packet. My plugin is being called to dissect each PDU independently of each other, and I'm not sure if it is what I really want it to do. I guess, I'd have to understand what is a PDU within a packet in terms of the conversation between the systems (TCP stream). Could you explain?

(14 Apr '16, 11:10) coloncm
1

The way we generally talk about things in Wireshark is like this:

  • Frame: this is a single Ethernet (or other) packet as it was on the wire. Sometimes also called a packet. You see frames in the packet list frame (generally the top-most frame) in Wireshark.
  • PDU (Protocol Data Unit): a single "message" from the point of the upper-layer (above TCP, UDP, etc.) protocol. Some transport protocols (like TCP) have no conception of where PDU boundaries are, others (like SCTP) do.

So:

  1. A frame can contain one or more PDUs
  2. A frame can also contain one or more fragments of PDUs
  3. (A frame can also contain both whole PDUs and fragments of PDUs)
  4. A PDU may be spread across one or more frames

tcp_dissect_pdus() deals with 1-4 for you so your dissector doesn't have to worry about PDU boundaries when TCP is the transport. As you said, your dissector does some setup work (telling TCP the PDU lenght) and then tcp_dissect_pdus() will call your dissector for each PDU.

If you want Wireshark to call you for each frame then just don't use tcp_dissect_pdus(). But then you'll have to deal with 1-4 yourself.

(14 Apr '16, 12:27) JeffMorriss ♦

I see. So, a PDU is a single transmission, already reassembled if sent in fragments, sent from one node to another, and not a frame with respect to TCP streams. Which means that my dissector, which currently parses each PDU separately, is actually doing it correctly. I just need to ensure what it's getting gets parsed as a single "message" (VSMF in this case) according to the established architecture. Am I understanding this correctly?

(14 Apr '16, 14:59) coloncm

Yes, that sounds about right. Really to check if things are working correctly you need to make sure it works in all of the 4 conditions listed above--that means verifying that it works when a frame has one PDU (common case, easy), when a frame has 2+ PDUs, when a PDU is spread across 2+ frames, etc.

(15 Apr '16, 06:52) JeffMorriss ♦