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

How to dissect TCP stream which emits multiple packets

0

I'am writing dissector for protocol over TCP stream which can emit more than one packet per real TCP frame. For example lets assume that we have ethernet tunnel over TCP stream, and one TCP frame of length 15000 bytes (assume the capture with TSO on) can contain five or ten embedded ethernet packets. So I can successfully dissect this stream, can write info about each packet to frame tree. But it is not possible to indicate such packet in frame list. And another case when I try to sub dissect emitted packets by ethernet dissector the system goes crazy and breaks TCP reassemble functionality.

What is a proper way to write such dissector? How can I indicate new frames to frame list? How not to break TCP reassemble functionality when subdissecting nested packets?

The best approach I have found is to dump the emitted packets to another pcap file on dissection and then load it to wireshark. But this is a hard way.

asked 13 Feb '14, 07:41

RuAnShi's gravatar image

RuAnShi
11113
accept rate: 0%


One Answer:

0

But it is not possible to indicate such packet in frame list.

That's not supported. At some point in the future we might support having multiple ways of viewing the list of packets, with an option to have the list show all packets at a given layer, so that, while the frame list will always be a list of "frames" as defined by the lowest layer protocol in the capture, you could see, instead, a list of reassembled IP datagrams (with one entry per IP datagram, and with the fragments not shown as individual frames) or a list of XXX-over-TCP packets (with one entry per XXX packet, even if there are multiple XXX packets in one frame or one TCP segment or if an XXX packet requires multiple frames or TCP segments), but that's not available now.

What is a proper way to write such dissector?

How do you determine where an Ethernet packet begins or ends in the TCP byte stream? Do you have a length field before each Ethernet packet? If so, you could use tcp_dissect_pdus().

answered 13 Feb '14, 15:11

Guy%20Harris's gravatar image

Guy Harris ♦♦
17.4k335196
accept rate: 19%

That's not supported. At some point in the future ....

Personally I have waiting for such feature from 1.4 release, when I start to write plugins for wireshark. It is good to see lots of improvements and refactoring in source tree. Hope this great functionality will be implemented at nearest future.

How do you determine where an Ethernet packet begins or ends in the TCP byte stream?

Lets assume there is a length mark. I have not using tcp_dissect_pdus() because it's to old, my dissector is based on "new" stream dissection architecture. Where I can indicate desegment_offset and desegment_len and ask for more data when needed. This totally avoid to be dependent on underlying dissector.

Related to TCP reassemble bug. It is now clear for me that if I subdissect emmited frames through eth dissector, which than call TCP dissector again. Than after returning from subdissection the packet_info struct totally reflect underlying TCP substream, not the original TCP frame stream, and there is a roots of broken reassemble functionality. I'am not know a proper way how to fix this.

(14 Feb '14, 01:23) RuAnShi
1

I have not using tcp_dissect_pdus() because it's to old, my dissector is based on "new" stream dissection architecture. Where I can indicate desegment_offset and desegment_len and ask for more data when needed.

You have it exactly backwards. The old architecture required every dissector to manage desegment_offset and desegment_len itself. Several dissectors, for protocols with headers that included a length, had duplicate code to do the same thing; that code was extracted into tcp_dissect_pdus() and generalized to have the length of the part containing the length field, and a routine to extract the length from that part, be arguments to tcp_dissect_pdus().

(14 Feb '14, 01:31) Guy Harris ♦♦

May be this is true for protocols running only atop of TCP, but in general way I wish my dissector to be running at any data stream. So, according to README.dissector 2.7 I should use 2.7.2 method, which allow me to dissect any data stream in general. Otherwise I need to write dissector for each underlying transport. According to desegment_offset and desegment_len, they only used when dissector detect that there more data required to be called once again with enlarged tvb. And of cause the dissector use new_create_dissector_handle with function which return amount of already processed data.

(14 Feb '14, 03:50) RuAnShi