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

tcp_dissect_pdus doesn’t work well - TCP segment of a reassembled PDU

0

Hey, I'm wrote a wireshark dissector named PLUGIN.

Now when I'm testing it, for some reason a packet of type X can be seen on the wireshark as PLUGIN (like it should), and some other packets afterwards, of the same type X cannot be seen as PLUGIN.

The other packets can be found in the .pcap as [TCP segment of a reassembled PDU]

The question is: why doesn't WireShark dissect other packets of type X like the first packet of type X and shows it to me as PLUGIN ?

Why does the dissection works only for the first time?

I use functions for assembling fragments of chopped packets:

tcp_dissect_pdus()
get_PLUGIN_message_len()

as written in "9.4.2. How to reassemble split TCP Packets"

in "http://www.wireshark.org/docs/wsdg_html_chunked/ChDissectReassemble.html#TcpDissectPdus"

This is the function of dissection: (FRAME_HEADER_LEN = 8)

static void
dissect_PROTOC(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    //Reassembling TCP fragments
    tcp_dissect_pdus(tvb, pinfo, tree, TRUE, FRAME_HEADER_LEN,
                     get_PROTOC_message_len, dissect_PROTOC_message);

}

static guint get_PROTOC_message_len(packet_info *pinfo, tvbuff_t tvb, int offset) { / the packet's size is "length" + 4bytes of TYPESIZE + 4bytes of LENGTHSIZE + 256bytes of CONTEXTIDSIZE / return (guint)(tvb_get_ntohl(tvb, offset + 4) + CONTEXT_ID_SIZE + TYPE_SIZE + LENGTH_SIZE); / e.g. length is at offset 4 */ }

static void dissect_PROTOC_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree tree) { / my dissecting code */ guint32 packet_type = tvb_get_ntohl(tvb, 0);

col_set_str(pinfo->cinfo, COL_PROTOCOL, "PROTOC");
/* Clear out stuff in the info column */
col_clear(pinfo->cinfo,COL_INFO);
col_add_fstr(pinfo->cinfo, COL_INFO, "%d > %d [%s]",pinfo->srcport, pinfo->destport,
         val_to_str(packet_type, packettypenames, "Unknown (0x%02x)"));

if (tree) { /* we are being asked for details */
    proto_item *ti              = NULL;
    proto_tree *PROTOC_tree         = NULL;
    proto_item *PROTOC_data         = NULL;
    proto_tree *PROTOC_data_tree    = NULL;
    guint32 type    = 0;
    guint32 length  = 0;
    gint offset     = 0;

    ti = proto_tree_add_item(tree, proto_PROTOC, tvb, 0, -1, ENC_NA);
    proto_item_append_text(ti, ", Type: %s",
        val_to_str(packet_type, packettypenames, "Unknown (0x%02x)"));
    PROTOC_tree = proto_item_add_subtree(ti, ett_PROTOC);

    //getting type
    type = tvb_get_ntohl(tvb, offset);
    proto_tree_add_item(PROTOC_tree, hf_PROTOC_pdu_type, tvb, 0, TYPE_SIZE, ENC_BIG_ENDIAN);
    offset += TYPE_SIZE;

    //getting length for the data length
    length = tvb_get_ntohl(tvb, offset);
    proto_tree_add_item(PROTOC_tree, hf_PROTOC_len, tvb, offset, LENGTH_SIZE, ENC_BIG_ENDIAN);
    offset += LENGTH_SIZE;
    proto_tree_add_item(PROTOC_tree, hf_PROTOC_contextid, tvb, offset, CONTEXT_ID_SIZE, ENC_BIG_ENDIAN);
    offset += CONTEXT_ID_SIZE;
    PROTOC_data = proto_tree_add_item(PROTOC_tree, hf_PROTOC_data, tvb, offset, length, FALSE);
    PROTOC_data_tree = proto_item_add_subtree(PROTOC_data, ett_PROTOC_data);
    offset += length;

}

}

edited: more information:

more information:

  1. I opened the file.pcap on some hex editor and I can see my packets that the wireshark doesn’t dissect…

  2. Inside wireshark I can find a packet that wireshark doesn’t dissect, with the info of: “[TCP segment of a reassembled PDU]”, but it doesn’t say to which reassemble packet it belong, and I can’t find it anywhere…

Thanks

asked 30 Jan ‘13, 01:14

hudac's gravatar image

hudac
61111317
accept rate: 50%

edited 25 Feb ‘13, 02:07


2 Answers:

1

