ipv4_misc.c
Go to the documentation of this file.
1 /**
2  * @file ipv4_misc.c
3  * @brief Helper functions for IPv4
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 IPV4_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/net.h"
36 #include "ipv4/ipv4.h"
37 #include "ipv4/ipv4_misc.h"
38 #include "debug.h"
39 
40 //Check TCP/IP stack configuration
41 #if (IPV4_SUPPORT == ENABLED)
42 
43 
44 /**
45  * @brief Append a Router Alert option to an IPv4 packet
46  * @param[in] buffer Multi-part buffer containing the payload
47  * @param[in,out] offset Offset to the first payload byte
48  * @return Error code
49  **/
50 
51 error_t ipv4AddRouterAlertOption(NetBuffer *buffer, size_t *offset)
52 {
53  error_t error;
54  Ipv4RouterAlertOption *option;
55 
56  //Make sure there is sufficient space for the option
57  if(*offset >= sizeof(Ipv4RouterAlertOption))
58  {
59  //Make room for the option
60  *offset -= sizeof(Ipv4RouterAlertOption);
61  //Point to the option
62  option = netBufferAt(buffer, *offset, 0);
63 
64  //Format Router Alert option
65  option->type = IPV4_OPTION_RTRALT;
66  option->length = sizeof(Ipv4RouterAlertOption);
67  option->value = HTONS(0);
68 
69  //Successful processing
70  error = NO_ERROR;
71  }
72  else
73  {
74  //Report an error
76  }
77 
78  //Return status code
79  return error;
80 }
81 
82 
83 /**
84  * @brief Source IPv4 address filtering
85  * @param[in] interface Underlying network interface
86  * @param[in] ipAddr Source IPv4 address to be checked
87  * @return Error code
88  **/
89 
91 {
92  //Broadcast and multicast addresses must not be used as source address
93  //(refer to RFC 1122, section 3.2.1.3)
95  {
96  //Debug message
97  TRACE_WARNING("Wrong source IPv4 address!\r\n");
98  //The source address not is acceptable
99  return ERROR_INVALID_ADDRESS;
100  }
101 
102  //The source address is acceptable
103  return NO_ERROR;
104 }
105 
106 
107 /**
108  * @brief Destination IPv4 address filtering
109  * @param[in] interface Underlying network interface
110  * @param[in] ipAddr Destination IPv4 address to be checked
111  * @return Error code
112  **/
113 
115 {
116  error_t error;
117  uint_t i;
118 
119  //Filter out any invalid addresses
120  error = ERROR_INVALID_ADDRESS;
121 
122  //Broadcast address?
123  if(ipv4IsBroadcastAddr(interface, ipAddr))
124  {
125  //Always accept broadcast address
126  error = NO_ERROR;
127  }
128  else
129  {
130  //Loop through the list of IPv4 addresses assigned to the interface
131  for(i = 0; i < IPV4_ADDR_LIST_SIZE; i++)
132  {
133  Ipv4AddrEntry *entry;
134 
135  //Point to the current entry
136  entry = &interface->ipv4Context.addrList[i];
137 
138  //Valid entry?
139  if(entry->state != IPV4_ADDR_STATE_INVALID)
140  {
141  //Check whether the destination address matches a valid unicast
142  //address assigned to the interface
143  if(entry->addr == ipAddr)
144  {
145  //The destination address is acceptable
146  error = NO_ERROR;
147  //We are done
148  break;
149  }
150  }
151  }
152  }
153 
154  //Return status code
155  return error;
156 }
157 
158 
159 /**
160  * @brief IPv4 source address selection
161  *
162  * This function selects the source address and the relevant network interface
163  * to be used in order to join the specified destination address
164  *
165  * @param[in] context Pointer to the TCP/IP stack context
166  * @param[in,out] interface A pointer to a valid network interface may be provided as
167  * a hint. The function returns a pointer identifying the interface to be used
168  * @param[in] destAddr Destination IPv4 address
169  * @param[out] srcAddr Local IPv4 address to be used
170  * @return Error code
171  **/
172 
175 {
176  error_t error;
177  uint_t i;
178  uint_t j;
179  NetInterface *currentInterface;
180  NetInterface *bestInterface;
181  Ipv4AddrEntry *currentAddr;
182  Ipv4AddrEntry *bestAddr;
183 
184  //Initialize variables
185  bestInterface = NULL;
186  bestAddr = NULL;
187 
188  //Loop through network interfaces
189  for(i = 0; i < context->numInterfaces; i++)
190  {
191  //Point to the current interface
192  currentInterface = &context->interfaces[i];
193 
194  //A network interface may be provided as a hint
195  if(*interface != currentInterface && *interface != NULL)
196  {
197  //Select the next interface in the list
198  continue;
199  }
200 
201  //A sort of the candidate source addresses is being performed
202  for(j = 0; j < IPV4_ADDR_LIST_SIZE; j++)
203  {
204  //Point to the current entry
205  currentAddr = &currentInterface->ipv4Context.addrList[j];
206 
207  //Check the state of the address
208  if(currentAddr->state == IPV4_ADDR_STATE_VALID)
209  {
210  //Select the first address as default
211  if(bestAddr == NULL)
212  {
213  //Give the current source address the higher precedence
214  bestInterface = currentInterface;
215  bestAddr = currentAddr;
216 
217  //Select the next address in the list
218  continue;
219  }
220 
221  //Prefer same address
222  if(bestAddr->addr == destAddr)
223  {
224  //Select the next address in the list
225  continue;
226  }
227  else if(currentAddr->addr == destAddr)
228  {
229  //Give the current source address the higher precedence
230  bestInterface = currentInterface;
231  bestAddr = currentAddr;
232 
233  //Select the next address in the list
234  continue;
235  }
236 
237  //Check whether the destination address matches the default gateway
238  if(bestAddr->defaultGateway == destAddr)
239  {
240  //Select the next address in the list
241  continue;
242  }
243  else if(currentAddr->defaultGateway == destAddr)
244  {
245  //Give the current source address the higher precedence
246  bestInterface = currentInterface;
247  bestAddr = currentAddr;
248 
249  //Select the next address in the list
250  continue;
251  }
252 
253  //Prefer appropriate scope
254  if(ipv4GetAddrScope(currentAddr->addr) < ipv4GetAddrScope(bestAddr->addr))
255  {
256  if(ipv4GetAddrScope(currentAddr->addr) >= ipv4GetAddrScope(destAddr))
257  {
258  //Give the current source address the higher precedence
259  bestInterface = currentInterface;
260  bestAddr = currentAddr;
261  }
262 
263  //Select the next address in the list
264  continue;
265  }
266  else if(ipv4GetAddrScope(bestAddr->addr) < ipv4GetAddrScope(currentAddr->addr))
267  {
269  {
270  //Give the current source address the higher precedence
271  bestInterface = currentInterface;
272  bestAddr = currentAddr;
273  }
274 
275  //Select the next address in the list
276  continue;
277  }
278 
279  //If the destination address lies on one of the subnets to which
280  //the host is directly connected, the corresponding source address
281  //may be chosen (refer to RFC 1122, section 3.3.4.3)
282  if(ipv4IsOnSubnet(bestAddr, destAddr))
283  {
284  if(ipv4IsOnSubnet(currentAddr, destAddr))
285  {
286  //Use longest subnet mask
287  if(ipv4GetPrefixLength(currentAddr->subnetMask) >
288  ipv4GetPrefixLength(bestAddr->subnetMask))
289  {
290  //Give the current source address the higher precedence
291  bestInterface = currentInterface;
292  bestAddr = currentAddr;
293  }
294  }
295 
296  //Select the next address in the list
297  continue;
298  }
299  else
300  {
301  if(ipv4IsOnSubnet(currentAddr, destAddr))
302  {
303  //Give the current source address the higher precedence
304  bestInterface = currentInterface;
305  bestAddr = currentAddr;
306 
307  //Select the next address in the list
308  continue;
309  }
310  }
311 
312  //The default gateways may be consulted. If these gateways are
313  //assigned to different interfaces, the interface corresponding
314  //to the gateway with the highest preference may be chosen
315  if(bestAddr->defaultGateway != IPV4_UNSPECIFIED_ADDR)
316  {
317  //Select the next address in the list
318  continue;
319  }
320  else if(currentAddr->defaultGateway != IPV4_UNSPECIFIED_ADDR)
321  {
322  //Give the current source address the higher precedence
323  bestInterface = currentInterface;
324  bestAddr = currentAddr;
325 
326  //Select the next address in the list
327  continue;
328  }
329  }
330  }
331  }
332 
333  //Valid source address?
334  if(bestAddr != NULL)
335  {
336  //Return the out-going interface and the source address to be used
337  *interface = bestInterface;
338  *srcAddr = bestAddr->addr;
339 
340  //Successful source address selection
341  error = NO_ERROR;
342  }
343  else
344  {
345  //Report an error
346  error = ERROR_NO_ADDRESS;
347  }
348 
349  //Return status code
350  return error;
351 }
352 
353 
354 /**
355  * @brief Default gateway selection
356  * @param[in] interface Underlying network interface
357  * @param[in] srcAddr Source IPv4 address
358  * @param[out] defaultGatewayAddr IPv4 address of the gateway
359  * @return Error code
360  **/
361 
363  Ipv4Addr *defaultGatewayAddr)
364 {
365  uint_t i;
366  Ipv4AddrEntry *entry;
367 
368  //Loop through the list of default gateways
369  for(i = 0; i < IPV4_ADDR_LIST_SIZE; i++)
370  {
371  //Point to the current entry
372  entry = &interface->ipv4Context.addrList[i];
373 
374  //Check whether the gateway address is valid
375  if(entry->state == IPV4_ADDR_STATE_VALID &&
377  {
378  //Under the strong ES model, the source address is included as a
379  //parameter in order to select a gateway that is directly reachable
380  //on the corresponding physical interface (refer to RFC 1122,
381  //section 3.3.4.2)
382  if(entry->addr == srcAddr)
383  {
384  //Return the IPv4 address of the default gateway
385  *defaultGatewayAddr = entry->defaultGateway;
386  //Successful default gateway selection
387  return NO_ERROR;
388  }
389  }
390  }
391 
392  //No default gateway found
393  return ERROR_NO_ROUTE;
394 }
395 
396 
397 /**
398  * @brief Check whether a valid IPv4 address has been assigned to the interface
399  * @param[in] interface Underlying network interface
400  * @return TRUE if a valid IPv4 address has been assigned, else FALSE
401  **/
402 
404 {
405  uint_t i;
406  bool_t flag;
407  Ipv4AddrEntry *entry;
408 
409  //Initialize flag
410  flag = FALSE;
411 
412  //Loop through the list of IPv4 addresses assigned to the interface
413  for(i = 0; i < IPV4_ADDR_LIST_SIZE; i++)
414  {
415  //Point to the current entry
416  entry = &interface->ipv4Context.addrList[i];
417 
418  //Valid entry?
419  if(entry->state == IPV4_ADDR_STATE_VALID)
420  {
421  flag = TRUE;
422  }
423  }
424 
425  //Return TRUE if a valid IPv4 address has been assigned to the interface
426  return flag;
427 }
428 
429 
430 /**
431  * @brief Check whether an IPv4 address is on-link
432  * @param[in] interface Underlying network interface
433  * @param[in] ipAddr IPv4 address to be checked
434  * @return TRUE if the IPv4 address is on-link, else FALSE
435  **/
436 
438 {
439  uint_t i;
440  bool_t flag;
441  Ipv4AddrEntry *entry;
442 
443  //Initialize flag
444  flag = FALSE;
445 
446  //Loop through the list of IPv4 addresses assigned to the interface
447  for(i = 0; i < IPV4_ADDR_LIST_SIZE && !flag; i++)
448  {
449  //Point to the current entry
450  entry = &interface->ipv4Context.addrList[i];
451 
452  //Valid entry?
453  if(entry->state != IPV4_ADDR_STATE_INVALID)
454  {
455  //Check whether the specified IPv4 address belongs to the same subnet
456  if(ipv4IsOnSubnet(entry, ipAddr))
457  {
458  flag = TRUE;
459  }
460  }
461  }
462 
463  //Return TRUE if the specified IPv4 address is on-link
464  return flag;
465 }
466 
467 
468 /**
469  * @brief Check whether an IPv4 address is a broadcast address
470  * @param[in] interface Underlying network interface
471  * @param[in] ipAddr IPv4 address to be checked
472  * @return TRUE if the IPv4 address is a broadcast address, else FALSE
473  **/
474 
476 {
477  uint_t i;
478  bool_t flag;
479  Ipv4AddrEntry *entry;
480 
481  //Initialize flag
482  flag = FALSE;
483 
484  //Check whether the specified IPv4 address is the broadcast address
486  {
487  flag = TRUE;
488  }
489  else
490  {
491  //Loop through the list of IPv4 addresses assigned to the interface
492  for(i = 0; i < IPV4_ADDR_LIST_SIZE && !flag; i++)
493  {
494  //Point to the current entry
495  entry = &interface->ipv4Context.addrList[i];
496 
497  //Valid entry?
498  if(entry->state != IPV4_ADDR_STATE_INVALID)
499  {
500  //Check whether the specified IPv4 address belongs to the same subnet
501  if(ipv4IsOnSubnet(entry, ipAddr))
502  {
503  //Make sure the subnet mask is not 255.255.255.255
504  if(entry->subnetMask != IPV4_BROADCAST_ADDR)
505  {
506  //Directed broadcast address?
507  if((ipAddr | entry->subnetMask) == IPV4_BROADCAST_ADDR)
508  {
509  flag = TRUE;
510  }
511  }
512  }
513  }
514  }
515  }
516 
517  //Return TRUE if the specified IPv4 address is a broadcast address
518  return flag;
519 }
520 
521 
522 /**
523  * @brief Check whether an IPv4 address is a tentative address
524  * @param[in] interface Underlying network interface
525  * @param[in] ipAddr IPv4 address to be checked
526  * @return TRUE if the IPv4 address is a tentative address, else FALSE
527  **/
528 
530 {
531  uint_t i;
532  bool_t flag;
533  Ipv4AddrEntry *entry;
534 
535  //Initialize flag
536  flag = FALSE;
537 
538  //Loop through the list of IPv4 addresses assigned to the interface
539  for(i = 0; i < IPV4_ADDR_LIST_SIZE && !flag; i++)
540  {
541  //Point to the current entry
542  entry = &interface->ipv4Context.addrList[i];
543 
544  //Tentative address?
545  if(entry->state == IPV4_ADDR_STATE_TENTATIVE)
546  {
547  //Check whether the specified address matches a valid unicast
548  //address assigned to the interface
549  if(entry->addr == ipAddr)
550  {
551  flag = TRUE;
552  }
553  }
554  }
555 
556  //Return TRUE if the specified IPv4 address is a tentative address
557  return flag;
558 }
559 
560 
561 /**
562  * @brief Check whether the specified IPv4 is assigned to the host
563  * @param[in] context Pointer to the TCP/IP stack context
564  * @param[in] ipAddr IPv4 address to be checked
565  * @return TRUE if the IPv4 address matches any address assigned to the host,
566  * else FALSE
567  **/
568 
570 {
571  uint_t i;
572  uint_t j;
573  bool_t flag;
574  NetInterface *interface;
575  Ipv4AddrEntry *entry;
576 
577  //Initialize flag
578  flag = FALSE;
579 
580  //Loopback address?
582  {
583  //The 127.0.0.0/8 block is assigned for use as the host loopback address.
584  //A datagram sent by a higher-level protocol to an address anywhere within
585  //this block loops back inside the host (refer to RFC 5735, section 3)
586  flag = TRUE;
587  }
588  else
589  {
590  //Loop through network interfaces
591  for(i = 0; i < context->numInterfaces && !flag; i++)
592  {
593  //Point to the current interface
594  interface = &context->interfaces[i];
595 
596  //Iterate through the list of addresses assigned to the interface
597  for(j = 0; j < IPV4_ADDR_LIST_SIZE && !flag; j++)
598  {
599  //Point to the current entry
600  entry = &interface->ipv4Context.addrList[j];
601 
602  //Check whether the specified IPv4 address matches any address
603  //assigned to the host
604  if(entry->state == IPV4_ADDR_STATE_VALID &&
605  entry->addr == ipAddr)
606  {
607  flag = TRUE;
608  }
609  }
610  }
611  }
612 
613  //Return TRUE if the specified address matches any address assigned to the host
614  return flag;
615 }
616 
617 
618 /**
619  * @brief Compare IPv4 address prefixes
620  * @param[in] ipAddr1 First IPv4 address
621  * @param[in] ipAddr2 Second IPv4 address
622  * @param[in] length Prefix length
623  * @return TRUE if the prefixes match each other, else FALSE
624  **/
625 
626 bool_t ipv4CompPrefix(Ipv4Addr ipAddr1, Ipv4Addr ipAddr2, size_t length)
627 {
628  uint32_t mask;
629 
630  //Check prefix length
631  if(length == 0)
632  {
633  return TRUE;
634  }
635  else if(length < 32)
636  {
637  //Calculate the mask to be applied
638  mask = ((1 << length) - 1) << (32 - length);
639  //Convert the mask to network byte order
640  mask = htonl(mask);
641  }
642  else if(length == 32)
643  {
644  mask = IPV4_ADDR(255, 255, 255, 255);
645  }
646  else
647  {
648  return FALSE;
649  }
650 
651  //Compare address prefixes
652  return ((ipAddr1 & mask) == (ipAddr2 & mask));
653 }
654 
655 
656 /**
657  * @brief Retrieve the scope of an IPv4 address
658  * @param[in] ipAddr IPv4 address
659  * @return IPv4 address scope
660  **/
661 
663 {
664  uint_t scope;
665 
666  //Broadcast address?
668  {
669  //The broadcast address is never forwarded by the routers connecting
670  //the local network to other networks
672  }
673  //Multicast address?
674  else if(ipv4IsMulticastAddr(ipAddr))
675  {
676  //Local Network Control Block?
678  {
679  //Addresses in the Local Network Control Block are used for protocol
680  //control traffic that is not forwarded off link
682  }
683  //Any other multicast address?
684  else
685  {
686  //Other addresses are assigned global scope
687  scope = IPV4_ADDR_SCOPE_GLOBAL;
688  }
689  }
690  //Unicast address?
691  else
692  {
693  //Loopback address?
695  {
696  //IPv4 loopback addresses, which have the prefix 127.0.0.0/8,
697  //are assigned interface-local scope
699  }
700  //Link-local address?
702  {
703  //IPv4 auto-configuration addresses, which have the prefix
704  //169.254.0.0/16, are assigned link-local scope
706  }
707  //Any other unicast address?
708  else
709  {
710  //Other addresses are assigned global scope
711  scope = IPV4_ADDR_SCOPE_GLOBAL;
712  }
713  }
714 
715  //Return the scope of the specified IPv4 address
716  return scope;
717 }
718 
719 
720 /**
721  * @brief Calculate prefix length for a given subnet mask
722  * @param[in] mask Subnet mask
723  * @return Prefix length
724  **/
725 
727 {
728  uint_t i;
729 
730  //Convert from network byte order to host byte order
731  mask = ntohl(mask);
732 
733  //Count of the number of leading 1 bits in the network mask
734  for(i = 0; i < 32; i++)
735  {
736  //Check the value of the current bit
737  if(!(mask & (1U << (31 - i))))
738  {
739  break;
740  }
741  }
742 
743  //Return prefix length
744  return i;
745 }
746 
747 
748 /**
749  * @brief Get IPv4 broadcast address
750  * @param[in] interface Pointer to the desired network interface
751  * @param[out] addr IPv4 broadcast address
752  **/
753 
755 {
756  error_t error;
757  uint_t i;
758  Ipv4AddrEntry *entry;
759 
760  //Check parameters
761  if(interface != NULL && addr != NULL)
762  {
763  //Initialize status code
764  error = ERROR_NO_ADDRESS;
765 
766  //Loop through the list of IPv4 addresses assigned to the interface
767  for(i = 0; i < IPV4_ADDR_LIST_SIZE; i++)
768  {
769  //Point to the current entry
770  entry = &interface->ipv4Context.addrList[i];
771 
772  //Valid entry?
773  if(entry->state != IPV4_ADDR_STATE_INVALID)
774  {
775  //The broadcast address is obtained by performing a bitwise OR
776  //operation between the bit complement of the subnet mask and the
777  //host IP address
778  *addr = entry->addr;
779  *addr |= ~entry->subnetMask;
780 
781  //We are done
782  error = NO_ERROR;
783  break;
784  }
785  }
786  }
787  else
788  {
789  //Report an error
790  error = ERROR_INVALID_PARAMETER;
791  }
792 
793  //Return status code
794  return error;
795 }
796 
797 
798 /**
799  * @brief Trap IGMP packets
800  * @param[in] header Pointer to the IPv4 header
801  * @return TRUE if the IPv4 packet contains an IGMP message, else FALSE
802  **/
803 
805 {
806  bool_t flag;
807 
808  //Initialize flag
809  flag = FALSE;
810 
811  //Make sure the IPv4 packet is not fragmented
812  if((ntohs(header->fragmentOffset) & (IPV4_FLAG_MF | IPV4_OFFSET_MASK)) == 0)
813  {
814  //Valid IGMP message?
815  if(ipv4IsMulticastAddr(header->destAddr) &&
816  header->protocol == IPV4_PROTOCOL_IGMP)
817  {
818  flag = TRUE;
819  }
820  }
821 
822  //Return TRUE if the IPv4 packet contains an IGMP message
823  return flag;
824 }
825 
826 
827 /**
828  * @brief Update IPv4 input statistics
829  * @param[in] interface Underlying network interface
830  * @param[in] destIpAddr Destination IP address
831  * @param[in] length Length of the incoming IP packet
832  **/
833 
835  size_t length)
836 {
837  //Check whether the destination address is a unicast, broadcast or multicast
838  //address
839  if(ipv4IsBroadcastAddr(interface, destIpAddr))
840  {
841  //Number of IP broadcast datagrams transmitted
842  IPV4_SYSTEM_STATS_INC_COUNTER64(inBcastPkts, 1);
843  IPV4_IF_STATS_INC_COUNTER64(inBcastPkts, 1);
844  }
846  {
847  //Number of IP multicast datagrams transmitted
848  IPV4_SYSTEM_STATS_INC_COUNTER64(inMcastPkts, 1);
849  IPV4_IF_STATS_INC_COUNTER64(inMcastPkts, 1);
850 
851  //Total number of octets transmitted in IP multicast datagrams
852  IPV4_SYSTEM_STATS_INC_COUNTER64(inMcastOctets, length);
853  IPV4_IF_STATS_INC_COUNTER64(inMcastOctets, length);
854  }
855  else
856  {
857  //The destination address is a unicast address
858  }
859 }
860 
861 
862 /**
863  * @brief Update IPv4 output statistics
864  * @param[in] interface Underlying network interface
865  * @param[in] destIpAddr Destination IP address
866  * @param[in] length Length of the outgoing IP packet
867  **/
868 
870  size_t length)
871 {
872  //Check whether the destination address is a unicast, broadcast or multicast
873  //address
874  if(ipv4IsBroadcastAddr(interface, destIpAddr))
875  {
876  //Number of IP broadcast datagrams transmitted
877  IPV4_SYSTEM_STATS_INC_COUNTER64(outBcastPkts, 1);
878  IPV4_IF_STATS_INC_COUNTER64(outBcastPkts, 1);
879  }
881  {
882  //Number of IP multicast datagrams transmitted
883  IPV4_SYSTEM_STATS_INC_COUNTER64(outMcastPkts, 1);
884  IPV4_IF_STATS_INC_COUNTER64(outMcastPkts, 1);
885 
886  //Total number of octets transmitted in IP multicast datagrams
887  IPV4_SYSTEM_STATS_INC_COUNTER64(outMcastOctets, length);
888  IPV4_IF_STATS_INC_COUNTER64(outMcastOctets, length);
889  }
890  else
891  {
892  //The destination address is a unicast address
893  }
894 
895  //Total number of IP datagrams that this entity supplied to the lower layers
896  //for transmission
897  IPV4_SYSTEM_STATS_INC_COUNTER64(outTransmits, 1);
898  IPV4_IF_STATS_INC_COUNTER64(outTransmits, 1);
899 
900  //Total number of octets in IP datagrams delivered to the lower layers for
901  //transmission
904 }
905 
906 
907 /**
908  * @brief Update Ethernet error statistics
909  * @param[in] interface Underlying network interface
910  * @param[in] error Status code describing the error
911  **/
912 
914 {
915  //Check error code
916  switch(error)
917  {
919  //Number of input datagrams discarded due to errors in their IP headers
920  IPV4_SYSTEM_STATS_INC_COUNTER32(inHdrErrors, 1);
921  IPV4_IF_STATS_INC_COUNTER32(inHdrErrors, 1);
922  break;
923 
925  //Number of input datagrams discarded because the destination IP address
926  //was not a valid address
927  IPV4_SYSTEM_STATS_INC_COUNTER32(inAddrErrors, 1);
928  IPV4_IF_STATS_INC_COUNTER32(inAddrErrors, 1);
929  break;
930 
932  //Number of locally-addressed datagrams received successfully but
933  //discarded because of an unknown or unsupported protocol
934  IPV4_SYSTEM_STATS_INC_COUNTER32(inUnknownProtos, 1);
935  IPV4_IF_STATS_INC_COUNTER32(inUnknownProtos, 1);
936  break;
937 
939  //Number of input IP datagrams discarded because the datagram frame
940  //didn't carry enough data
941  IPV4_SYSTEM_STATS_INC_COUNTER32(inTruncatedPkts, 1);
942  IPV4_IF_STATS_INC_COUNTER32(inTruncatedPkts, 1);
943  break;
944 
945  default:
946  //Just for sanity
947  break;
948  }
949 }
950 
951 #endif
#define ipv4IsMulticastAddr(ipAddr)
Definition: ipv4.h:186
error_t ipv4SelectDefaultGateway(NetInterface *interface, Ipv4Addr srcAddr, Ipv4Addr *defaultGatewayAddr)
Default gateway selection.
Definition: ipv4_misc.c:362
#define NetContext
Definition: net.h:36
bool_t ipv4CompPrefix(Ipv4Addr ipAddr1, Ipv4Addr ipAddr2, size_t length)
Compare IPv4 address prefixes.
Definition: ipv4_misc.c:626
@ ERROR_NO_ADDRESS
Definition: error.h:200
int bool_t
Definition: compiler_port.h:63
#define Ipv4Header
Definition: ipv4.h:36
Ipv4Addr destAddr
Definition: ipv4.h:354
Ipv4Addr addr
IPv4 address.
Definition: ipv4.h:411
@ IPV4_OFFSET_MASK
Definition: ipv4.h:264
@ IPV4_ADDR_SCOPE_LINK_LOCAL
Definition: ipv4.h:215
#define IPV4_IF_STATS_INC_COUNTER64(name, value)
Definition: ipv4.h:194
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
bool_t ipv4IsBroadcastAddr(NetInterface *interface, Ipv4Addr ipAddr)
Check whether an IPv4 address is a broadcast address.
Definition: ipv4_misc.c:475
#define IPV4_MULTICAST_LNCB_PREFIX
Definition: ipv4.h:146
#define TRUE
Definition: os_port.h:50
@ ERROR_INVALID_HEADER
Definition: error.h:87
#define ipv4IsOnSubnet(entry, ipAddr)
Definition: ipv4.h:174
Ipv4AddrState state
IPv4 address state.
Definition: ipv4.h:412
uint_t ipv4GetPrefixLength(Ipv4Addr mask)
Calculate prefix length for a given subnet mask.
Definition: ipv4_misc.c:726
#define IPV4_ADDR(a, b, c, d)
Definition: ipv4.h:124
Ipv4RouterAlertOption
Definition: ipv4.h:394
uint32_t Ipv4Addr
IPv4 network address.
Definition: ipv4.h:322
error_t ipv4CheckDestAddr(NetInterface *interface, Ipv4Addr ipAddr)
Destination IPv4 address filtering.
Definition: ipv4_misc.c:114
Helper functions for IPv4.
#define FALSE
Definition: os_port.h:46
void ipv4UpdateErrorStats(NetInterface *interface, error_t error)
Update Ethernet error statistics.
Definition: ipv4_misc.c:913
Ipv4Addr defaultGateway
Default gateway.
Definition: ipv4.h:415
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
#define htonl(value)
Definition: cpu_endian.h:414
error_t
Error codes.
Definition: error.h:43
@ IPV4_ADDR_STATE_TENTATIVE
An address whose uniqueness on a link is being verified.
Definition: ipv4.h:227
@ ERROR_PROTOCOL_UNREACHABLE
Definition: error.h:84
void ipv4UpdateInStats(NetInterface *interface, Ipv4Addr destIpAddr, size_t length)
Update IPv4 input statistics.
Definition: ipv4_misc.c:834
@ ERROR_INVALID_ADDRESS
Definition: error.h:103
error_t ipv4SelectSourceAddr(NetContext *context, NetInterface **interface, Ipv4Addr destAddr, Ipv4Addr *srcAddr)
IPv4 source address selection.
Definition: ipv4_misc.c:173
@ IPV4_FLAG_MF
Definition: ipv4.h:263
#define NetInterface
Definition: net.h:40
bool_t ipv4IsHostAddrValid(NetInterface *interface)
Check whether a valid IPv4 address has been assigned to the interface.
Definition: ipv4_misc.c:403
@ ERROR_INVALID_LENGTH
Definition: error.h:111
bool_t ipv4IsTentativeAddr(NetInterface *interface, Ipv4Addr ipAddr)
Check whether an IPv4 address is a tentative address.
Definition: ipv4_misc.c:529
uint8_t mask
Definition: web_socket.h:319
void ipv4UpdateOutStats(NetInterface *interface, Ipv4Addr destIpAddr, size_t length)
Update IPv4 output statistics.
Definition: ipv4_misc.c:869
#define IPV4_ADDR_LIST_SIZE
Definition: ipv4.h:80
uint8_t length
Definition: tcp.h:375
bool_t ipv4IsOnLink(NetInterface *interface, Ipv4Addr ipAddr)
Check whether an IPv4 address is on-link.
Definition: ipv4_misc.c:437
IPv4 address entry.
Definition: ipv4.h:410
#define IPV4_BROADCAST_ADDR
Definition: ipv4.h:130
bool_t ipv4TrapIgmpPacket(Ipv4Header *header)
Trap IGMP packets.
Definition: ipv4_misc.c:804
@ ERROR_NO_ROUTE
Definition: error.h:221
#define IPV4_LINK_LOCAL_PREFIX
Definition: ipv4.h:138
@ IPV4_PROTOCOL_IGMP
Definition: ipv4.h:276
@ IPV4_ADDR_SCOPE_INTERFACE_LOCAL
Definition: ipv4.h:214
#define IPV4_LOOPBACK_MASK
Definition: ipv4.h:135
#define ntohs(value)
Definition: cpu_endian.h:421
#define IPV4_SYSTEM_STATS_INC_COUNTER32(name, value)
Definition: ipv4.h:191
#define TRACE_WARNING(...)
Definition: debug.h:93
Ipv4Addr subnetMask
Subnet mask.
Definition: ipv4.h:414
#define IPV4_SYSTEM_STATS_INC_COUNTER64(name, value)
Definition: ipv4.h:192
#define IPV4_LOOPBACK_PREFIX
Definition: ipv4.h:134
#define HTONS(value)
Definition: cpu_endian.h:410
@ IPV4_ADDR_STATE_INVALID
An address that is not assigned to any interface.
Definition: ipv4.h:226
error_t ipv4GetBroadcastAddr(NetInterface *interface, Ipv4Addr *addr)
Get IPv4 broadcast address.
Definition: ipv4_misc.c:754
MacAddr srcAddr
Definition: ethernet.h:222
#define IPV4_IF_STATS_INC_COUNTER32(name, value)
Definition: ipv4.h:193
@ IPV4_OPTION_RTRALT
Router Alert.
Definition: ipv4.h:310
#define ipv4IsLoopbackAddr(ipAddr)
Definition: ipv4.h:178
void * netBufferAt(const NetBuffer *buffer, size_t offset, size_t length)
Returns a pointer to a data segment.
Definition: net_mem.c:418
Ipv4Addr ipAddr
Definition: ipcp.h:105
error_t ipv4CheckSourceAddr(NetInterface *interface, Ipv4Addr ipAddr)
Source IPv4 address filtering.
Definition: ipv4_misc.c:90
@ IPV4_ADDR_STATE_VALID
An address assigned to an interface whose use is unrestricted.
Definition: ipv4.h:228
Ipv4Addr addr
Definition: nbns_common.h:141
IPv4 (Internet Protocol Version 4)
unsigned int uint_t
Definition: compiler_port.h:57
error_t ipv4AddRouterAlertOption(NetBuffer *buffer, size_t *offset)
Append a Router Alert option to an IPv4 packet.
Definition: ipv4_misc.c:51
TCP/IP stack core.
bool_t ipv4IsLocalHostAddr(NetContext *context, Ipv4Addr ipAddr)
Check whether the specified IPv4 is assigned to the host.
Definition: ipv4_misc.c:569
#define IPV4_LINK_LOCAL_MASK
Definition: ipv4.h:139
#define ntohl(value)
Definition: cpu_endian.h:422
@ NO_ERROR
Success.
Definition: error.h:44
#define IPV4_MULTICAST_LNCB_MASK
Definition: ipv4.h:147
Debugging facilities.
#define IPV4_UNSPECIFIED_ADDR
Definition: ipv4.h:128
@ IPV4_ADDR_SCOPE_GLOBAL
Definition: ipv4.h:216
uint_t ipv4GetAddrScope(Ipv4Addr ipAddr)
Retrieve the scope of an IPv4 address.
Definition: ipv4_misc.c:662
Ipv4Addr destIpAddr
Definition: ipcp.h:80