ip.c
Go to the documentation of this file.
1 /**
2  * @file ip.c
3  * @brief IPv4 and IPv6 common routines
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2019 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 1.9.6
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL IP_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/net.h"
36 #include "core/ethernet.h"
37 #include "core/ip.h"
38 #include "ipv4/ipv4.h"
39 #include "ipv4/ipv4_misc.h"
40 #include "ipv6/ipv6.h"
41 #include "ipv6/ipv6_misc.h"
42 #include "debug.h"
43 
44 //Special IP addresses
45 const IpAddr IP_ADDR_ANY = {0};
47 
48 
49 /**
50  * @brief Send an IP datagram
51  * @param[in] interface Underlying network interface
52  * @param[in] pseudoHeader IP pseudo header
53  * @param[in] buffer Multi-part buffer containing the payload
54  * @param[in] offset Offset to the first payload byte
55  * @param[in] flags Set of flags that influences the behavior of this function
56  * @return Error code
57  **/
58 
60  NetBuffer *buffer, size_t offset, uint_t flags)
61 {
62  error_t error;
63 
64 #if (IPV4_SUPPORT == ENABLED)
65  //Destination address is an IPv4 address?
66  if(pseudoHeader->length == sizeof(Ipv4PseudoHeader))
67  {
68  //Form an IPv4 packet and send it
69  error = ipv4SendDatagram(interface, &pseudoHeader->ipv4Data,
70  buffer, offset, flags);
71  }
72  else
73 #endif
74 #if (IPV6_SUPPORT == ENABLED)
75  //Destination address is an IPv6 address?
76  if(pseudoHeader->length == sizeof(Ipv6PseudoHeader))
77  {
78  //Form an IPv6 packet and send it
79  error = ipv6SendDatagram(interface, &pseudoHeader->ipv6Data,
80  buffer, offset, flags);
81  }
82  else
83 #endif
84  //Destination address is invalid
85  {
86  //Report an error
87  error = ERROR_INVALID_ADDRESS;
88  }
89 
90  //Return status code
91  return error;
92 }
93 
94 
95 /**
96  * @brief IP source address selection
97  *
98  * This function selects the source address and the relevant network interface
99  * to be used in order to join the specified destination address
100  *
101  * @param[in,out] interface A pointer to a valid network interface may be
102  * provided as a hint. The function returns a pointer identifying the
103  * interface to be used
104  * @param[in] destAddr Destination IP address
105  * @param[out] srcAddr Local IP address to be used
106  * @return Error code
107  **/
108 
110  const IpAddr *destAddr, IpAddr *srcAddr)
111 {
112  error_t error;
113 
114 #if (IPV4_SUPPORT == ENABLED)
115  //The destination address is an IPv4 address?
116  if(destAddr->length == sizeof(Ipv4Addr))
117  {
118  //An IPv4 address is expected
119  srcAddr->length = sizeof(Ipv4Addr);
120 
121  //Get the most appropriate source address to use
122  error = ipv4SelectSourceAddr(interface, destAddr->ipv4Addr,
123  &srcAddr->ipv4Addr);
124  }
125  else
126 #endif
127 #if (IPV6_SUPPORT == ENABLED)
128  //The destination address is an IPv6 address?
129  if(destAddr->length == sizeof(Ipv6Addr))
130  {
131  //An IPv6 address is expected
132  srcAddr->length = sizeof(Ipv6Addr);
133 
134  //Get the most appropriate source address to use
135  error = ipv6SelectSourceAddr(interface, &destAddr->ipv6Addr,
136  &srcAddr->ipv6Addr);
137  }
138  else
139 #endif
140  //The destination address is not valid?
141  {
142  //Report an error
143  error = ERROR_INVALID_ADDRESS;
144  }
145 
146  //Return status code
147  return error;
148 }
149 
150 
151 /**
152  * @brief Compare IP addresses
153  * @param[in] ipAddr1 First IP address
154  * @param[in] ipAddr2 Second IP address
155  * @return Comparison result
156  **/
157 
158 bool_t ipCompAddr(const IpAddr *ipAddr1, const IpAddr *ipAddr2)
159 {
160  bool_t result;
161 
162 #if (IPV4_SUPPORT == ENABLED)
163  //IPv4 addresses?
164  if(ipAddr1->length == sizeof(Ipv4Addr) && ipAddr2->length == sizeof(Ipv4Addr))
165  {
166  //Compare IPv4 addresses
167  if(ipAddr1->ipv4Addr == ipAddr2->ipv4Addr)
168  {
169  result = TRUE;
170  }
171  else
172  {
173  result = FALSE;
174  }
175  }
176  else
177 #endif
178 #if (IPV6_SUPPORT == ENABLED)
179  //IPv6 addresses?
180  if(ipAddr1->length == sizeof(Ipv6Addr) && ipAddr2->length == sizeof(Ipv6Addr))
181  {
182  //Compare IPv6 addresses
183  result = ipv6CompAddr(&ipAddr1->ipv6Addr, &ipAddr2->ipv6Addr);
184  }
185  else
186 #endif
187  //Unspecified IP addresses?
188  if(ipAddr1->length == 0 && ipAddr2->length == 0)
189  {
190  result = TRUE;
191  }
192  //Invalid IP addresses?
193  else
194  {
195  result = FALSE;
196  }
197 
198  //Return TRUE if the IP addresses match, else FALSE
199  return result;
200 }
201 
202 
203 /**
204  * @brief Compare an IP address against the unspecified address
205  * @param[in] ipAddr IP address
206  * @return TRUE if the IP address is unspecified, else FALSE
207  **/
208 
210 {
211  bool_t result;
212 
213 #if (IPV4_SUPPORT == ENABLED)
214  //IPv4 address?
215  if(ipAddr->length == sizeof(Ipv4Addr))
216  {
217  //Compare IPv4 address
218  if(ipAddr->ipv4Addr == IPV4_UNSPECIFIED_ADDR)
219  {
220  result = TRUE;
221  }
222  else
223  {
224  result = FALSE;
225  }
226  }
227  else
228 #endif
229 #if (IPV6_SUPPORT == ENABLED)
230  //IPv6 address?
231  if(ipAddr->length == sizeof(Ipv6Addr))
232  {
233  //Compare IPv6 address
234  result = ipv6CompAddr(&ipAddr->ipv6Addr, &IPV6_UNSPECIFIED_ADDR);
235  }
236  else
237 #endif
238  //Invalid IP address?
239  {
240  result = FALSE;
241  }
242 
243  //Return TRUE if the IP address is unspecified, else FALSE
244  return result;
245 }
246 
247 
248 /**
249  * @brief Determine whether an IP address is a multicast address
250  * @param[in] ipAddr IP address
251  * @return TRUE if the IP address is a multicast address, else FALSE
252  **/
253 
255 {
256  bool_t result;
257 
258 #if (IPV4_SUPPORT == ENABLED)
259  //IPv4 address?
260  if(ipAddr->length == sizeof(Ipv4Addr))
261  {
262  //Check whether the IPv4 address is a multicast address
263  result = ipv4IsMulticastAddr(ipAddr->ipv4Addr);
264  }
265  else
266 #endif
267 #if (IPV6_SUPPORT == ENABLED)
268  //IPv6 address?
269  if(ipAddr->length == sizeof(Ipv6Addr))
270  {
271  //Check whether the IPv6 address is a multicast address
272  result = ipv6IsMulticastAddr(&ipAddr->ipv6Addr);
273  }
274  else
275 #endif
276  //Invalid IP address?
277  {
278  result = FALSE;
279  }
280 
281  //Return TRUE if the IP address is a multicast address, else FALSE
282  return result;
283 }
284 
285 
286 /**
287  * @brief Join the specified host group
288  * @param[in] interface Underlying network interface (optional parameter)
289  * @param[in] groupAddr IP address identifying the host group to join
290  * @return Error code
291  **/
292 
294 {
295  error_t error;
296 
297  //Use default network interface?
298  if(interface == NULL)
299  interface = netGetDefaultInterface();
300 
301  //Get exclusive access
303 
304 #if (IPV4_SUPPORT == ENABLED)
305  //IPv4 multicast address?
306  if(groupAddr->length == sizeof(Ipv4Addr))
307  {
308  //Join the specified host group
309  error = ipv4JoinMulticastGroup(interface, groupAddr->ipv4Addr);
310  }
311  else
312 #endif
313 #if (IPV6_SUPPORT == ENABLED)
314  //IPv6 multicast address?
315  if(groupAddr->length == sizeof(Ipv6Addr))
316  {
317  //Join the specified host group
318  error = ipv6JoinMulticastGroup(interface, &groupAddr->ipv6Addr);
319  }
320  else
321 #endif
322  //Invalid IP address?
323  {
324  //Report an error
325  error = ERROR_INVALID_ADDRESS;
326  }
327 
328  //Release exclusive access
330 
331  //Return status code
332  return error;
333 }
334 
335 
336 /**
337  * @brief Leave the specified host group
338  * @param[in] interface Underlying network interface (optional parameter)
339  * @param[in] groupAddr IP address identifying the host group to leave
340  * @return Error code
341  **/
342 
344 {
345  error_t error;
346 
347  //Use default network interface?
348  if(interface == NULL)
349  interface = netGetDefaultInterface();
350 
351  //Get exclusive access
353 
354 #if (IPV4_SUPPORT == ENABLED)
355  //IPv4 multicast address?
356  if(groupAddr->length == sizeof(Ipv4Addr))
357  {
358  //Drop membership
359  error = ipv4LeaveMulticastGroup(interface, groupAddr->ipv4Addr);
360  }
361  else
362 #endif
363 #if (IPV6_SUPPORT == ENABLED)
364  //IPv6 multicast address?
365  if(groupAddr->length == sizeof(Ipv6Addr))
366  {
367  //Drop membership
368  error = ipv6LeaveMulticastGroup(interface, &groupAddr->ipv6Addr);
369  }
370  else
371 #endif
372  //Invalid IP address?
373  {
374  error = ERROR_INVALID_ADDRESS;
375  }
376 
377  //Release exclusive access
379 
380  //Return status code
381  return error;
382 }
383 
384 
385 /**
386  * @brief IP checksum calculation
387  * @param[in] data Pointer to the data over which to calculate the IP checksum
388  * @param[in] length Number of bytes to process
389  * @return Checksum value
390  **/
391 
392 uint16_t ipCalcChecksum(const void *data, size_t length)
393 {
394  uint32_t temp;
395  uint32_t checksum;
396  const uint8_t *p;
397 
398  //Checksum preset value
399  checksum = 0x0000;
400 
401  //Point to the data over which to calculate the IP checksum
402  p = (const uint8_t *) data;
403 
404  //Pointer not aligned on a 16-bit boundary?
405  if(((uint_t) p & 1) != 0)
406  {
407  if(length >= 1)
408  {
409 #ifdef _CPU_BIG_ENDIAN
410  //Update checksum value
411  checksum += (uint32_t) *p;
412 #else
413  //Update checksum value
414  checksum += (uint32_t) *p << 8;
415 #endif
416  //Restore the alignment on 16-bit boundaries
417  p++;
418  //Number of bytes left to process
419  length--;
420  }
421  }
422 
423  //Pointer not aligned on a 32-bit boundary?
424  if(((uint_t) p & 2) != 0)
425  {
426  if(length >= 2)
427  {
428  //Update checksum value
429  checksum += (uint32_t) *((uint16_t *) p);
430 
431  //Restore the alignment on 32-bit boundaries
432  p += 2;
433  //Number of bytes left to process
434  length -= 2;
435  }
436  }
437 
438  //Process the data 4 bytes at a time
439  while(length >= 4)
440  {
441  //Update checksum value
442  temp = checksum + *((uint32_t *) p);
443 
444  //Add carry bit, if any
445  if(temp < checksum)
446  {
447  checksum = temp + 1;
448  }
449  else
450  {
451  checksum = temp;
452  }
453 
454  //Point to the next 32-bit word
455  p += 4;
456  //Number of bytes left to process
457  length -= 4;
458  }
459 
460  //Fold 32-bit sum to 16 bits
461  checksum = (checksum & 0xFFFF) + (checksum >> 16);
462 
463  //Add left-over 16-bit word, if any
464  if(length >= 2)
465  {
466  //Update checksum value
467  checksum += (uint32_t) *((uint16_t *) p);
468 
469  //Point to the next byte
470  p += 2;
471  //Number of bytes left to process
472  length -= 2;
473  }
474 
475  //Add left-over byte, if any
476  if(length >= 1)
477  {
478 #ifdef _CPU_BIG_ENDIAN
479  //Update checksum value
480  checksum += (uint32_t) *p << 8;
481 #else
482  //Update checksum value
483  checksum += (uint32_t) *p;
484 #endif
485  }
486 
487  //Fold 32-bit sum to 16 bits (first pass)
488  checksum = (checksum & 0xFFFF) + (checksum >> 16);
489  //Fold 32-bit sum to 16 bits (second pass)
490  checksum = (checksum & 0xFFFF) + (checksum >> 16);
491 
492  //Restore checksum endianness
493  if(((uint_t) data & 1) != 0)
494  {
495  //Swap checksum value
496  checksum = ((checksum >> 8) | (checksum << 8)) & 0xFFFF;
497  }
498 
499  //Return 1's complement value
500  return checksum ^ 0xFFFF;
501 }
502 
503 
504 /**
505  * @brief Calculate IP checksum over a multi-part buffer
506  * @param[in] buffer Pointer to the multi-part buffer
507  * @param[in] offset Offset from the beginning of the buffer
508  * @param[in] length Number of bytes to process
509  * @return Checksum value
510  **/
511 
512 uint16_t ipCalcChecksumEx(const NetBuffer *buffer, size_t offset, size_t length)
513 {
514  uint_t i;
515  uint_t n;
516  uint_t pos;
517  uint8_t *data;
518  uint32_t checksum;
519 
520  //Checksum preset value
521  checksum = 0x0000;
522 
523  //Current position in the multi-part buffer
524  pos = 0;
525 
526  //Loop through data chunks
527  for(i = 0; i < buffer->chunkCount && pos < length; i++)
528  {
529  //Is there any data to process in the current chunk?
530  if(offset < buffer->chunk[i].length)
531  {
532  //Point to the first data byte
533  data = (uint8_t *) buffer->chunk[i].address + offset;
534 
535  //Number of bytes available in the current chunk
536  n = buffer->chunk[i].length - offset;
537  //Limit the number of byte to process
538  n = MIN(n, length - pos);
539 
540  //Take care of alignment issues
541  if((pos & 1) != 0)
542  {
543  //Swap checksum value
544  checksum = ((checksum >> 8) | (checksum << 8)) & 0xFFFF;
545  }
546 
547  //Process data chunk
548  checksum += ipCalcChecksum(data, n) ^ 0xFFFF;
549  //Fold 32-bit sum to 16 bits
550  checksum = (checksum & 0xFFFF) + (checksum >> 16);
551 
552  //Restore checksum endianness
553  if((pos & 1) != 0)
554  {
555  //Swap checksum value
556  checksum = ((checksum >> 8) | (checksum << 8)) & 0xFFFF;
557  }
558 
559  //Advance current position
560  pos += n;
561  //Process the next block from the start
562  offset = 0;
563  }
564  else
565  {
566  //Skip the current chunk
567  offset -= buffer->chunk[i].length;
568  }
569  }
570 
571  //Return 1's complement value
572  return checksum ^ 0xFFFF;
573 }
574 
575 
576 /**
577  * @brief Calculate IP upper-layer checksum
578  * @param[in] pseudoHeader Pointer to the pseudo header
579  * @param[in] pseudoHeaderLen Pseudo header length
580  * @param[in] data Pointer to the upper-layer data
581  * @param[in] dataLen Upper-layer data length
582  * @return Checksum value
583  **/
584 
585 uint16_t ipCalcUpperLayerChecksum(const void *pseudoHeader,
586  size_t pseudoHeaderLen, const void *data, size_t dataLen)
587 {
588  uint32_t checksum;
589 
590  //Process pseudo header
591  checksum = ipCalcChecksum(pseudoHeader, pseudoHeaderLen) ^ 0xFFFF;
592  //Process upper-layer data
593  checksum += ipCalcChecksum(data, dataLen) ^ 0xFFFF;
594  //Fold 32-bit sum to 16 bits
595  checksum = (checksum & 0xFFFF) + (checksum >> 16);
596 
597  //Return 1's complement value
598  return checksum ^ 0xFFFF;
599 }
600 
601 
602 /**
603  * @brief Calculate IP upper-layer checksum over a multi-part buffer
604  * @param[in] pseudoHeader Pointer to the pseudo header
605  * @param[in] pseudoHeaderLen Pseudo header length
606  * @param[in] buffer Multi-part buffer containing the upper-layer data
607  * @param[in] offset Offset from the first data byte to process
608  * @param[in] length Number of data bytes to process
609  * @return Checksum value
610  **/
611 
612 uint16_t ipCalcUpperLayerChecksumEx(const void *pseudoHeader,
613  size_t pseudoHeaderLen, const NetBuffer *buffer, size_t offset, size_t length)
614 {
615  uint32_t checksum;
616 
617  //Process pseudo header
618  checksum = ipCalcChecksum(pseudoHeader, pseudoHeaderLen) ^ 0xFFFF;
619  //Process upper-layer data
620  checksum += ipCalcChecksumEx(buffer, offset, length) ^ 0xFFFF;
621  //Fold 32-bit sum to 16 bits
622  checksum = (checksum & 0xFFFF) + (checksum >> 16);
623 
624  //Return 1's complement value
625  return checksum ^ 0xFFFF;
626 }
627 
628 
629 /**
630  * @brief Allocate a buffer to hold an IP packet
631  * @param[in] length Desired payload length
632  * @param[out] offset Offset to the first byte of the payload
633  * @return The function returns a pointer to the newly allocated
634  * buffer. If the system is out of resources, NULL is returned
635  **/
636 
637 NetBuffer *ipAllocBuffer(size_t length, size_t *offset)
638 {
639  size_t headerLen;
640  NetBuffer *buffer;
641 
642 #if (IPV6_SUPPORT == ENABLED)
643  //Maximum overhead when using IPv6
644  headerLen = sizeof(Ipv6Header) + sizeof(Ipv6FragmentHeader);
645 #else
646  //Maximum overhead when using IPv4
647  headerLen = sizeof(Ipv4Header);
648 #endif
649 
650 #if (ETH_SUPPORT == ENABLED)
651  //Allocate a buffer to hold the Ethernet header and the IP packet
652  buffer = ethAllocBuffer(length + headerLen, offset);
653 #elif (PPP_SUPPORT == ENABLED)
654  //Allocate a buffer to hold the PPP header and the IP packet
655  buffer = pppAllocBuffer(length + headerLen, offset);
656 #else
657  //Allocate a buffer to hold the IP packet
658  buffer = netBufferAlloc(length + headerLen);
659  //Clear offset value
660  *offset = 0;
661 #endif
662 
663  //Successful memory allocation?
664  if(buffer != NULL)
665  {
666  //Offset to the first byte of the payload
667  *offset += headerLen;
668  }
669 
670  //Return a pointer to the freshly allocated buffer
671  return buffer;
672 }
673 
674 
675 /**
676  * @brief Convert a string representation of an IP address to a binary IP address
677  * @param[in] str NULL-terminated string representing the IP address
678  * @param[out] ipAddr Binary representation of the IP address
679  * @return Error code
680  **/
681 
683 {
684  error_t error;
685 
686 #if (IPV6_SUPPORT == ENABLED)
687  //IPv6 address?
688  if(strchr(str, ':'))
689  {
690  //IPv6 addresses are 16-byte long
691  ipAddr->length = sizeof(Ipv6Addr);
692  //Convert the string to IPv6 address
693  error = ipv6StringToAddr(str, &ipAddr->ipv6Addr);
694  }
695  else
696 #endif
697 #if (IPV4_SUPPORT == ENABLED)
698  //IPv4 address?
699  if(strchr(str, '.'))
700  {
701  //IPv4 addresses are 4-byte long
702  ipAddr->length = sizeof(Ipv4Addr);
703  //Convert the string to IPv4 address
704  error = ipv4StringToAddr(str, &ipAddr->ipv4Addr);
705  }
706  else
707 #endif
708  //Invalid IP address?
709  {
710  //Report an error
711  error = ERROR_FAILURE;
712  }
713 
714  //Return status code
715  return error;
716 }
717 
718 
719 /**
720  * @brief Convert a binary IP address to a string representation
721  * @param[in] ipAddr Binary representation of the IP address
722  * @param[out] str NULL-terminated string representing the IP address
723  * @return Pointer to the formatted string
724  **/
725 
727 {
728 #if (IPV4_SUPPORT == ENABLED)
729  //IPv4 address?
730  if(ipAddr->length == sizeof(Ipv4Addr))
731  {
732  //Convert IPv4 address to string representation
733  return ipv4AddrToString(ipAddr->ipv4Addr, str);
734  }
735  else
736 #endif
737 #if (IPV6_SUPPORT == ENABLED)
738  //IPv6 address?
739  if(ipAddr->length == sizeof(Ipv6Addr))
740  {
741  //Convert IPv6 address to string representation
742  return ipv6AddrToString(&ipAddr->ipv6Addr, str);
743  }
744  else
745 #endif
746  //Invalid IP address?
747  {
748  static char_t c;
749 
750  //The last parameter is optional
751  if(str == NULL)
752  {
753  str = &c;
754  }
755 
756  //Properly terminate the string
757  str[0] = '\0';
758 
759  //Return an empty string
760  return str;
761  }
762 }
#define ipv4IsMulticastAddr(ipAddr)
Definition: ipv4.h:162
char_t * ipv6AddrToString(const Ipv6Addr *ipAddr, char_t *str)
Convert a binary IPv6 address to a string representation.
Definition: ipv6.c:2254
IPv6 (Internet Protocol Version 6)
uint8_t length
Definition: dtls_misc.h:149
NetBuffer * ipAllocBuffer(size_t length, size_t *offset)
Allocate a buffer to hold an IP packet.
Definition: ip.c:637
Ipv6PseudoHeader ipv6Data
Definition: ip.h:99
int bool_t
Definition: compiler_port.h:49
#define Ipv4Header
Definition: ipv4.h:36
error_t ipJoinMulticastGroup(NetInterface *interface, const IpAddr *groupAddr)
Join the specified host group.
Definition: ip.c:293
uint16_t ipCalcChecksumEx(const NetBuffer *buffer, size_t offset, size_t length)
Calculate IP checksum over a multi-part buffer.
Definition: ip.c:512
MacAddr srcAddr
Definition: ethernet.h:193
IP network address.
Definition: ip.h:71
uint8_t p
Definition: ndp.h:298
uint16_t checksum
Definition: tcp.h:318
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:88
uint_t chunkCount
Definition: net_mem.h:90
const IpAddr IP_ADDR_UNSPECIFIED
Definition: ip.c:46
#define TRUE
Definition: os_port.h:50
#define Ipv6Header
Definition: ipv6.h:36
error_t ipv4SendDatagram(NetInterface *interface, Ipv4PseudoHeader *pseudoHeader, NetBuffer *buffer, size_t offset, uint_t flags)
Send an IPv4 datagram.
Definition: ipv4.c:878
char_t * ipAddrToString(const IpAddr *ipAddr, char_t *str)
Convert a binary IP address to a string representation.
Definition: ip.c:726
error_t ipv4SelectSourceAddr(NetInterface **interface, Ipv4Addr destAddr, Ipv4Addr *srcAddr)
IPv4 source address selection.
Definition: ipv4_misc.c:163
error_t ipv6SendDatagram(NetInterface *interface, Ipv6PseudoHeader *pseudoHeader, NetBuffer *buffer, size_t offset, uint_t flags)
Send an IPv6 datagram.
Definition: ipv6.c:1576
#define ipv6CompAddr(ipAddr1, ipAddr2)
Definition: ipv6.h:121
error_t ipSendDatagram(NetInterface *interface, IpPseudoHeader *pseudoHeader, NetBuffer *buffer, size_t offset, uint_t flags)
Send an IP datagram.
Definition: ip.c:59
NetBuffer * pppAllocBuffer(size_t length, size_t *offset)
Allocate a buffer to hold a PPP frame.
Definition: ppp.c:1265
size_t length
Definition: ip.h:92
uint32_t Ipv4Addr
IPv4 network address.
Definition: ipv4.h:239
Ethernet.
MacAddr destAddr
Definition: ethernet.h:192
IP pseudo header.
Definition: ip.h:90
error_t ipStringToAddr(const char_t *str, IpAddr *ipAddr)
Convert a string representation of an IP address to a binary IP address.
Definition: ip.c:682
const IpAddr IP_ADDR_ANY
Definition: ip.c:45
#define ipv6IsMulticastAddr(ipAddr)
Definition: ipv6.h:133
Helper functions for IPv4.
uint16_t length
Definition: net_mem.h:79
#define FALSE
Definition: os_port.h:46
error_t
Error codes.
Definition: error.h:42
bool_t ipCompAddr(const IpAddr *ipAddr1, const IpAddr *ipAddr2)
Compare IP addresses.
Definition: ip.c:158
bool_t ipIsMulticastAddr(const IpAddr *ipAddr)
Determine whether an IP address is a multicast address.
Definition: ip.c:254
#define Ipv6PseudoHeader
Definition: ipv6.h:42
error_t ipv6SelectSourceAddr(NetInterface **interface, const Ipv6Addr *destAddr, Ipv6Addr *srcAddr)
IPv6 source address selection.
Definition: ipv6_misc.c:882
void * address
Definition: net_mem.h:78
@ ERROR_INVALID_ADDRESS
Definition: error.h:102
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
error_t ipSelectSourceAddr(NetInterface **interface, const IpAddr *destAddr, IpAddr *srcAddr)
IP source address selection.
Definition: ip.c:109
#define NetInterface
Definition: net.h:36
NetInterface * netGetDefaultInterface(void)
Get default network interface.
Definition: net.c:1782
Helper functions for IPv6.
OsMutex netMutex
Definition: net.c:75
bool_t ipIsUnspecifiedAddr(const IpAddr *ipAddr)
Compare an IP address against the unspecified address.
Definition: ip.c:209
const Ipv6Addr IPV6_UNSPECIFIED_ADDR
Definition: ipv6.c:67
error_t ipv6LeaveMulticastGroup(NetInterface *interface, const Ipv6Addr *groupAddr)
Leave an IPv6 multicast group.
Definition: ipv6.c:2038
__start_packed struct @179 Ipv6Addr
IPv6 network address.
error_t ipv6JoinMulticastGroup(NetInterface *interface, const Ipv6Addr *groupAddr)
Join an IPv6 multicast group.
Definition: ipv6.c:1928
#define Ipv4PseudoHeader
Definition: ipv4.h:39
#define MIN(a, b)
Definition: os_port.h:62
size_t length
Definition: ip.h:73
NetBuffer * netBufferAlloc(size_t length)
Allocate a multi-part buffer.
Definition: net_mem.c:243
uint16_t ipCalcUpperLayerChecksum(const void *pseudoHeader, size_t pseudoHeaderLen, const void *data, size_t dataLen)
Calculate IP upper-layer checksum.
Definition: ip.c:585
uint8_t flags
Definition: tcp.h:314
char char_t
Definition: compiler_port.h:43
Ipv4Addr ipv4Addr
Definition: ip.h:77
ChunkDesc chunk[]
Definition: net_mem.h:92
uint16_t ipCalcUpperLayerChecksumEx(const void *pseudoHeader, size_t pseudoHeaderLen, const NetBuffer *buffer, size_t offset, size_t length)
Calculate IP upper-layer checksum over a multi-part buffer.
Definition: ip.c:612
IPv4 and IPv6 common routines.
uint8_t n
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
Ipv4Addr groupAddr
Definition: igmp.h:127
#define Ipv6FragmentHeader
Definition: ipv6.h:39
error_t ipv4StringToAddr(const char_t *str, Ipv4Addr *ipAddr)
Convert a dot-decimal string to a binary IPv4 address.
Definition: ipv4.c:1379
error_t ipv6StringToAddr(const char_t *str, Ipv6Addr *ipAddr)
Convert a string representation of an IPv6 address to a binary IPv6 address.
Definition: ipv6.c:2114
error_t ipv4JoinMulticastGroup(NetInterface *interface, Ipv4Addr groupAddr)
Join the specified host group.
Definition: ipv4.c:1194
IPv4 (Internet Protocol Version 4)
error_t ipv4LeaveMulticastGroup(NetInterface *interface, Ipv4Addr groupAddr)
Leave the specified host group.
Definition: ipv4.c:1303
Ipv6Addr ipv6Addr
Definition: ip.h:80
NetBuffer * ethAllocBuffer(size_t length, size_t *offset)
Allocate a buffer to hold an Ethernet frame.
Definition: ethernet.c:641
unsigned int uint_t
Definition: compiler_port.h:45
TCP/IP stack core.
uint8_t data[]
Definition: dtls_misc.h:176
error_t ipLeaveMulticastGroup(NetInterface *interface, const IpAddr *groupAddr)
Leave the specified host group.
Definition: ip.c:343
char_t * ipv4AddrToString(Ipv4Addr ipAddr, char_t *str)
Convert a binary IPv4 address to dot-decimal notation.
Definition: ipv4.c:1466
uint8_t ipAddr[4]
Definition: mib_common.h:187
Ipv4PseudoHeader ipv4Data
Definition: ip.h:96
uint8_t c
Definition: ndp.h:513
Debugging facilities.
#define IPV4_UNSPECIFIED_ADDR
Definition: ipv4.h:104
uint16_t ipCalcChecksum(const void *data, size_t length)
IP checksum calculation.
Definition: ip.c:392