If the function get_acp_message_len() results in a value that is greater than the actual length of the next PLUGIN PDU, then tcp_dissect_pdus() will tell the TCP dissector to look for more data than is necessary and therefor the TCP dissector will show [TCP segment of a reassembled PDU], instead of handing over the data to your dissector for dissection as PLUGIN.

answered 30 Jan '13, 01:23

SYN-bit's gravatar image

SYN-bit ♦♦
17.1k957245
accept rate: 20%

thanks,

  1. what is PDU ?

  2. But how can it be that for the first time it succeed dissecting, and later on it cannot dissect any of them ?

(30 Jan '13, 01:35) hudac
1

A PDU is a Protocol Data Unit. One well-defined message from protocol PLUGIN in your case. If that PDU is segmented by TCP, it can span multiple TCP segments (and therefor multiple frames). The function tcp_dissect_pdus() is used to reassemble your PDU. But it does this by handing it a function that can determine the length of your PDU within the first X bytes of the data. Does your protocol work like that? Is there a length value somewhere in the first bytes of each PDU? If not, you can not use tcp_dissect_pdus().

(30 Jan '13, 02:04) SYN-bit ♦♦

Without looking at the trace and dissector it is really hard to tell you why it does not work... unless one has a crystal ball of course ;-)

(30 Jan '13, 02:05) SYN-bit ♦♦

Yeah I understand it hard.. It even hard while it in front of my eyes... Let me know what information you need and I'll post it here..

Thanks!!

And Yes, That's how my protocol works, There is a length value in the first bytes of each PDU, and I already use the tcp_dissect_pdus()...

For the first packet it works, and then it doesn't

(30 Jan '13, 04:19) hudac

Posting your dissector source somewhere would be handy.

(30 Jan '13, 06:00) grahamb ♦

everything? that's a lot, isn't it ? I can post the main things I guess

(30 Jan '13, 07:19) hudac

@grahamb, @SYN-bit, I added some code if you can check it out.. Thanks!

(15 Feb '13, 04:25) hudac

You might want to check the length function and print some debug info and then dissect the packet yourself to see whether your code is actually telling TCP to collect just the right amount of data. It looks like it tries to collect more data than is in the packets...

(25 Feb '13, 06:37) SYN-bit ♦♦

Thanks @SYN-bit, what do you mean "dissect the packet yourself" ?

How can I do that ?

I already printed the length of each packet... The problem is that for packets which it dissect, it prints the length, and the desired packets which it doesn't dissect, it don't print anything (cause it doesn't use my code to dissect it...)

(25 Feb '13, 07:35) hudac
1

Well, by "dissect the packet yourself" I mean that you look at the packet data and calculate the lengths yourself (according to the protocol specification) and then check whether your code calculates the same length. You can disable reassembly in the TCP protocol preferences to make things easier for you. You can print the lengths that your code calculates from within the "get_PROTOC_message_len()" function, which should be called, even for the message that never reaches "dissect_PROTOC_message()".

(25 Feb '13, 07:43) SYN-bit ♦♦

@SYN-bit,

  1. I tried it, but "get_PROTOC_message_len()" prints it's value only on messages of my protocol, so I don't know how to check it...

  2. I tried disabling reassembly in the TCP preferences but I'm not sure how it my help me

  3. In the TCP preferences I checked "Validate the TCP checksum if possible.", suddenly I see ALL of my messages, even the ones that I didn't see before, but all of them have the error "Bad Checksum: True", Can this information help me understand what is the problem ?

Thanks!

(26 Feb '13, 22:54) hudac
1

I tried it, but "get_PROTOC_message_len()" prints it's value only on messages of my protocol, so I don't know how to check it...

Look at the raw hex data of the packets and interpret them yourself by hand, without any code, whether it's existing Wireshark code or code in your dissector. That's what SYN-bit meant by "dissect the packet yourself" - do, by hand, what the Wireshark dissectors would be expected to do.

(27 Feb '13, 00:33) Guy Harris ♦♦
1

In the TCP preferences I checked "Validate the TCP checksum if possible.", suddenly I see ALL of my messages, even the ones that I didn't see before, but all of them have the error "Bad Checksum: True"

That probably means that the packets are being transmitted by your machine and that your machine's network adapter is doing TCP checksum offloading, so that, when Wireshark captures the packet, the TCP checksum hasn't been calculated and would appear to be incorrect. Wireshark doesn't do TCP reassembly if a packet is found to have a bad checksum, so that's like disabling TCP reassembly.

(27 Feb '13, 00:35) Guy Harris ♦♦

Thanks,

I dissected the .pcap myself and I saw the messages of my protocol that I can't see in the wireshark... They exist...

Isn't the "checksum" thing is my problem?

Because the checksum hasn't been calculated and would appear to be incorrect, Wireshark doesn't do TCP reassembly. So I can't see my messages on wireshark ?

What should I do in order to see them?

(27 Feb '13, 01:03) hudac

By the way, I record the .pcap on the loopback... there should not be any problem of checksum, - I think it offloaded anyway...

When I check "Validate the TCP checksum if possible.", I can see the frame dissected with my protocol,

when I uncheck "Validate the TCP checksum if possible.", the frame isn't dissected as my protocol, and his type is TCP, and [TCP segment of a reassembled PDU]

(27 Feb '13, 02:40) hudac
1

OK, when there is TCP checksum offloading, all ougoing packets will have the wrong TCP checksum. If you do validate the checksums, then wireshark will see a bad checksum and disable reassembly (no use in reassembling data that is corrupt).

So in your case, your dissector does get called and when reassembly is turned off by the bad checksums, your code just gets the first part of the PDU delivered and will dissect it, even though it might not be a full PDU.

When reassembly is being done (because you disable checksum validation), your dissector tells TCP to collect more data (hence the "[TCP segment of a reassembled PDU]" info line), but your dissector probably tells TCP to collect more data than there is in the PDU, so dissection never takes place.

Again, please check whether your dissector code calculates the correct length for your PDU (by hand). We can help you there, but then you would have to provide the capture file (see www.cloudshark.org).

(27 Feb '13, 02:56) SYN-bit ♦♦
1

By the way, I record the .pcap on the loopback... there should not be any problem of checksum, - I think it offloaded anyway...

On at least some UN*Xes, the loopback interface driver indicates that it supports checksum generation and checking offloading, and then never bothers to compute the checksum when "transmitting" and never bothers to check it when "receiving", just reporting "checksum OK" to the networking stack, because there's not much point in actually checksumming packets. That means that when a sniffer captures the packets, they will appear to have an invalid checksum.

(27 Feb '13, 10:18) Guy Harris ♦♦

@SYN-bit , I uploaded the .pcap to "[http://www.cloudshark.org/captures/fdbbf1feedda]" Thanks...

The packet that is being dissected: 1, 3 The packet that is not being dissected: 6312

Another thing I payed attention to: When I diluted the .pcap to be shorter, and put only these both packets (the one that can be dissected, and the one that is not being dissected), it dissected them both...

Thanks alot, please tell me if you need anything else

I checked if it calculates the length and I think it's ok...

(27 Feb '13, 23:13) hudac

@SYN-bit , @Guy Harris , Can I upload to you some small dissection code somewhere ?

(01 Mar '13, 13:46) hudac

@SYN-bit , @Guy Harris ?

(17 Mar '13, 06:07) hudac
showing 5 of 20 show 15 more comments

0

Are there any missing TCP packets in your capture? Wireshark cannot reassemble a PDU for a protocol running atop TCP if some of the TCP packets in the middle of, or at the end of, the PDU are missing.

answered 25 Feb '13, 00:51

Guy%20Harris's gravatar image

Guy Harris ♦♦
17.4k335196
accept rate: 19%

How can I know if there are any missing TCP packets? I don't think there are any missing TCP packets..

more information:

  1. I opened the file.pcap on some hex editor and I can see my packets that the wireshark doesn't dissect...

  2. Inside wireshark I can find a packet that wireshark doesn't dissect, with the info of: "[TCP segment of a reassembled PDU]", but it doesn't say to which reassemble packet it belong, and I can't find it anywhere...

(25 Feb '13, 02:07) hudac

Look at the sequence numbers for each of the packets in each direction. If packet N in one direction has a "next sequence number" of X, and the next packet in that direction has a "next sequence number" of Y and Y > X, and there's no later packet that contains bytes with sequence numbers from X to Y, then there's a missing packet (perhaps present on the network but not captured, perhaps not even present on the network). If there is such a packet later, the packets were delivered out of order; Wireshark might not handle that correctly.

(25 Feb '13, 03:06) Guy Harris ♦♦

"and there's no later packet that contains bytes with sequence numbers from X to Y", Do you mean by that, that there is no reassembled packet after couple of "[TCP segment of a reassembled PDU]"?

As I said in "2." , I can see a packet of "[TCP segment of a reassembled PDU]", that it's value of "TCP segment data" is exactly my desired packet, but somehow there is no reassembled packet after it, and wireshark doesn't dissect it as my message :/

(25 Feb '13, 06:10) hudac