Wireshark-dev: Re: [Wireshark-dev] Discerning Ethernet 802.3 vs Ethernet II (or TCP/IP)
From: Guy Harris <guy@xxxxxxxxxxxx>
Date: Mon, 29 Sep 2008 11:30:45 -0700

On Sep 29, 2008, at 10:15 AM, Pat Kujawa wrote:

We are currently working on a dissector which needs to address two different types of packets. One will be a simple ethernet packet with custom data. The other will be TCP/IP packets. Currently, our dissector (which was originally authored by another engineer) filters on the MAC address to determine whether or not it is one of our packets (this is probably not the best solution, but it was the quickest that the prior developer could come up with - other suggestions welcome). I am trying to find a way to tell whether the packet would have been treated as an ethernet 802.3 packet or an ethernet II packet (or some other TCP/IP identifier) in order to separate dissection of these two cases.

In reading through packet-eth.c, it seems that the ethernet type is being determined by checking a length field, but I don't understand where that field is coming from

It's coming from IEEE Std 802.3-2005, section 3.2.6:

	3.2.6 Length/Type field

This two-octet field takes one of two meanings, depending on its numeric value. For numerical evaluation,
the first octet is the most significant octet of this field.
a) If the value of this field is less than or equal to the value of maxValidFrame (as specified in 4.2.7.1), then the Length/Type field indicates the number of MAC client data octets contained in the subsequent data field of the frame (Length interpretation). b) If the value of this field is greater than or equal to 1536 decimal (equal to 0600 hexadecimal), then the Length/Type field indicates the nature of the MAC client protocol (Type interpretation). The Length and Type interpretations of this field are mutually exclusive.

When used as a Type field, it is the responsibility of the MAC client to ensure that the MAC client operates properly when the MAC sublayer pads the supplied data, as discussed in 3.2.7.

4.2.7.1 says

	addressSize = 48; {In bits, in compliance with 3.2.3}
	lengthOrTypeSize = 16; {In bits}

		...

	crcSize = 32; {In bits, 32-bit CRC}

		...

maxUntaggedFrameSize = ...; {In octets, implementation-dependent, see 4.4} maxValidFrame = maxUntaggedFrameSize – (2 x addressSize + lengthOrTypeSize + crcSize) / 8;


and 4.4 says that the "implementation-dependent" maxUntaggedFrameSize is 1518 octets for all implementations. That means that maxValidFrame is 1518 - (2 x 48 + 16 + 32)/8 = 1500.

Also, if there is a better way to dissect such that TCP/IP packets are treated differently (e.g. a new dissector) than the ethernet packets, please let me know.

A "simple Ethernet packet" can have a length field or a type field, so that's not sufficient to distinguish between "a simple Ethernet packet" and "[a] TCP/IP [packet]". (For that matter, in theory, a packet with a type field could carry an IP datagram and hence a TCP segment, although that doesn't happen in practice.)

It's also not *necessary*. For "a simple Ethernet packet" you presumably either have

1) an Ethernet type value for your protocol, in which case you would just register a dissector for the "simple Ethernet packet" with that type value and register a dissector for your TCP packets as a TCP dissector

or

2) a SNAP OUI and protocol ID, in which case you would register an OUI handler for the OUI, register a dissector for the "simple Ethernet packet" in that OUI handler's dissector table with the protocol ID in question, and register a dissector for your TCP packets as a TCP dissector.

If the two different types of packets are really that different, there should probably be two different dissectors for them.