# Ignoring false bytes in tvb

I have a protocol that I am trying to create a dissector for and have run into a small problem. Originally this protocol was intended for serial buses but it seems someone created an IP driver (I do not have source for this). While 99% of the protocol is a simple 1 to 1 on top of TCP there is a small quirk that I cannot determine how to deal with.

If the transmission contains 0x10:0x10 then the underlying protocol just sent 0x10. If it was 0x10:0x10:0x10 then 0x10:0x10 was sent and so on. I have validated this behaviour against the checksum being transmitted but I cannot handle this in wireshark.

I create a new guint8 * array to hold the "corrected" data and I can easily place it in a tvb buffer with tvb_new_real_data but wireshark then looses the link between the decoded fields and the hex data. I also tried creating a child and recalling the dissector but still the link was lost since my array of data has no link to the original hex bytes found in tvb.

So my question is. How can I easily skip over the duplicate 0x10 with my dissector without loosing the link to the hex data (thing at the bottom of wireshark sorry I don't know the proper name)? I could place a check before every tvb_get command in my code but that sounds absolutely horrible and like there should be a better method.

Thanks for the help.

edit retag close merge delete

Sort by » oldest newest most voted

Sounds like byte stuffing where an escape character (in your case 0x10) has to be preceded by another escape character.

Most dissectors use a variable named "offset" to hold their current position in the tvb, incrementing it accordingly after each protocol field is handled. In your case when you detect the extra 0x10, simply increment offset by 1 and don't add anything to the tree. Subsequent tree additions will then use the "corrected" offset.

more

Yeah I have a field called offset and when I first found this I placed a check in the location I noticed the behaviour then exactly as you said went offset+=1.

The problem is, I have since learned this escape character can exist anywhere within the tvb passed from the TCP dissector. As such before every field grab, (which includes 32bit numbers and strings), I would have to scan that region and skip over duplicates. This becomes especially difficult in the case where I have a IEEE 32bit float passed as. 0x00: 0x10: 0x10: 0x80: 0x34. The second 0x10 here should not exist and obviously creates bad data. Since it's in the middle of my float I cannot simple increment offset (at least using the proto_tree_add_item function that I have been working with based on README.Dissector).

( 2018-07-27 13:54:25 +0000 )edit

Ok, in that case you have to un-byte stuff the whole tvb to create a new tvb and then pass that into the actual dissector function. Imagine the un-byte stuffing as another layer in the protocol stack so you have

...
tcp
byte stuffed data
un-byte stuffed data


Where the byte-stuffed data layer produces the new tvb with the byte stuffing removed, so when you select the un-byte stuffed part of the protocol tree the hex bytes will only show the un-byte stuffed data as it's a new tvb.

I don't think you can have dissection of the byte-stuffed data because of the issues you mention.

( 2018-07-27 14:46:20 +0000 )edit

Ok I think I follow that but just a quick question on implementing that. At one point I tried to grab the un-byte stuffed data within my dissect function and place that in a new tvb with tvb_new_real_data. Then I used call_dissector_with_data and passed it the new tvb I had created. Now at the time to save effort I simply called the same dissector I already had registered instead of creating a byte stuffed dissector just to hand off to the un-byte stuffed dissector.

Are you saying that if I create 2 dissectors this will work where I do the following. Register 2 protocols within proto_register and create 2 dissectors in my reg_handoff? First I hand the TCP tvb to byte stuffed tvb via the reg_handoff function. In there I create a tvb of the un-byte stuffed data. Also here I would like to ask, how specifically should I be ...(more)

( 2018-07-27 15:30:11 +0000 )edit

I've had to do something similar for DNP3 where the data link layer adds a 16 bit CRC for every 16 bytes of application data. The data link layer function removes those CRC's (after checking them) and creates a new tvb to hand to the application layer function. Both functions are in the same dissector file.

I would expect you to do something similar, at some point you would need to call the un-stuff function and that would either return the new tvb to be dissected in subsequent code, or it could directly call the function to dissect the tvb contents. Which arrangement you use is up to you.

( 2018-07-27 15:47:10 +0000 )edit

AH I GOT IT! THANK YOU FOR THE HELP!

My original idea to create a second tvb was correct I was just missing one small step (I would prefer to give you credit for the answer though so I'll just paste what I ended up doing).

new_data_len = bsap_duplicate_removal(tvb, &new_data);

trimmed_tvb = tvb_new_real_data(new_data, new_data_len, new_data_len);

tvb_set_child_real_data_tvbuff(tvb, trimmed_tvb);

tvb = trimmed_tvb;

By adding the next to last command I injected the created tvb into the hex debugger section. I did not realize there was a separate command for this I assumed the tvb was handling that somewhere. Thanks again (funnily enough I've been using the DNP3 dissector as reference for a lot of what I've been working on).

( 2018-07-27 15:55:38 +0000 )edit