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