ethernet_misc.c
Go to the documentation of this file.
1 /**
2  * @file ethernet_misc.c
3  * @brief Helper functions for Ethernet
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2026 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.6.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL ETH_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/net.h"
36 #include "core/nic.h"
37 #include "core/ethernet.h"
38 #include "core/ethernet_misc.h"
39 #include "core/socket.h"
40 #include "core/raw_socket.h"
41 #include "core/tcp_timer.h"
42 #include "ipv4/arp.h"
43 #include "ipv4/ipv4.h"
44 #include "ipv4/ipv4_misc.h"
45 #include "ipv6/ipv6.h"
46 #include "debug.h"
47 
48 //Check TCP/IP stack configuration
49 #if (ETH_SUPPORT == ENABLED)
50 
51 //Padding bytes
52 const uint8_t ethPadding[64] =
53 {
54  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
62 };
63 
64 //A lookup table can be used to speed up CRC calculation
65 #if (ETH_FAST_CRC_SUPPORT == ENABLED)
66 
67 static const uint32_t crc32Table[256] =
68 {
69  0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
70  0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
71  0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
72  0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
73  0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
74  0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
75  0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
76  0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
77  0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
78  0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
79  0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
80  0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
81  0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
82  0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
83  0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
84  0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
85  0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
86  0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
87  0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
88  0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
89  0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
90  0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
91  0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
92  0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
93  0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
94  0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
95  0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
96  0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
97  0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
98  0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
99  0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
100  0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
101  0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
102  0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
103  0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
104  0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
105  0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
106  0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
107  0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
108  0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
109  0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
110  0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
111  0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
112  0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
113  0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
114  0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
115  0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
116  0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
117  0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
118  0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
119  0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
120  0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
121  0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
122  0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
123  0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
124  0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
125  0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
126  0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
127  0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
128  0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
129  0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
130  0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
131  0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
132  0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
133 };
134 
135 #endif
136 
137 
138 /**
139  * @brief Ethernet frame padding
140  * @param[in] buffer Multi-part buffer containing the Ethernet frame
141  * @param[in,out] length Length of the Ethernet frame, in bytes
142  * @return Error code
143  **/
144 
146 {
147  error_t error;
148  size_t n;
149 
150  //Ethernet frames have a minimum length of 64 byte
152  {
153  //Add padding as necessary
155 
156  //Append padding bytes
157  error = netBufferAppend(buffer, ethPadding, n);
158 
159  //Check status code
160  if(!error)
161  {
162  //Adjust frame length
163  *length += n;
164  }
165  }
166  else
167  {
168  //No padding needed
169  error = NO_ERROR;
170  }
171 
172  //Return status code
173  return error;
174 }
175 
176 
177 /**
178  * @brief VLAN tag encoding
179  * @param[in] buffer Multi-part buffer containing the payload
180  * @param[in,out] offset Offset to the first payload byte
181  * @param[in] vlanId VLAN identifier
182  * @param[in] vlanPcp VLAN priority
183  * @param[in] vlanDei Drop eligible indicator
184  * @param[in] type Ethernet type
185  * @return Error code
186  **/
187 
188 error_t ethEncodeVlanTag(NetBuffer *buffer, size_t *offset, uint16_t vlanId,
189  int8_t vlanPcp, int8_t vlanDei, uint16_t type)
190 {
191  VlanTag *vlanTag;
192 
193  //Sanity check
194  if(*offset < sizeof(VlanTag))
196 
197  //Valid PCP value?
198  if(vlanPcp >= 0)
199  {
200  //The PCP field specifies the frame priority level. Different PCP values
201  //can be used to prioritize different classes of traffic
202  vlanId = (((uint16_t) vlanPcp << VLAN_PCP_POS) & VLAN_PCP_MASK) |
203  (vlanId & ~VLAN_PCP_MASK);
204  }
205 
206  //Valid DEI value?
207  if(vlanDei >= 0)
208  {
209  //The DEI flag may be used to indicate frames eligible to be dropped in
210  //the presence of congestion
211  vlanId = (((uint16_t) vlanDei << VLAN_DEI_POS) & VLAN_DEI_MASK) |
212  (vlanId & ~VLAN_DEI_MASK);
213  }
214 
215  //Make room for the VLAN tag
216  *offset -= sizeof(VlanTag);
217  //Point to the VLAN tag
218  vlanTag = netBufferAt(buffer, *offset, 0);
219 
220  //The TCI field is divided into PCP, DEI, and VID
221  vlanTag->tci = htons(vlanId);
222 
223  //The EtherType field indicates which protocol is encapsulated in the
224  //payload
225  vlanTag->type = htons(type);
226 
227  //Successful processing
228  return NO_ERROR;
229 }
230 
231 
232 /**
233  * @brief VLAN tag decoding
234  * @param[in] frame Pointer to the received Ethernet frame
235  * @param[in] length Length of the frame, in bytes
236  * @param[out] vlanId VLAN identifier
237  * @param[out] type Ethernet type
238  * @return Error code
239  **/
240 
241 error_t ethDecodeVlanTag(const uint8_t *frame, size_t length, uint16_t *vlanId,
242  uint16_t *type)
243 {
244  VlanTag *vlanTag;
245 
246  //Malformed Ethernet frame?
247  if(length < sizeof(VlanTag))
248  {
249  //Drop the received frame
250  return ERROR_INVALID_LENGTH;
251  }
252 
253  //Point to the VLAN tag
254  vlanTag = (VlanTag *) frame;
255 
256  //The VID is encoded in a 12-bit field. The null VID indicates that the
257  //tag header contains only priority information (refer to IEEE 802.1Q,
258  //section 9.6)
259  *vlanId = ntohs(vlanTag->tci) & VLAN_VID_MASK;
260 
261  //The EtherType field indicates which protocol is encapsulated in the
262  //payload
263  *type = ntohs(vlanTag->type);
264 
265  //Successful processing
266  return NO_ERROR;
267 }
268 
269 
270 /**
271  * @brief Destination MAC address filtering
272  * @param[in] interface Underlying network interface
273  * @param[in] macAddr Destination MAC address to be checked
274  * @return Error code
275  **/
276 
277 error_t ethCheckDestAddr(NetInterface *interface, const MacAddr *macAddr)
278 {
279  error_t error;
280  uint_t i;
281  MacFilterEntry *entry;
282  NetInterface *logicalInterface;
283 
284  //Filter out any invalid addresses
285  error = ERROR_INVALID_ADDRESS;
286 
287  //Point to the logical interface
288  logicalInterface = nicGetLogicalInterface(interface);
289 
290  //Interface MAC address?
291  if(macCompAddr(macAddr, &logicalInterface->macAddr))
292  {
293  error = NO_ERROR;
294  }
295  //Broadcast address?
296  else if(macCompAddr(macAddr, &MAC_BROADCAST_ADDR))
297  {
298  error = NO_ERROR;
299  }
300  //Multicast address?
301  else if(macIsMulticastAddr(macAddr))
302  {
303 #if (IPV4_SUPPORT == ENABLED && IGMP_ROUTER_SUPPORT == ENABLED)
304  //Trap multicast packets when IGMP router is enabled
305  if(interface->igmpRouterContext != NULL &&
306  interface->igmpRouterContext->running)
307  {
308  error = NO_ERROR;
309  }
310  else
311 #endif
312  {
313  //Go through the MAC filter table
314  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
315  {
316  //Point to the current entry
317  entry = &interface->macAddrFilter[i];
318 
319  //Valid entry?
320  if(entry->refCount > 0)
321  {
322  //Check whether the destination MAC address matches
323  //a relevant multicast address
324  if(macCompAddr(&entry->addr, macAddr))
325  {
326  //The MAC address is acceptable
327  error = NO_ERROR;
328  //Stop immediately
329  break;
330  }
331  }
332  }
333  }
334  }
335 
336  //Return status code
337  return error;
338 }
339 
340 
341 /**
342  * @brief Trap IGMP packets
343  * @param[in] header Pointer to the Ethernet header
344  * @param[in] data Pointer to the payload data
345  * @param[in] length Length of the payload data, in bytes
346  * @return TRUE if the Ethernet frame contains an IGMP message, else FALSE
347  **/
348 
349 bool_t ethTrapIgmpPacket(EthHeader *header, uint8_t *data, size_t length)
350 {
351  bool_t flag;
352 
353  //Initialize flag
354  flag = FALSE;
355 
356 #if (IPV4_SUPPORT == ENABLED)
357  //Multicast IPv4 packet?
358  if(macIsMulticastAddr(&header->destAddr) &&
359  ntohs(header->type) == ETH_TYPE_IPV4)
360  {
361  //Check the length of the payload data
362  if(length >= sizeof(Ipv4Header))
363  {
364  //Check whether the IPv4 packet contains an IGMP message
365  flag = ipv4TrapIgmpPacket((Ipv4Header *) data);
366  }
367  }
368 #endif
369 
370  //Return TRUE if the Ethernet frame contains an IGMP message
371  return flag;
372 }
373 
374 
375 /**
376  * @brief Update Ethernet input statistics
377  * @param[in] interface Underlying network interface
378  * @param[in] destMacAddr Destination MAC address
379  **/
380 
381 void ethUpdateInStats(NetInterface *interface, const MacAddr *destMacAddr)
382 {
383  //Check whether the destination address is a unicast, broadcast or multicast address
384  if(macCompAddr(destMacAddr, &MAC_BROADCAST_ADDR))
385  {
386  //Number of non-unicast packets delivered to a higher-layer protocol
387  NET_IF_STATS_INC_COUNTER32(inNUcastPkts, 1);
388  //Number of broadcast packets delivered to a higher-layer protocol
389  NET_IF_STATS_INC_COUNTER64(inBroadcastPkts, 1);
390  }
391  else if(macIsMulticastAddr(destMacAddr))
392  {
393  //Number of non-unicast packets delivered to a higher-layer protocol
394  NET_IF_STATS_INC_COUNTER32(inNUcastPkts, 1);
395  //Number of multicast packets delivered to a higher-layer protocol
396  NET_IF_STATS_INC_COUNTER64(inMulticastPkts, 1);
397  }
398  else
399  {
400  //Number of unicast packets delivered to a higher-layer protocol
401  NET_IF_STATS_INC_COUNTER64(inUcastPkts, 1);
402  }
403 }
404 
405 
406 /**
407  * @brief Update Ethernet output statistics
408  * @param[in] interface Underlying network interface
409  * @param[in] destMacAddr Destination MAC address
410  * @param[in] length Length of the Ethernet frame, in bytes
411  **/
412 
413 void ethUpdateOutStats(NetInterface *interface, const MacAddr *destMacAddr,
414  size_t length)
415 {
416  //Total number of octets transmitted out of the interface
418 
419  //Check whether the destination address is a unicast, broadcast or multicast address
420  if(macCompAddr(destMacAddr, &MAC_BROADCAST_ADDR))
421  {
422  //Number of non-unicast packets that higher-level protocols requested be transmitted
423  NET_IF_STATS_INC_COUNTER32(outNUcastPkts, 1);
424  //Number of broadcast packets that higher-level protocols requested be transmitted
425  NET_IF_STATS_INC_COUNTER64(outBroadcastPkts, 1);
426  }
427  else if(macIsMulticastAddr(destMacAddr))
428  {
429  //Number of non-unicast packets that higher-level protocols requested be transmitted
430  NET_IF_STATS_INC_COUNTER32(outNUcastPkts, 1);
431  //Number of multicast packets that higher-level protocols requested be transmitted
432  NET_IF_STATS_INC_COUNTER64(outMulticastPkts, 1);
433  }
434  else
435  {
436  //Number of unicast packets that higher-level protocols requested be transmitted
437  NET_IF_STATS_INC_COUNTER64(outUcastPkts, 1);
438  }
439 }
440 
441 
442 /**
443  * @brief Update Ethernet error statistics
444  * @param[in] interface Underlying network interface
445  * @param[in] error Status code describing the error
446  **/
447 
448 void ethUpdateErrorStats(NetInterface *interface, error_t error)
449 {
450  //Check error code
451  switch(error)
452  {
455  //Number of inbound packets which were chosen to be discarded even though
456  //no errors had been detected
457  NET_IF_STATS_INC_COUNTER32(inDiscards, 1);
458  break;
459 
462  //Number of inbound packets that contained errors
463  NET_IF_STATS_INC_COUNTER32(inErrors, 1);
464  break;
465 
467  //Number of packets received via the interface which were discarded
468  //because of an unknown or unsupported protocol
469  NET_IF_STATS_INC_COUNTER32(inUnknownProtos, 1);
470  break;
471 
472  default:
473  //Just for sanity
474  break;
475  }
476 }
477 
478 
479 /**
480  * @brief Ethernet CRC calculation
481  * @param[in] data Pointer to the data over which to calculate the CRC
482  * @param[in] length Number of bytes to process
483  * @return Resulting CRC value
484  **/
485 
486 uint32_t ethCalcCrc(const void *data, size_t length)
487 {
488 //A lookup table can be used to speed up CRC calculation
489 #if (ETH_FAST_CRC_SUPPORT == ENABLED)
490  uint_t i;
491 
492  //Point to the data over which to calculate the CRC
493  const uint8_t *p = (uint8_t *) data;
494  //CRC preset value
495  uint32_t crc = 0xFFFFFFFF;
496 
497  //Loop through data
498  for(i = 0; i < length; i++)
499  {
500  //The message is processed byte by byte
501  crc = (crc >> 8) ^ crc32Table[(crc & 0xFF) ^ p[i]];
502  }
503 
504  //Return 1's complement value
505  return ~crc;
506 
507 //Bit by bit CRC calculation
508 #else
509  uint_t i;
510  uint_t j;
511 
512  //Point to the data over which to calculate the CRC
513  const uint8_t *p = (uint8_t *) data;
514  //CRC preset value
515  uint32_t crc = 0xFFFFFFFF;
516 
517  //Loop through data
518  for(i = 0; i < length; i++)
519  {
520  //Update CRC value
521  crc ^= p[i];
522 
523  //The message is processed bit by bit
524  for(j = 0; j < 8; j++)
525  {
526  if(crc & 0x00000001)
527  {
528  crc = (crc >> 1) ^ 0xEDB88320;
529  }
530  else
531  {
532  crc = crc >> 1;
533  }
534  }
535  }
536 
537  //Return 1's complement value
538  return ~crc;
539 #endif
540 }
541 
542 
543 /**
544  * @brief Calculate CRC over a multi-part buffer
545  * @param[in] buffer Pointer to the multi-part buffer
546  * @param[in] offset Offset from the beginning of the buffer
547  * @param[in] length Number of bytes to process
548  * @return Resulting CRC value
549  **/
550 
551 uint32_t ethCalcCrcEx(const NetBuffer *buffer, size_t offset, size_t length)
552 {
553  uint_t i;
554  uint_t n;
555  uint32_t crc;
556  uint8_t *p;
557 #if (ETH_FAST_CRC_SUPPORT == DISABLED)
558  uint_t k;
559 #endif
560 
561  //CRC preset value
562  crc = 0xFFFFFFFF;
563 
564  //Loop through data chunks
565  for(i = 0; i < buffer->chunkCount && length > 0; i++)
566  {
567  //Is there any data to process in the current chunk?
568  if(offset < buffer->chunk[i].length)
569  {
570  //Point to the first data byte
571  p = (uint8_t *) buffer->chunk[i].address + offset;
572  //Compute the number of bytes to process
573  n = MIN(buffer->chunk[i].length - offset, length);
574  //Adjust byte counter
575  length -= n;
576 
577  //Process current chunk
578  while(n > 0)
579  {
580 #if (ETH_FAST_CRC_SUPPORT == ENABLED)
581  //The message is processed byte by byte
582  crc = (crc >> 8) ^ crc32Table[(crc & 0xFF) ^ *p];
583 #else
584  //Update CRC value
585  crc ^= *p;
586 
587  //The message is processed bit by bit
588  for(k = 0; k < 8; k++)
589  {
590  if(crc & 0x00000001)
591  {
592  crc = (crc >> 1) ^ 0xEDB88320;
593  }
594  else
595  {
596  crc = crc >> 1;
597  }
598  }
599 #endif
600  //Next byte
601  p++;
602  n--;
603  }
604 
605  //Process the next block from the start
606  offset = 0;
607  }
608  else
609  {
610  //Skip the current chunk
611  offset -= buffer->chunk[i].length;
612  }
613  }
614 
615  //Return 1's complement value
616  return ~crc;
617 }
618 
619 
620 /**
621  * @brief Ethernet CRC verification
622  * @param[in] interface Underlying network interface
623  * @param[in] frame Pointer to the received Ethernet frame
624  * @param[in] length Length of the frame, in bytes
625  * @return Error code
626  **/
627 
628 error_t ethCheckCrc(NetInterface *interface, const uint8_t *frame,
629  size_t length)
630 {
631  //Malformed Ethernet frame?
632  if(length < (sizeof(EthHeader) + ETH_CRC_SIZE))
633  {
634  //Drop the received frame
635  return ERROR_INVALID_LENGTH;
636  }
637 
638  //CRC verification not supported by hardware?
639  if(!interface->nicDriver->autoCrcVerif)
640  {
641  //The value of the residue is 0x2144DF1C when no CRC errors are detected
642  if(ethCalcCrc(frame, length) != 0x2144DF1C)
643  {
644  //Drop the received frame
645  return ERROR_WRONG_CHECKSUM;
646  }
647  }
648 
649  //Successful CRC verification
650  return NO_ERROR;
651 }
652 
653 #endif
#define htons(value)
Definition: cpu_endian.h:413
IPv6 (Internet Protocol Version 6)
#define VLAN_PCP_POS
Definition: ethernet.h:119
int bool_t
Definition: compiler_port.h:63
#define Ipv4Header
Definition: ipv4.h:36
void ethUpdateInStats(NetInterface *interface, const MacAddr *destMacAddr)
Update Ethernet input statistics.
uint8_t p
Definition: ndp.h:300
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
uint_t chunkCount
Definition: net_mem.h:90
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:95
uint8_t data[]
Definition: ethernet.h:224
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:266
error_t ethCheckCrc(NetInterface *interface, const uint8_t *frame, size_t length)
Ethernet CRC verification.
uint8_t type
Definition: coap_common.h:176
#define VLAN_DEI_POS
Definition: ethernet.h:120
#define ETH_MIN_FRAME_SIZE
Definition: ethernet.h:108
@ ETH_TYPE_IPV4
Definition: ethernet.h:164
EthHeader
Definition: ethernet.h:225
#define VLAN_VID_MASK
Definition: ethernet.h:124
#define macIsMulticastAddr(macAddr)
Definition: ethernet.h:133
Ethernet.
VlanTag
Definition: ethernet.h:248
uint32_t ethCalcCrcEx(const NetBuffer *buffer, size_t offset, size_t length)
Calculate CRC over a multi-part buffer.
Helper functions for IPv4.
uint16_t length
Definition: net_mem.h:79
#define FALSE
Definition: os_port.h:46
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
void ethUpdateErrorStats(NetInterface *interface, error_t error)
Update Ethernet error statistics.
error_t
Error codes.
Definition: error.h:43
error_t ethDecodeVlanTag(const uint8_t *frame, size_t length, uint16_t *vlanId, uint16_t *type)
VLAN tag decoding.
void * address
Definition: net_mem.h:78
@ ERROR_INVALID_ADDRESS
Definition: error.h:103
#define NET_IF_STATS_INC_COUNTER64(name, value)
Definition: net.h:204
#define NetInterface
Definition: net.h:40
MacAddr addr
MAC address.
Definition: ethernet.h:265
@ ERROR_INVALID_LENGTH
Definition: error.h:111
error_t ethPadFrame(NetBuffer *buffer, size_t *length)
Ethernet frame padding.
uint8_t length
Definition: tcp.h:375
@ ERROR_INVALID_PROTOCOL
Definition: error.h:101
#define MIN(a, b)
Definition: os_port.h:63
bool_t ipv4TrapIgmpPacket(Ipv4Header *header)
Trap IGMP packets.
Definition: ipv4_misc.c:804
MacAddr
Definition: ethernet.h:197
TCP/IP raw sockets.
#define ntohs(value)
Definition: cpu_endian.h:421
error_t ethCheckDestAddr(NetInterface *interface, const MacAddr *macAddr)
Destination MAC address filtering.
const uint8_t ethPadding[64]
Definition: ethernet_misc.c:52
#define VLAN_DEI_MASK
Definition: ethernet.h:123
ChunkDesc chunk[]
Definition: net_mem.h:92
#define ETH_CRC_SIZE
Definition: ethernet.h:114
uint8_t n
MAC filter table entry.
Definition: ethernet.h:264
error_t netBufferAppend(NetBuffer *dest, const void *src, size_t length)
Append data a multi-part buffer.
Definition: net_mem.c:604
Network interface controller abstraction layer.
#define VLAN_PCP_MASK
Definition: ethernet.h:122
#define macCompAddr(macAddr1, macAddr2)
Definition: ethernet.h:130
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:89
Socket API.
void ethUpdateOutStats(NetInterface *interface, const MacAddr *destMacAddr, size_t length)
Update Ethernet output statistics.
void * netBufferAt(const NetBuffer *buffer, size_t offset, size_t length)
Returns a pointer to a data segment.
Definition: net_mem.c:418
bool_t ethTrapIgmpPacket(EthHeader *header, uint8_t *data, size_t length)
Trap IGMP packets.
@ ERROR_WRONG_CHECKSUM
Definition: error.h:88
IPv4 (Internet Protocol Version 4)
uint32_t ethCalcCrc(const void *data, size_t length)
Ethernet CRC calculation.
TCP timer management.
unsigned int uint_t
Definition: compiler_port.h:57
TCP/IP stack core.
NetInterface * nicGetLogicalInterface(NetInterface *interface)
Retrieve logical interface.
Definition: nic.c:51
#define NET_IF_STATS_INC_COUNTER32(name, value)
Definition: net.h:203
ARP (Address Resolution Protocol)
Helper functions for Ethernet.
error_t ethEncodeVlanTag(NetBuffer *buffer, size_t *offset, uint16_t vlanId, int8_t vlanPcp, int8_t vlanDei, uint16_t type)
VLAN tag encoding.
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
const MacAddr MAC_BROADCAST_ADDR
Definition: ethernet.c:53