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
72 ETH_TYPE_IPV4_NBO = 0x0008,
73 ETH_TYPE_IPV6_NBO = 0xDD86,
74 ETH_TYPE_ARP_NBO = 0x0608,
75 ETH_TYPE_RARP_NBO = 0x3580,
76 ETH_TYPE_LLDP_NBO = 0xCC88,
77 ETH_TYPE_CDP_NBO = 0x0020,
78 ETH_TYPE_AKIMBI_NBO = 0xDE88,
79 ETH_TYPE_802_1PQ_NBO = 0x0081, // not really a DIX type, but used as such
82 /* low two bits of the LLC control byte */
84 ETH_LLC_CONTROL_IFRAME = 0x0, // both 0x0 and 0x2, only low bit of 0 needed
85 ETH_LLC_CONTROL_SFRAME = 0x1,
86 ETH_LLC_CONTROL_UFRAME = 0x3,
89 #define ETH_LLC_CONTROL_UFRAME_MASK (0x3)
91 typedef struct Eth_DIX {
92 UINT16 typeNBO; // indicates the higher level protocol
96 * LLC header come in two varieties: 8 bit control and 16 bit control.
97 * when the lower two bits of the first byte's control are '11', this
98 * indicated the 8 bit control field.
100 typedef struct Eth_LLC8 {
106 typedef struct Eth_LLC16 {
112 typedef struct Eth_SNAP {
117 typedef struct Eth_802_3 {
118 UINT16 lenNBO; // length of the frame
119 Eth_LLC8 llc; // LLC header
120 Eth_SNAP snap; // SNAP header
123 // 802.1p QOS/priority tags
125 ETH_802_1_P_BEST_EFFORT = 0,
126 ETH_802_1_P_BACKGROUND = 1,
127 ETH_802_1_P_EXCELLENT_EFFORT = 2,
128 ETH_802_1_P_CRITICAL_APPS = 3,
129 ETH_802_1_P_VIDEO = 4,
130 ETH_802_1_P_VOICE = 5,
131 ETH_802_1_P_INTERNETWORK_CONROL = 6,
132 ETH_802_1_P_NETWORK_CONTROL = 7
135 typedef struct Eth_802_1pq_Tag {
136 UINT16 typeNBO; // always ETH_TYPE_802_1PQ
137 UINT16 vidHi:4, // 802.1q vlan ID high nibble
138 canonical:1, // bit order? (should always be 0)
139 priority:3, // 802.1p priority tag
140 vidLo:8; // 802.1q vlan ID low byte
143 typedef struct Eth_802_1pq {
144 Eth_802_1pq_Tag tag; // VLAN/QOS tag
146 Eth_DIX dix; // DIX header follows
147 Eth_802_3 e802_3; // or 802.3 header follows
151 typedef struct Eth_Header {
152 Eth_Address dst; // all types of ethernet frame have dst first
153 Eth_Address src; // and the src next (at least all the ones we'll see)
155 Eth_DIX dix; // followed by a DIX header...
156 Eth_802_3 e802_3; // ...or an 802.3 header
157 Eth_802_1pq e802_1pq; // ...or an 802.1[pq] tag and a header
161 #define ETH_BROADCAST_ADDRESS { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
163 static Eth_Address netEthBroadcastAddr = ETH_BROADCAST_ADDRESS;
166 * simple predicate for 1536 boundary.
167 * the parameter is a network ordered UINT16, which is compared to 0x06,
168 * testing for "length" values greater than or equal to 0x0600 (1536)
171 #define ETH_TYPENOT8023(x) (((x) & 0xff) >= 0x06)
174 * header length macros
176 * first two are typical: ETH_HEADER_LEN_DIX, ETH_HEADER_LEN_802_1PQ
177 * last two are suspicious, due to 802.3 incompleteness
180 #define ETH_HEADER_LEN_DIX (sizeof(Eth_Address) + \
181 sizeof(Eth_Address) + \
183 #define ETH_HEADER_LEN_802_1PQ (sizeof(Eth_Address) + \
184 sizeof(Eth_Address) + \
185 sizeof(Eth_802_1pq_Tag) + \
187 #define ETH_HEADER_LEN_802_2_LLC (sizeof(Eth_Address) + \
188 sizeof(Eth_Address) + \
191 #define ETH_HEADER_LEN_802_2_LLC16 (sizeof(Eth_Address) + \
192 sizeof(Eth_Address) + \
195 #define ETH_HEADER_LEN_802_3 (sizeof(Eth_Address) + \
196 sizeof(Eth_Address) + \
198 #define ETH_HEADER_LEN_802_1PQ_LLC (sizeof(Eth_Address) + \
199 sizeof(Eth_Address) + \
200 sizeof(Eth_802_1pq_Tag) + \
203 #define ETH_HEADER_LEN_802_1PQ_LLC16 (sizeof(Eth_Address) + \
204 sizeof(Eth_Address) + \
205 sizeof(Eth_802_1pq_Tag) + \
208 #define ETH_HEADER_LEN_802_1PQ_802_3 (sizeof(Eth_Address) + \
209 sizeof(Eth_Address) + \
210 sizeof(Eth_802_1pq_Tag) + \
213 #define ETH_MIN_HEADER_LEN (ETH_HEADER_LEN_DIX)
214 #define ETH_MAX_HEADER_LEN (ETH_HEADER_LEN_802_1PQ_802_3)
216 #define ETH_MIN_FRAME_LEN 60
217 #define ETH_MAX_STD_MTU 1500
218 #define ETH_MAX_STD_FRAMELEN (ETH_MAX_STD_MTU + ETH_MAX_HEADER_LEN)
219 #define ETH_MAX_JUMBO_MTU 9000
220 #define ETH_MAX_JUMBO_FRAMELEN (ETH_MAX_JUMBO_MTU + ETH_MAX_HEADER_LEN)
222 #define ETH_DEFAULT_MTU 1500
224 #define ETH_FCS_LEN 4
225 #define ETH_VLAN_LEN sizeof(Eth_802_1pq_Tag)
229 *----------------------------------------------------------------------------
230 * Do the two ethernet addresses match?
231 *----------------------------------------------------------------------------
233 static __inline BOOLEAN
234 Eth_IsAddrMatch(const Eth_Address addr1, const Eth_Address addr2)
236 return !memcmp(addr1, addr2, ETH_ADDR_LENGTH);
241 *----------------------------------------------------------------------------
242 * Is the address the broadcast address?
243 *----------------------------------------------------------------------------
245 static __inline BOOLEAN
246 Eth_IsBroadcastAddr(const Eth_Address addr)
248 return Eth_IsAddrMatch(addr, netEthBroadcastAddr);
253 *----------------------------------------------------------------------------
254 * Is the address a unicast address?
255 *----------------------------------------------------------------------------
257 static __inline BOOLEAN
258 Eth_IsUnicastAddr(const Eth_Address addr)
260 // broadcast and multicast frames always have the low bit set in byte 0
261 return !(((CHAR *)addr)[0] & 0x1);
265 *----------------------------------------------------------------------------
266 * Is the address the all-zeros address?
267 *----------------------------------------------------------------------------
269 static __inline BOOLEAN
270 Eth_IsNullAddr(const Eth_Address addr)
272 return ((addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]) == 0);
276 *----------------------------------------------------------------------------
279 * return an Eth_HdrType depending on the eth header
280 * contents. will not work in all cases, especially since it
281 * requres ETH_HEADER_LEN_802_1PQ bytes to determine the type
283 * HeaderType isn't sufficient to determine the length of
284 * the eth header. for 802.3 header, its not clear without
285 * examination, whether a SNAP is included
289 * ETH_HEADER_TYPE_DIX: typical 14 byte eth header
290 * ETH_HEADER_TYPE_802_1PQ: DIX+vlan tagging
291 * ETH_HEADER_TYPE_802_3: 802.3 eth header
292 * ETH_HEADER_TYPE_802_1PQ_802_3: 802.3 + vlan tag
294 * the test for DIX was moved from a 1500 boundary to a 1536
295 * boundary, since the vmxnet2 MTU was updated to 1514. when
296 * W2K8 attempted to send LLC frames, these were interpreted
297 * as DIX frames instead of the correct 802.3 type
299 * these links may help if they're valid:
301 * http://standards.ieee.org/regauth/ethertype/type-tut.html
302 * http://standards.ieee.org/regauth/ethertype/type-pub.html
307 *----------------------------------------------------------------------------
309 static __inline Eth_HdrType
310 Eth_HeaderType(const Eth_Header *eh)
313 * we use 1536 (IEEE 802.3-std mentions 1536, but iana indicates
314 * type of 0-0x5dc are 802.3) instead of some #def symbol to prevent
315 * inadvertant reuse of the same macro for buffer size decls.
317 if (ETH_TYPENOT8023(eh->dix.typeNBO)) {
318 if (eh->dix.typeNBO != ETH_TYPE_802_1PQ_NBO) {
320 return ETH_HEADER_TYPE_DIX;
323 /* some type of 802.1pq tagged frame */
324 if (ETH_TYPENOT8023(eh->e802_1pq.dix.typeNBO)) {
325 /* vlan tagging with dix style type */
326 return ETH_HEADER_TYPE_802_1PQ;
329 /* vlan tagging with 802.3 header */
330 return ETH_HEADER_TYPE_802_1PQ_802_3;
334 return ETH_HEADER_TYPE_802_3;
339 *----------------------------------------------------------------------------
341 * Eth_EncapsulatedPktType --
342 * Get the encapsulated (layer 3) frame type.
343 * for LLC frames without SNAP, we don't have
344 * an encapsulated type, and return ETH_TYPE_LLC.
346 * IANA reserves 0xFFFF, which we reuse to indicate
352 *----------------------------------------------------------------------------
354 static __inline UINT16
355 Eth_EncapsulatedPktType(const Eth_Header *eh)
357 Eth_HdrType type = Eth_HeaderType(eh);
360 case ETH_HEADER_TYPE_DIX: return eh->dix.typeNBO;
361 case ETH_HEADER_TYPE_802_1PQ: return eh->e802_1pq.dix.typeNBO;
362 case ETH_HEADER_TYPE_802_3:
364 * Documentation describes SNAP headers as having ONLY
365 * 0x03 as the control fields, not just the lower two bits
366 * This prevents the use of Eth_IsLLCControlUFormat.
368 if ((eh->e802_3.llc.dsap == 0xaa) && (eh->e802_3.llc.ssap == 0xaa) &&
369 (eh->e802_3.llc.control == ETH_LLC_CONTROL_UFRAME)) {
370 return eh->e802_3.snap.snapType.typeNBO;
372 // LLC, no snap header, then no type
376 case ETH_HEADER_TYPE_802_1PQ_802_3:
377 if ((eh->e802_1pq.e802_3.llc.dsap == 0xaa) &&
378 (eh->e802_1pq.e802_3.llc.ssap == 0xaa) &&
379 (eh->e802_1pq.e802_3.llc.control == ETH_LLC_CONTROL_UFRAME)) {
380 return eh->e802_1pq.e802_3.snap.snapType.typeNBO;
382 // tagged LLC, no snap header, then no type
392 *----------------------------------------------------------------------------
393 * Is the frame of the requested protocol type or is it an 802.1[pq]
394 * encapsulation of such a frame?
395 *----------------------------------------------------------------------------
397 static __inline BOOLEAN
398 Eth_IsDixType(const Eth_Header *eh, const Eth_DixTypeNBO type)
400 return Eth_EncapsulatedPktType(eh) == type;
405 *----------------------------------------------------------------------------
406 * Is the frame an IPV4 frame?
407 *----------------------------------------------------------------------------
409 static __inline BOOLEAN
410 Eth_IsIPV4(const Eth_Header *eh)
412 return Eth_IsDixType(eh, ETH_TYPE_IPV4_NBO);
417 *----------------------------------------------------------------------------
418 * Is the frame an IPV6 frame?
419 *----------------------------------------------------------------------------
421 static __inline BOOLEAN
422 Eth_IsIPV6(const Eth_Header *eh)
424 return Eth_IsDixType(eh, ETH_TYPE_IPV6_NBO);
429 *----------------------------------------------------------------------------
430 * Is the frame an ARP frame?
431 *----------------------------------------------------------------------------
433 static __inline BOOLEAN
434 Eth_IsARP(const Eth_Header *eh)
436 return Eth_IsDixType(eh, ETH_TYPE_ARP_NBO);
441 *----------------------------------------------------------------------------
442 * Does the frame contain an 802.1[pq] tag?
443 *----------------------------------------------------------------------------
445 static __inline BOOLEAN
446 Eth_IsFrameTagged(const Eth_Header *eh)
448 return (eh->dix.typeNBO == ETH_TYPE_802_1PQ_NBO);
450 #endif /* __ETHERNET_H_ */