Wireshark-dev: Re: [Wireshark-dev] Discerning Ethernet 802.3 vs Ethernet II (or TCP/IP)
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.