ANNOUNCEMENT: Live Wireshark University & Allegro Packets online APAC Wireshark Training Session
April 17th, 2024 | 14:30-16:00 SGT (UTC+8) | Online

Wireshark-dev: Re: [Wireshark-dev] Dissect multiple PDUs in one TCP Segment

From: Guy Harris <guy@xxxxxxxxxxxx>
Date: Wed, 23 May 2007 10:45:07 -0700
Robert Naumann wrote:

i'm new to the dissector developement for wireshark. I've read that it should be actually possible to dissect multiple PDUs from one TCP Segment with tcp_dissect_pdus(), but i don't get it working.

For example: i've got 2 different PDUs with different lengths (5 and 6). I already got the pdu lengths. The Length of the TCP Datasegment is 11.

So for the first PDU the function:

tcp_dissect_pdus(tvb, pinfo, tree, TRUE, min_pdu_size, *first_pdu_size*, dissect_pdu_sc);

tcp_dissect_pdus() isn't called for every PDU; it's called *once* in the dissector for your protocol, and the argument you mark as "first pdu size" is a function that gets the PDU size of a PDU.

"min_pdu_size" should be the minimum amount of packet data needed to calculate the PDU size. For example, if every PDU starts with a 2-byte PDU type and a 2-byte PDU length, in that order, "min_pdu_size" should be 4, to include the PDU length. If the length comes *before* the type, it'd be 2.

If the value of the length field in the PDU includes the lengths of the type and length fields, and the fields are in big-endian order, then:

In the case where there's a type and length, in that order, the function to get the PDU size would be

	static gint
	get_sc_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
	{
		return tvb_get_ntohs(tvb, offset + 2);
	}

and in the case where the length comes before the type, it'd be

	static gint
	get_sc_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
	{
		return tvb_get_ntohs(tvb, offset);
	}

Replace "tvb_get_ntohs()" with "tvb_get_letohs()" if the fields are in little-endian order.

If the value of the length field in the PDU *doesn't* include the lengths of the type and length field, you'd add 4 to the length field in the first of those functions and add 2 to the length field in the second of those functions.

so the first PDU with the correct size (proved) should be passed to the dissector function dissect_pdu_sc.

My first problem: ============= At the dissection of my top level protocol the PDU is marked as [Malformed Packet], why? Size is correct! bitstream show the complete data of my PDU

So your function is returning the value 5 for the first PDU?

Is your dissector trying to dissect more than 5 bytes in the PDU? If so, it's acting as if the packet should be longer than 5 bytes long, and thus a 5-byte-long packet would be malformed. An attempt to fetch data past the end of the 5-byte tvbuff your dissector is handed will cause an exception to be thrown and your packet marked as malformed.

My second problem: =============== The second PDU within the the TCP Segment wont be dissected and not shown as a part of my top level protocol. Is the second PDU automatically processed

Yes.

or do i have to call the function tcp_dissect_pdus() again?

No. It's called "tcp_dissect_pdus()", plural, not "tcp_dissect_pdu()", singular, because it's supposed to be handed all the data that's passed to the disector and dissects all the PDUs in that data.