2 * Copyright (c) 2014 VMware, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #define __ETHERNET_H_ 1
20 #define ETH_LADRF_LEN 2
21 #define ETH_ADDR_LENGTH 6
23 typedef UINT8 Eth_Address[ETH_ADDR_LENGTH];
25 #define ETH_ADDR_FMT_STR "%02x:%02x:%02x:%02x:%02x:%02x"
26 #define ETH_ADDR_FMT_ARGS(a) ((UINT8 *)a)[0], ((UINT8 *)a)[1], ((UINT8 *)a)[2], \
27 ((UINT8 *)a)[3], ((UINT8 *)a)[4], ((UINT8 *)a)[5]
29 #define ETH_MAX_EXACT_MULTICAST_ADDRS 32
31 typedef enum Eth_RxMode {
32 ETH_FILTER_UNICAST = 0x0001, /* pass unicast (directed) frames */
33 ETH_FILTER_MULTICAST = 0x0002, /* pass some multicast frames */
34 ETH_FILTER_ALLMULTI = 0x0004, /* pass *all* multicast frames */
35 ETH_FILTER_BROADCAST = 0x0008, /* pass broadcast frames */
36 ETH_FILTER_PROMISC = 0x0010, /* pass all frames (ie no filter) */
37 ETH_FILTER_USE_LADRF = 0x0020, /* use the LADRF for multicast filtering */
38 ETH_FILTER_SINK = 0x10000 /* pass not-matched unicast frames */
41 /* filter flags printf helpers */
42 #define ETH_FILTER_FLAG_FMT_STR "%s%s%s%s%s%s%s"
43 #define ETH_FILTER_FLAG_FMT_ARGS(f) (f) & ETH_FILTER_UNICAST ? " UNICAST" : "", \
44 (f) & ETH_FILTER_MULTICAST ? " MULTICAST" : "", \
45 (f) & ETH_FILTER_ALLMULTI ? " ALLMULTI" : "", \
46 (f) & ETH_FILTER_BROADCAST ? " BROADCAST" : "", \
47 (f) & ETH_FILTER_PROMISC ? " PROMISC" : "", \
48 (f) & ETH_FILTER_USE_LADRF ? " USE_LADRF" : "", \
49 (f) & ETH_FILTER_SINK ? " SINK" : ""
51 /* Ethernet header type */
54 ETH_HEADER_TYPE_802_1PQ,
55 ETH_HEADER_TYPE_802_3,
56 ETH_HEADER_TYPE_802_1PQ_802_3,
59 /* DIX type fields we care about */
61 ETH_TYPE_IPV4 = 0x0800,
62 ETH_TYPE_IPV6 = 0x86DD,
63 ETH_TYPE_ARP = 0x0806,
64 ETH_TYPE_RARP = 0x8035,
65 ETH_TYPE_LLDP = 0x88CC,
66 ETH_TYPE_CDP = 0x2000,
67 ETH_TYPE_802_1PQ = 0x8100, // not really a DIX type, but used as such
68 ETH_TYPE_LLC = 0xFFFF, // 0xFFFF is IANA reserved, used to mark LLC
69 ETH_TYPE_MPLS = 0x8847,
70 ETH_TYPE_MPLS_MCAST = 0x8848,
74 ETH_TYPE_IPV4_NBO = 0x0008,
75 ETH_TYPE_IPV6_NBO = 0xDD86,
76 ETH_TYPE_ARP_NBO = 0x0608,
77 ETH_TYPE_RARP_NBO = 0x3580,
78 ETH_TYPE_LLDP_NBO = 0xCC88,
79 ETH_TYPE_CDP_NBO = 0x0020,
80 ETH_TYPE_AKIMBI_NBO = 0xDE88,
81 ETH_TYPE_802_1PQ_NBO = 0x0081, // not really a DIX type, but used as such
84 /* low two bits of the LLC control byte */
86 ETH_LLC_CONTROL_IFRAME = 0x0, // both 0x0 and 0x2, only low bit of 0 needed
87 ETH_LLC_CONTROL_SFRAME = 0x1,
88 ETH_LLC_CONTROL_UFRAME = 0x3,
91 #define ETH_LLC_CONTROL_UFRAME_MASK (0x3)
93 typedef struct Eth_DIX {
94 UINT16 typeNBO; // indicates the higher level protocol
98 * LLC header come in two varieties: 8 bit control and 16 bit control.
99 * when the lower two bits of the first byte's control are '11', this
100 * indicated the 8 bit control field.
102 typedef struct Eth_LLC8 {
108 typedef struct Eth_LLC16 {
114 typedef struct Eth_SNAP {
119 typedef struct Eth_802_3 {
120 UINT16 lenNBO; // length of the frame
121 Eth_LLC8 llc; // LLC header
122 Eth_SNAP snap; // SNAP header
125 // 802.1p QOS/priority tags
127 ETH_802_1_P_BEST_EFFORT = 0,
128 ETH_802_1_P_BACKGROUND = 1,
129 ETH_802_1_P_EXCELLENT_EFFORT = 2,
130 ETH_802_1_P_CRITICAL_APPS = 3,
131 ETH_802_1_P_VIDEO = 4,
132 ETH_802_1_P_VOICE = 5,
133 ETH_802_1_P_INTERNETWORK_CONROL = 6,
134 ETH_802_1_P_NETWORK_CONTROL = 7
137 typedef struct Eth_802_1pq_Tag {
138 UINT16 typeNBO; // always ETH_TYPE_802_1PQ
139 UINT16 vidHi:4, // 802.1q vlan ID high nibble
140 canonical:1, // bit order? (should always be 0)
141 priority:3, // 802.1p priority tag
142 vidLo:8; // 802.1q vlan ID low byte
145 typedef struct Eth_802_1pq {
146 Eth_802_1pq_Tag tag; // VLAN/QOS tag
148 Eth_DIX dix; // DIX header follows
149 Eth_802_3 e802_3; // or 802.3 header follows
153 typedef struct Eth_Header {
154 Eth_Address dst; // all types of ethernet frame have dst first
155 Eth_Address src; // and the src next (at least all the ones we'll see)
157 Eth_DIX dix; // followed by a DIX header...
158 Eth_802_3 e802_3; // ...or an 802.3 header
159 Eth_802_1pq e802_1pq; // ...or an 802.1[pq] tag and a header
163 #define ETH_BROADCAST_ADDRESS { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
165 static Eth_Address netEthBroadcastAddr = ETH_BROADCAST_ADDRESS;
168 * simple predicate for 1536 boundary.
169 * the parameter is a network ordered UINT16, which is compared to 0x06,
170 * testing for "length" values greater than or equal to 0x0600 (1536)
173 #define ETH_TYPENOT8023(x) (((x) & 0xff) >= 0x06)
176 * header length macros
178 * first two are typical: ETH_HEADER_LEN_DIX, ETH_HEADER_LEN_802_1PQ
179 * last two are suspicious, due to 802.3 incompleteness
182 #define ETH_HEADER_LEN_DIX (sizeof(Eth_Address) + \
183 sizeof(Eth_Address) + \
185 #define ETH_HEADER_LEN_802_1PQ (sizeof(Eth_Address) + \
186 sizeof(Eth_Address) + \
187 sizeof(Eth_802_1pq_Tag) + \
189 #define ETH_HEADER_LEN_802_2_LLC (sizeof(Eth_Address) + \
190 sizeof(Eth_Address) + \
193 #define ETH_HEADER_LEN_802_2_LLC16 (sizeof(Eth_Address) + \
194 sizeof(Eth_Address) + \
197 #define ETH_HEADER_LEN_802_3 (sizeof(Eth_Address) + \
198 sizeof(Eth_Address) + \
200 #define ETH_HEADER_LEN_802_1PQ_LLC (sizeof(Eth_Address) + \
201 sizeof(Eth_Address) + \
202 sizeof(Eth_802_1pq_Tag) + \
205 #define ETH_HEADER_LEN_802_1PQ_LLC16 (sizeof(Eth_Address) + \
206 sizeof(Eth_Address) + \
207 sizeof(Eth_802_1pq_Tag) + \
210 #define ETH_HEADER_LEN_802_1PQ_802_3 (sizeof(Eth_Address) + \
211 sizeof(Eth_Address) + \
212 sizeof(Eth_802_1pq_Tag) + \
215 #define ETH_MIN_HEADER_LEN (ETH_HEADER_LEN_DIX)
216 #define ETH_MAX_HEADER_LEN (ETH_HEADER_LEN_802_1PQ_802_3)
218 #define ETH_MIN_FRAME_LEN 60
219 #define ETH_MAX_STD_MTU 1500
220 #define ETH_MAX_STD_FRAMELEN (ETH_MAX_STD_MTU + ETH_MAX_HEADER_LEN)
221 #define ETH_MAX_JUMBO_MTU 9000
222 #define ETH_MAX_JUMBO_FRAMELEN (ETH_MAX_JUMBO_MTU + ETH_MAX_HEADER_LEN)
224 #define ETH_DEFAULT_MTU 1500
226 #define ETH_FCS_LEN 4
227 #define ETH_VLAN_LEN sizeof(Eth_802_1pq_Tag)
231 *----------------------------------------------------------------------------
232 * Do the two ethernet addresses match?
233 *----------------------------------------------------------------------------
235 static __inline BOOLEAN
236 Eth_IsAddrMatch(const Eth_Address addr1, const Eth_Address addr2)
238 return !memcmp(addr1, addr2, ETH_ADDR_LENGTH);
243 *----------------------------------------------------------------------------
244 * Is the address the broadcast address?
245 *----------------------------------------------------------------------------
247 static __inline BOOLEAN
248 Eth_IsBroadcastAddr(const Eth_Address addr)
250 return Eth_IsAddrMatch(addr, netEthBroadcastAddr);
255 *----------------------------------------------------------------------------
256 * Is the address a unicast address?
257 *----------------------------------------------------------------------------
259 static __inline BOOLEAN
260 Eth_IsUnicastAddr(const Eth_Address addr)
262 // broadcast and multicast frames always have the low bit set in byte 0
263 return !(((CHAR *)addr)[0] & 0x1);
267 *----------------------------------------------------------------------------
268 * Is the address the all-zeros address?
269 *----------------------------------------------------------------------------
271 static __inline BOOLEAN
272 Eth_IsNullAddr(const Eth_Address addr)
274 return ((addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]) == 0);
278 *----------------------------------------------------------------------------
281 * return an Eth_HdrType depending on the eth header
282 * contents. will not work in all cases, especially since it
283 * requres ETH_HEADER_LEN_802_1PQ bytes to determine the type
285 * HeaderType isn't sufficient to determine the length of
286 * the eth header. for 802.3 header, its not clear without
287 * examination, whether a SNAP is included
291 * ETH_HEADER_TYPE_DIX: typical 14 byte eth header
292 * ETH_HEADER_TYPE_802_1PQ: DIX+vlan tagging
293 * ETH_HEADER_TYPE_802_3: 802.3 eth header
294 * ETH_HEADER_TYPE_802_1PQ_802_3: 802.3 + vlan tag
296 * the test for DIX was moved from a 1500 boundary to a 1536
297 * boundary, since the vmxnet2 MTU was updated to 1514. when
298 * W2K8 attempted to send LLC frames, these were interpreted
299 * as DIX frames instead of the correct 802.3 type
301 * these links may help if they're valid:
303 * http://standards.ieee.org/regauth/ethertype/type-tut.html
304 * http://standards.ieee.org/regauth/ethertype/type-pub.html
309 *----------------------------------------------------------------------------
311 static __inline Eth_HdrType
312 Eth_HeaderType(const Eth_Header *eh)
315 * we use 1536 (IEEE 802.3-std mentions 1536, but iana indicates
316 * type of 0-0x5dc are 802.3) instead of some #def symbol to prevent
317 * inadvertant reuse of the same macro for buffer size decls.
319 if (ETH_TYPENOT8023(eh->dix.typeNBO)) {
320 if (eh->dix.typeNBO != ETH_TYPE_802_1PQ_NBO) {
322 return ETH_HEADER_TYPE_DIX;
325 /* some type of 802.1pq tagged frame */
326 if (ETH_TYPENOT8023(eh->e802_1pq.dix.typeNBO)) {
327 /* vlan tagging with dix style type */
328 return ETH_HEADER_TYPE_802_1PQ;
331 /* vlan tagging with 802.3 header */
332 return ETH_HEADER_TYPE_802_1PQ_802_3;
336 return ETH_HEADER_TYPE_802_3;
341 *----------------------------------------------------------------------------
343 * Eth_EncapsulatedPktType --
344 * Get the encapsulated (layer 3) frame type.
345 * for LLC frames without SNAP, we don't have
346 * an encapsulated type, and return ETH_TYPE_LLC.
348 * IANA reserves 0xFFFF, which we reuse to indicate
354 *----------------------------------------------------------------------------
356 static __inline UINT16
357 Eth_EncapsulatedPktType(const Eth_Header *eh)
359 Eth_HdrType type = Eth_HeaderType(eh);
362 case ETH_HEADER_TYPE_DIX: return eh->dix.typeNBO;
363 case ETH_HEADER_TYPE_802_1PQ: return eh->e802_1pq.dix.typeNBO;
364 case ETH_HEADER_TYPE_802_3:
366 * Documentation describes SNAP headers as having ONLY
367 * 0x03 as the control fields, not just the lower two bits
368 * This prevents the use of Eth_IsLLCControlUFormat.
370 if ((eh->e802_3.llc.dsap == 0xaa) && (eh->e802_3.llc.ssap == 0xaa) &&
371 (eh->e802_3.llc.control == ETH_LLC_CONTROL_UFRAME)) {
372 return eh->e802_3.snap.snapType.typeNBO;
374 // LLC, no snap header, then no type
378 case ETH_HEADER_TYPE_802_1PQ_802_3:
379 if ((eh->e802_1pq.e802_3.llc.dsap == 0xaa) &&
380 (eh->e802_1pq.e802_3.llc.ssap == 0xaa) &&
381 (eh->e802_1pq.e802_3.llc.control == ETH_LLC_CONTROL_UFRAME)) {
382 return eh->e802_1pq.e802_3.snap.snapType.typeNBO;
384 // tagged LLC, no snap header, then no type
394 *----------------------------------------------------------------------------
395 * Is the frame of the requested protocol type or is it an 802.1[pq]
396 * encapsulation of such a frame?
397 *----------------------------------------------------------------------------
399 static __inline BOOLEAN
400 Eth_IsDixType(const Eth_Header *eh, const Eth_DixTypeNBO type)
402 return Eth_EncapsulatedPktType(eh) == type;
407 *----------------------------------------------------------------------------
408 * Is the frame an IPV4 frame?
409 *----------------------------------------------------------------------------
411 static __inline BOOLEAN
412 Eth_IsIPV4(const Eth_Header *eh)
414 return Eth_IsDixType(eh, ETH_TYPE_IPV4_NBO);
419 *----------------------------------------------------------------------------
420 * Is the frame an IPV6 frame?
421 *----------------------------------------------------------------------------
423 static __inline BOOLEAN
424 Eth_IsIPV6(const Eth_Header *eh)
426 return Eth_IsDixType(eh, ETH_TYPE_IPV6_NBO);
431 *----------------------------------------------------------------------------
432 * Is the frame an ARP frame?
433 *----------------------------------------------------------------------------
435 static __inline BOOLEAN
436 Eth_IsARP(const Eth_Header *eh)
438 return Eth_IsDixType(eh, ETH_TYPE_ARP_NBO);
443 *----------------------------------------------------------------------------
444 * Does the frame contain an 802.1[pq] tag?
445 *----------------------------------------------------------------------------
447 static __inline BOOLEAN
448 Eth_IsFrameTagged(const Eth_Header *eh)
450 return (eh->dix.typeNBO == ETH_TYPE_802_1PQ_NBO);
452 #endif /* __ETHERNET_H_ */