Ask Your Question
0

Debugging Dissector Read and Dissector Handoff Issue

asked 2020-07-14 15:06:45 +0000

dmanderson gravatar image

updated 2020-07-29 13:46:06 +0000

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:

  1. 2 bit version number -
  2. 1 bit bypass flag
  3. 1 bit command flag
  4. 2 bit spare field
  5. 10 bit spacecraft_id field
  6. 6 bit virtual_channel_id field
  7. 10 bit length field
  8. 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:

  1. A 2 bit sequence flag field
  2. 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 ...
(more)
edit retag flag offensive close merge delete

Comments

I wonder why don't people use [email protected] anymore.

Jaap gravatar imageJaap ( 2020-07-14 16:27:20 +0000 )edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2020-07-15 14:28:05 +0000

Pascal Quantin gravatar image

Hi,

1/ please clarify your current output and what you would like to have

2/ FT_BOOLEAN should use TFS(), not VALS(). See doc/README.dissector

3/ there is no dissector named "eth", thus the assert. As seen in epan/dissectors/packet-eth.c, you have "eth_withoutfcs", "eth_withfcs" and "eth_maybefcs"

edit flag offensive delete link more

Comments

Thank you for your reply. I'll address your suggestions in the same order.

1: Currently, omitting some details due to irrelevance, my dissection window looks something like this:Note that > denotes an unexpanded tree or subtree while V denotes one that has been expanded.

>Frame 1
V TC_Subset
   >TC_Subset
   >TC_Subset
>Ethernet II
>Data

I would like the output to look like this.

>Frame 1
V TC_Subset
   >Primary Header
   >Segment Header
>Ethernet II
>IPv4

2: That fixed the issue. Thank you for pointing me at the correct documentation.

3: I've tried withoutfcs and maybefcs. They lead to correct dissection of the ethernet packet, including the ethertype indicating that IPv4 follows the ethernet header. However, there's no dissection of that Ipv4 afterwards. I tried adding a second call to call_dissector but that didn't work either. I updated the offset but it still doesn't dissect the IPv4 ...(more)

dmanderson gravatar imagedmanderson ( 2020-07-15 15:23:12 +0000 )edit

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.

Only if the Ethernet header has, in the type/length field, a value of 0x0800.

What follows the Ethernet header is either:

  • indicated by the value of the type/length field, if the type/length field value is >= 1536 - a value of 0x0800, for example, means IPv4;
  • an old-fashioned Netware frame, if the type/length field value is <= 1500 and the first two octets of the payload are 0xFFFF;
  • an 802.2 LLC header, if the type/length field value is <= 1500 and the first two octets of the payload are not 0xFFFF.

What is the value in the type/length field ...(more)

Guy Harris gravatar imageGuy Harris ( 2020-07-15 22:50:48 +0000 )edit

3: I've tried withoutfcs and maybefcs. They lead to correct dissection of the ethernet packet, including the ethertype indicating that IPv4 follows the ethernet header.

What is the value in the type/length field of the Ethernet header?

Ethertype is always 0x0800 and it is fully known that the order of headers I gave is always that. The dissector currently successfully reads that ethertype as 0x0800 and recognizes that as indicating IPv4.

I think there may be a problem with parsing the IPv4, but I'm not sure what. Examining the IPv4 packet with Scapy gave me (just showing the IP part and what comes immediately after)

###[ IP ]###
version = 4L
ihl = 5L
tos = 0x0
len = 61
id = 1
flags = 
frag = 0L
ttl = 64
proto = tcp
chksum = 0x63b8
src = 10.0.1.1
dst = 10.0.2.2
\options  \
###[ TCP ] ###
<tcp details>

which looks very similar to example IPv4 packets ...(more)

dmanderson gravatar imagedmanderson ( 2020-07-16 13:33:41 +0000 )edit

So what does the IP dissection look like, totally failed or partial?

grahamb gravatar imagegrahamb ( 2020-07-17 17:09:32 +0000 )edit

@grahamb

Completely failed - it just says "Data" and just lists the entire rest of the packet's bytes with no formatting in a giant run-on single line.

I even tried changing the packet formation and the generator code such that there is no ethernet header and I can directly hand off to IP instead of going through the ethernet dissector just as a check, and same result.

dmanderson gravatar imagedmanderson ( 2020-07-17 17:18:31 +0000 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2020-07-14 15:06:45 +0000

Seen: 556 times

Last updated: Jul 29 '20