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

How do I make a dissector handle a particular EtherType (Ethernet type field) value?

0

I have a custom packet that can be encapsulated in a TCP/IP or Ethernet protocol. The problem im having is adding my heuristic dissector in at the lowest level so the TCP/IP and Ethernet sections of the packets are decoded by their respective dissectors first before coming to my dissector.

If i use heur_dissector_add("eth",(heur_dissector_t) dissect_PROTONAME, proto_PROTONAME); it adds it in at the ethernet level but because the eth dissector tries all the heuristic dissectors first before it tries itself the destination and source MAC addresses aren't decoded. I've tried calling the "eth" dissector before my code runs but because of what i mentioned earlier it gets stuck in an infinite loop. I'd rather not have to decode the destination and source MAC addresses as this will cause my code to be unusable if the packet comes in wrapped in tcp/ip.

Is there any way to add my heuristic dissector in just before the "data dissector"?. I'm yet to find anything that lists all the different levels/types of heuristic dissectors....the only ones i've found are, "eth", "tcp", "udp" and a couple of others that haven't helped

thanks in advance for the help

asked 31 Jan '13, 14:46

StealthUE's gravatar image

StealthUE
667713
accept rate: 100%

edited 01 Feb '13, 17:18

Guy%20Harris's gravatar image

Guy Harris ♦♦
17.4k335196

Does your protocol have a specific Ethernet type value that you've either registered with the IEEE or are using despite that? If so, the right answer is not to use a heuristic dissector, but to register your dissector in the "ethertype" table using the Ethernet type value.

