Debugging Dissector Read and Dissector Handoff Issue
EDIT: As problems have been solved, I've reduced the amount of code shown to make it easier to pinpoint potential issues. Thanks to Pascal Quentin, Guy Harris, and grahamb for all their help so far.
Background:
I've written a dissector for reading a protocol called TC. The subset of this I'm implementing has two headers - a primary header and a segment header. The primary header is 40 bits long, and the segment header is 8 bits long. I will get into more detail as to how the headers are broken down shortly. After parsing the segment header, my intent is to pass the remainder of the packet into the standard ethernet dissector. This means that the protocol is a link layer protocol. The order of headers is as follows: Primary Header, Segment Header, Ethernet Header, IPv4 header. I've configured this protocol to take WTAP_ENCAP_USER10 and have a pcap configured to meet that type that contains two packets meeting its criteria.
The display in wireshark recognizes the protocol and mostly has the correct breakdown of the fields, but with some errors in reading and has a problem handing off to ethernet. For the rest of this question, I'll provide a breakdown of the fields of the two headers and how I've approached dissection+handoff, then talk about the result and what's wrong.
Detail of Protocol: Primary header
The primary header is comprised of eight fields in the following order:
- 2 bit version number -
- 1 bit bypass flag
- 1 bit command flag
- 2 bit spare field
- 10 bit spacecraft_id field
- 6 bit virtual_channel_id field
- 10 bit length field
- 8 bit sequence number field
Items 2,3,5, and 6 all have value_string mappings for values to semantic values.
Detail of Protocol: Segment header
The segment header only has two fields, in the following order:
- A 2 bit sequence flag field
- A 6 bit map_id field - I'll call this map for short.
"dissect_tc" Method
FIrst, I'll show some of the dissect_tc method.
static int
dissect_tc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
//I ASSUME OFFSET IS IN OCTETS
int offset = 0;
proto_item *tc_packet;
proto_tree *tc_tree = NULL;
proto_item *primary_header = NULL;
proto_tree *primary_header_tree;
proto_item *segment_header = NULL;
proto_tree *segment_header_tree;
guint32 first_word;
guint16 second_word;
gint tc_length;
gint length = 0;
gint reported_length;
...
/* Note - both headers together are 48 bits, so I split the amount I need to process
into two words - the first 32, and the second 16. This means that the second word
actually runs across both headers - it includes the sequence number of
the primary header and the entirety of the segment header. */
first_word = tvb_get_guint32(tvb, 0, ENC_BIG_ENDIAN);
second_word = tvb_get_guint16(tvb, 4, ENC_BIG_ENDIAN);
...(set length correctly)
tc_packet = proto_tree_add_item(tree, proto_tc_subset, tvb, 0, length, ENC_BIG_ENDIAN);
tc_tree = proto_item_add_subtree(tc_packet, ett_tc);
/* build the tc primary header tree */
primary_header = proto_tree_add_item(tc_tree, proto_tc_subset, tvb, offset, TC_PRIMARY_HEADER_LENGTH, ENC_NA);
primary_header_tree = proto_item_add_subtree(primary_header, ett_tc_primary_header);
proto_tree_add_uint(primary_header_tree, hf_tc_version_number, tvb, offset, 2, first_word);
//Continue adding items in a similar manner, updating offset as needed until ...
I wonder why don't people use [email protected] anymore.