(31 Jan '13, 17:04) Guy Harris ♦♦

Cirrus Cobranet Packet. How would I go about registering the dissector in the "ethertype" table?. My protocol can come in as either an (1) ethernet packet->my protocol or (2) ethernet packet->ip packet->my protocol. Would registering it in the "ethertype" table cause my dissector to reject the second type?

(31 Jan '13, 17:23) StealthUE

"Ethernet II" isn't an Ethernet type value; I'm referring to EtherType values.

(31 Jan '13, 17:37) Guy Harris ♦♦

sorry my bad, i edited it but it must not have refreshed for you. Cirrus Cobranet Packet 0x8819

(31 Jan '13, 17:40) StealthUE

inside my protocol there is also another type thats consistently used, 0x8401 but it's not a registered ethertype value. Can you point me to an example that registers its own ethertype value??

(31 Jan '13, 17:49) StealthUE

One Answer:

5

OK, then to dissect packets with an EtherType of 0x8819 with your dissector, and have the Ethernet dissector dissect the destination address, source address, and EtherType/length field and hand your dissector the Ethernet payload (i.e., the tvbuff handed to your dissector starts with the first byte of the payload, not the first byte of the destination address, and it includes neither the destination address, the source address, or the EtherType/length field), what you would do is:

  • create a handle for your dissector;
  • call dissector_add_uint("ethertype", 0x8819, my_handle); in your dissector's handoff routine.

As for whatever Cobranet-over-IP encapsulation you're using (Cirrus Logic seems pretty insistent that they don't use IP):

  • if it runs over raw IP, if you have an IP protocol number assigned to it, you could register in the "ip.proto" dissector table with that protocol number value - your dissector wouldn't be heuristic, and registering it in both the "ethertype" and "ip.proto" tables will not cause any problems (it will be recognized in both cases);
  • if it runs over TCP or UDP, you would either register it with a fixed (or configurable) port number ("tcp.port" or "udp.port"), in which case it wouldn't be heuristic and, again, would not have a problem with the "ethertype" registration, or you would register a heuristic dissector for TCP or UDP, in which case you would need two separate dissector functions, a non-heuristic one used for EtherType 0x8819 and a heuristic one that checks whether the packet is a Cobranet packet and then calls the non-heuristic one if the packet is a Cobranet packet.

As for 0x8401, there's "registered" in the sense of "registered with the IEEE", which requires $2,825 US and possibly as much as 97 days (or more if they have questions), and there's "registered" in the sense of "registered in the "ethernet" table of Wireshark. Wireshark doesn't know, or care, whether you've registered an Ethernet type with the IEEE, although dissectors that register an EtherType value in the "ethertype" table when that EtherType value isn't "registered" with the IEEE might not be accepted into the official Wireshark source code base if submitted for inclusion. For that one, you'd make a call to dissector_add_uint() the same way you'd make a call for an EtherType officially registered with the IEEE.

answered 31 Jan '13, 17:59

Guy%20Harris's gravatar image

Guy Harris ♦♦
17.4k335196
accept rate: 19%

edited 31 Jan '13, 18:05

you sir are a genius!. thanks heaps. I'll give this a go :). Ive read almost every bit of documentation on dissecting packets in wireshark and have yet to come across this information. thanks again...saved me heaps of time

(31 Jan '13, 18:03) StealthUE

dissector_add_uint() is discussed in doc/README.developer, but it doesn't specifically mention the "ethertype" dissector table there.

(31 Jan '13, 18:07) Guy Harris ♦♦

hey, this is what i have so far. It's not picking up the packets...not sure why

/* packet-MYPROTOCOL.c
 * Routines for MYPROTOCOL dissection
 */

#ifdef HAVE_CONFIG_H

include "config.h"

#endif

#if 0 #include <stdio.h> #include <stdlib.h> #include <string.h> #endif

#include <epan/packet.h> #include <epan/prefs.h>

void proto_reg_handoff_MYPROTOCOL(void);

static int proto_MYPROTOCOL = -1; static int hf_MYPROTOCOL_data = -1;

static gboolean gPREF_HEX = FALSE;

static gint ett_MYPROTOCOL = -1;

static int dissect_MYPROTOCOL(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *MYPROTOCOL_tree;

if ( tvb_get_guint8(tvb,-2) != 0x84 )
    return (FALSE);
if ( tvb_get_guint8(tvb,-1) != 0x01 )
    return (FALSE);

col_set_str(pinfo-&gt;cinfo, COL_PROTOCOL, &quot;MYPROTOCOL&quot;);
col_set_str(pinfo-&gt;cinfo, COL_INFO, &quot;XXX Request&quot;);

if (tree) {
    ti = proto_tree_add_item(tree, proto_MYPROTOCOL, tvb, 0, -1, ENC_NA);

    MYPROTOCOL_tree = proto_item_add_subtree(ti, ett_MYPROTOCOL);

    proto_tree_add_item(MYPROTOCOL_tree, hf_MYPROTOCOL_data, tvb, 0, -1, ENC_NA);
}

}

void proto_register_MYPROTOCOL(void) { module_t *MYPROTOCOL_module;

static hf_register_info hf[] = {
    { &amp;hf_MYPROTOCOL_data,
        { &quot;MYPROTOCOL Data&quot;, &quot;MYPROTOCOL.data&quot;, FT_NONE, BASE_NONE, NULL, 0x0, &quot;MYPROTOCOL Data Collected&quot;, HFILL }
    }
};

static gint *ett[] = {
    &amp;ett_MYPROTOCOL
};

proto_MYPROTOCOL = proto_register_protocol(&quot;MYPROTOCOL&quot;, &quot;MYPROTOCOL&quot;, &quot;MYPROTOCOL&quot;);

proto_register_field_array(proto_MYPROTOCOL, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));

MYPROTOCOL_module = prefs_register_protocol(proto_MYPROTOCOL, proto_reg_handoff_MYPROTOCOL);

prefs_register_bool_preference(MYPROTOCOL_module, &quot;show_hex&quot;,
 &quot;Display numbers in Hex&quot;,
     &quot;Enable to display numerical values in hexadecimal.&quot;,
     &amp;gPREF_HEX);

}

void proto_reg_handoff_MYPROTOCOL(void) { static gboolean initialized = FALSE;

if (!initialized) {
    static dissector_handle_t MYPROTOCOL_handle;
    MYPROTOCOL_handle = create_dissector_handle((dissector_t)dissect_MYPROTOCOL, proto_MYPROTOCOL);
    dissector_add_uint(&quot;ethertype&quot;, 0x8401, MYPROTOCOL_handle);
}

}

This is what my packet looks like [Dest. MAC Addr][Source MAC Addr][Cobranet packet identifier][0x84][0x01][DATA to process]

any help is appreciated :)

(31 Jan ‘13, 19:18) StealthUE

hey Guy Harris, can you have a look at the code below and tell me what im doing wrong..thanks

(31 Jan ‘13, 19:27) StealthUE

i also tried changing the index values in tvb_get_guint8(tvb,INDEX) but it didnt change anything

(31 Jan ‘13, 19:32) StealthUE

This is what my packet looks like [Dest. MAC Addr][Source MAC Addr][Cobranet packet identifier][0x84][0x01][DATA to process]

If by “Cobranet packet identifier” you mean 0x8819, then that’s the EtherType of the packet, not 0x8401, and it’s not capturing the packets because you didn’t do

dissector_add_uint("ethertype", 0x8819, MYPROTOCOL_handle);

so that your dissector will be called for an EtherType of 0x8819.

(31 Jan ‘13, 20:30) Guy Harris ♦♦

ahhhhh, thanks man

(31 Jan ‘13, 20:35) StealthUE
showing 5 of 7 show 2 more comments