1 /** @file
2 * @brief IPv6 and IPv4 definitions
3 *
4 * Generic IPv6 and IPv4 address definitions.
5 */
6
7 /*
8 * Copyright (c) 2016 Intel Corporation
9 *
10 * SPDX-License-Identifier: Apache-2.0
11 */
12
13 #ifndef ZEPHYR_INCLUDE_NET_NET_IP_H_
14 #define ZEPHYR_INCLUDE_NET_NET_IP_H_
15
16 /**
17 * @brief IPv4/IPv6 primitives and helpers
18 * @defgroup ip_4_6 IPv4/IPv6 primitives and helpers
19 * @ingroup networking
20 * @{
21 */
22
23 #include <string.h>
24 #include <zephyr/types.h>
25 #include <stdbool.h>
26 #include <zephyr/sys/util.h>
27 #include <zephyr/sys/byteorder.h>
28 #include <zephyr/toolchain.h>
29
30 #include <zephyr/net/net_linkaddr.h>
31
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35
36 /** @cond INTERNAL_HIDDEN */
37 /* Specifying VLAN tag here in order to avoid circular dependencies */
38 #define NET_VLAN_TAG_UNSPEC 0x0fff
39 /** @endcond */
40
41 /* Protocol families. */
42 #define PF_UNSPEC 0 /**< Unspecified protocol family. */
43 #define PF_INET 1 /**< IP protocol family version 4. */
44 #define PF_INET6 2 /**< IP protocol family version 6. */
45 #define PF_PACKET 3 /**< Packet family. */
46 #define PF_CAN 4 /**< Controller Area Network. */
47 #define PF_NET_MGMT 5 /**< Network management info. */
48 #define PF_LOCAL 6 /**< Inter-process communication */
49 #define PF_UNIX PF_LOCAL /**< Inter-process communication */
50
51 /* Address families. */
52 #define AF_UNSPEC PF_UNSPEC /**< Unspecified address family. */
53 #define AF_INET PF_INET /**< IP protocol family version 4. */
54 #define AF_INET6 PF_INET6 /**< IP protocol family version 6. */
55 #define AF_PACKET PF_PACKET /**< Packet family. */
56 #define AF_CAN PF_CAN /**< Controller Area Network. */
57 #define AF_NET_MGMT PF_NET_MGMT /**< Network management info. */
58 #define AF_LOCAL PF_LOCAL /**< Inter-process communication */
59 #define AF_UNIX PF_UNIX /**< Inter-process communication */
60
61 /** Protocol numbers from IANA/BSD */
62 enum net_ip_protocol {
63 IPPROTO_IP = 0, /**< IP protocol (pseudo-val for setsockopt() */
64 IPPROTO_ICMP = 1, /**< ICMP protocol */
65 IPPROTO_IGMP = 2, /**< IGMP protocol */
66 IPPROTO_IPIP = 4, /**< IPIP tunnels */
67 IPPROTO_TCP = 6, /**< TCP protocol */
68 IPPROTO_UDP = 17, /**< UDP protocol */
69 IPPROTO_IPV6 = 41, /**< IPv6 protocol */
70 IPPROTO_ICMPV6 = 58, /**< ICMPv6 protocol */
71 IPPROTO_RAW = 255, /**< RAW IP packets */
72 };
73
74 /** Protocol numbers for TLS protocols */
75 enum net_ip_protocol_secure {
76 IPPROTO_TLS_1_0 = 256, /**< TLS 1.0 protocol */
77 IPPROTO_TLS_1_1 = 257, /**< TLS 1.1 protocol */
78 IPPROTO_TLS_1_2 = 258, /**< TLS 1.2 protocol */
79 IPPROTO_DTLS_1_0 = 272, /**< DTLS 1.0 protocol */
80 IPPROTO_DTLS_1_2 = 273, /**< DTLS 1.2 protocol */
81 };
82
83 /** Socket type */
84 enum net_sock_type {
85 SOCK_STREAM = 1, /**< Stream socket type */
86 SOCK_DGRAM, /**< Datagram socket type */
87 SOCK_RAW /**< RAW socket type */
88 };
89
90 /** @brief Convert 16-bit value from network to host byte order.
91 *
92 * @param x The network byte order value to convert.
93 *
94 * @return Host byte order value.
95 */
96 #define ntohs(x) sys_be16_to_cpu(x)
97
98 /** @brief Convert 32-bit value from network to host byte order.
99 *
100 * @param x The network byte order value to convert.
101 *
102 * @return Host byte order value.
103 */
104 #define ntohl(x) sys_be32_to_cpu(x)
105
106 /** @brief Convert 64-bit value from network to host byte order.
107 *
108 * @param x The network byte order value to convert.
109 *
110 * @return Host byte order value.
111 */
112 #define ntohll(x) sys_be64_to_cpu(x)
113
114 /** @brief Convert 16-bit value from host to network byte order.
115 *
116 * @param x The host byte order value to convert.
117 *
118 * @return Network byte order value.
119 */
120 #define htons(x) sys_cpu_to_be16(x)
121
122 /** @brief Convert 32-bit value from host to network byte order.
123 *
124 * @param x The host byte order value to convert.
125 *
126 * @return Network byte order value.
127 */
128 #define htonl(x) sys_cpu_to_be32(x)
129
130 /** @brief Convert 64-bit value from host to network byte order.
131 *
132 * @param x The host byte order value to convert.
133 *
134 * @return Network byte order value.
135 */
136 #define htonll(x) sys_cpu_to_be64(x)
137
138 /** IPv6 address struct */
139 struct in6_addr {
140 union {
141 uint8_t s6_addr[16];
142 uint16_t s6_addr16[8]; /* In big endian */
143 uint32_t s6_addr32[4]; /* In big endian */
144 };
145 };
146
147 /* Binary size of the IPv6 address */
148 #define NET_IPV6_ADDR_SIZE 16
149
150 /** IPv4 address struct */
151 struct in_addr {
152 union {
153 uint8_t s4_addr[4];
154 uint16_t s4_addr16[2]; /* In big endian */
155 uint32_t s4_addr32[1]; /* In big endian */
156 uint32_t s_addr; /* In big endian, for POSIX compatibility. */
157 };
158 };
159
160 /* Binary size of the IPv4 address */
161 #define NET_IPV4_ADDR_SIZE 4
162
163 /** Socket address family type */
164 typedef unsigned short int sa_family_t;
165
166 /** Length of a socket address */
167 #ifndef __socklen_t_defined
168 typedef size_t socklen_t;
169 #define __socklen_t_defined
170 #endif
171
172 /*
173 * Note that the sin_port and sin6_port are in network byte order
174 * in various sockaddr* structs.
175 */
176
177 /** Socket address struct for IPv6. */
178 struct sockaddr_in6 {
179 sa_family_t sin6_family; /* AF_INET6 */
180 uint16_t sin6_port; /* Port number */
181 struct in6_addr sin6_addr; /* IPv6 address */
182 uint8_t sin6_scope_id; /* interfaces for a scope */
183 };
184
185 struct sockaddr_in6_ptr {
186 sa_family_t sin6_family; /* AF_INET6 */
187 uint16_t sin6_port; /* Port number */
188 struct in6_addr *sin6_addr; /* IPv6 address */
189 uint8_t sin6_scope_id; /* interfaces for a scope */
190 };
191
192 /** Socket address struct for IPv4. */
193 struct sockaddr_in {
194 sa_family_t sin_family; /* AF_INET */
195 uint16_t sin_port; /* Port number */
196 struct in_addr sin_addr; /* IPv4 address */
197 };
198
199 struct sockaddr_in_ptr {
200 sa_family_t sin_family; /* AF_INET */
201 uint16_t sin_port; /* Port number */
202 struct in_addr *sin_addr; /* IPv4 address */
203 };
204
205 /** Socket address struct for packet socket. */
206 struct sockaddr_ll {
207 sa_family_t sll_family; /* Always AF_PACKET */
208 uint16_t sll_protocol; /* Physical-layer protocol */
209 int sll_ifindex; /* Interface number */
210 uint16_t sll_hatype; /* ARP hardware type */
211 uint8_t sll_pkttype; /* Packet type */
212 uint8_t sll_halen; /* Length of address */
213 uint8_t sll_addr[8]; /* Physical-layer address, big endian */
214 };
215
216 struct sockaddr_ll_ptr {
217 sa_family_t sll_family; /* Always AF_PACKET */
218 uint16_t sll_protocol; /* Physical-layer protocol */
219 int sll_ifindex; /* Interface number */
220 uint16_t sll_hatype; /* ARP hardware type */
221 uint8_t sll_pkttype; /* Packet type */
222 uint8_t sll_halen; /* Length of address */
223 uint8_t *sll_addr; /* Physical-layer address, big endian */
224 };
225
226 struct sockaddr_can_ptr {
227 sa_family_t can_family;
228 int can_ifindex;
229 };
230
231 #if !defined(HAVE_IOVEC)
232 struct iovec {
233 void *iov_base;
234 size_t iov_len;
235 };
236 #endif
237
238 struct msghdr {
239 void *msg_name; /* optional socket address, big endian */
240 socklen_t msg_namelen; /* size of socket address */
241 struct iovec *msg_iov; /* scatter/gather array */
242 size_t msg_iovlen; /* number of elements in msg_iov */
243 void *msg_control; /* ancillary data */
244 size_t msg_controllen; /* ancillary data buffer len */
245 int msg_flags; /* flags on received message */
246 };
247
248 struct cmsghdr {
249 socklen_t cmsg_len; /* Number of bytes, including header */
250 int cmsg_level; /* Originating protocol */
251 int cmsg_type; /* Protocol-specific type */
252 /* Flexible array member to force alignment of cmsghdr */
253 z_max_align_t cmsg_data[];
254 };
255
256 /* Alignment for headers and data. These are arch specific but define
257 * them here atm if not found alredy.
258 */
259 #if !defined(ALIGN_H)
260 #define ALIGN_H(x) ROUND_UP(x, __alignof__(struct cmsghdr))
261 #endif
262 #if !defined(ALIGN_D)
263 #define ALIGN_D(x) ROUND_UP(x, __alignof__(z_max_align_t))
264 #endif
265
266 #if !defined(CMSG_FIRSTHDR)
267 #define CMSG_FIRSTHDR(msghdr) \
268 ((msghdr)->msg_controllen >= sizeof(struct cmsghdr) ? \
269 (struct cmsghdr *)((msghdr)->msg_control) : NULL)
270 #endif
271
272 #if !defined(CMSG_NXTHDR)
273 #define CMSG_NXTHDR(msghdr, cmsg) \
274 (((cmsg) == NULL) ? CMSG_FIRSTHDR(msghdr) : \
275 (((uint8_t *)(cmsg) + ALIGN_H((cmsg)->cmsg_len) + \
276 ALIGN_D(sizeof(struct cmsghdr)) > \
277 (uint8_t *)((msghdr)->msg_control) + (msghdr)->msg_controllen) ? \
278 NULL : \
279 (struct cmsghdr *)((uint8_t *)(cmsg) + \
280 ALIGN_H((cmsg)->cmsg_len))))
281 #endif
282
283 #if !defined(CMSG_DATA)
284 #define CMSG_DATA(cmsg) ((uint8_t *)(cmsg) + ALIGN_D(sizeof(struct cmsghdr)))
285 #endif
286
287 #if !defined(CMSG_SPACE)
288 #define CMSG_SPACE(length) (ALIGN_D(sizeof(struct cmsghdr)) + ALIGN_H(length))
289 #endif
290
291 #if !defined(CMSG_LEN)
292 #define CMSG_LEN(length) (ALIGN_D(sizeof(struct cmsghdr)) + length)
293 #endif
294
295 /** @cond INTERNAL_HIDDEN */
296
297 /* Packet types. */
298 #define PACKET_HOST 0 /* To us */
299 #define PACKET_BROADCAST 1 /* To all */
300 #define PACKET_MULTICAST 2 /* To group */
301 #define PACKET_OTHERHOST 3 /* To someone else */
302 #define PACKET_OUTGOING 4 /* Originated by us */
303 #define PACKET_LOOPBACK 5
304 #define PACKET_FASTROUTE 6
305
306 /* ARP protocol HARDWARE identifiers. */
307 #define ARPHRD_ETHER 1
308
309 /* Note: These macros are defined in a specific order.
310 * The largest sockaddr size is the last one.
311 */
312 #if defined(CONFIG_NET_IPV4)
313 #undef NET_SOCKADDR_MAX_SIZE
314 #undef NET_SOCKADDR_PTR_MAX_SIZE
315 #define NET_SOCKADDR_MAX_SIZE (sizeof(struct sockaddr_in))
316 #define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct sockaddr_in_ptr))
317 #endif
318
319 #if defined(CONFIG_NET_SOCKETS_PACKET)
320 #undef NET_SOCKADDR_MAX_SIZE
321 #undef NET_SOCKADDR_PTR_MAX_SIZE
322 #define NET_SOCKADDR_MAX_SIZE (sizeof(struct sockaddr_ll))
323 #define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct sockaddr_ll_ptr))
324 #endif
325
326 #if defined(CONFIG_NET_IPV6)
327 #undef NET_SOCKADDR_MAX_SIZE
328 #define NET_SOCKADDR_MAX_SIZE (sizeof(struct sockaddr_in6))
329 #if !defined(CONFIG_NET_SOCKETS_PACKET)
330 #undef NET_SOCKADDR_PTR_MAX_SIZE
331 #define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct sockaddr_in6_ptr))
332 #endif
333 #endif
334
335 #if !defined(CONFIG_NET_IPV4)
336 #if !defined(CONFIG_NET_IPV6)
337 #if !defined(CONFIG_NET_SOCKETS_PACKET)
338 #define NET_SOCKADDR_MAX_SIZE (sizeof(struct sockaddr_in6))
339 #define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct sockaddr_in6_ptr))
340 #endif
341 #endif
342 #endif
343
344 /** @endcond */
345
346 /** Generic sockaddr struct. Must be cast to proper type. */
347 struct sockaddr {
348 sa_family_t sa_family;
349 char data[NET_SOCKADDR_MAX_SIZE - sizeof(sa_family_t)];
350 };
351
352 /** @cond INTERNAL_HIDDEN */
353
354 struct sockaddr_ptr {
355 sa_family_t family;
356 char data[NET_SOCKADDR_PTR_MAX_SIZE - sizeof(sa_family_t)];
357 };
358
359 /* Same as sockaddr in our case */
360 struct sockaddr_storage {
361 sa_family_t ss_family;
362 char data[NET_SOCKADDR_MAX_SIZE - sizeof(sa_family_t)];
363 };
364
365 /* Socket address struct for UNIX domain sockets */
366 struct sockaddr_un {
367 sa_family_t sun_family; /* AF_UNIX */
368 char sun_path[NET_SOCKADDR_MAX_SIZE - sizeof(sa_family_t)];
369 };
370
371 struct net_addr {
372 sa_family_t family;
373 union {
374 struct in6_addr in6_addr;
375 struct in_addr in_addr;
376 };
377 };
378
379 #define IN6ADDR_ANY_INIT { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, \
380 0, 0, 0, 0, 0, 0, 0 } } }
381 #define IN6ADDR_LOOPBACK_INIT { { { 0, 0, 0, 0, 0, 0, 0, \
382 0, 0, 0, 0, 0, 0, 0, 0, 1 } } }
383
384 extern const struct in6_addr in6addr_any;
385 extern const struct in6_addr in6addr_loopback;
386
387 /** @endcond */
388
389 /** Max length of the IPv4 address as a string. Defined by POSIX. */
390 #define INET_ADDRSTRLEN 16
391 /** Max length of the IPv6 address as a string. Takes into account possible
392 * mapped IPv4 addresses.
393 */
394 #define INET6_ADDRSTRLEN 46
395
396 /** @cond INTERNAL_HIDDEN */
397
398 /* These are for internal usage of the stack */
399 #define NET_IPV6_ADDR_LEN sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")
400 #define NET_IPV4_ADDR_LEN sizeof("xxx.xxx.xxx.xxx")
401
402 #define INADDR_ANY 0
403 #define INADDR_ANY_INIT { { { INADDR_ANY } } }
404
405 #define INADDR_LOOPBACK_INIT { { { 127, 0, 0, 1 } } }
406
407 /** @endcond */
408
409 enum net_ip_mtu {
410 /** IPv6 MTU length. We must be able to receive this size IPv6 packet
411 * without fragmentation.
412 */
413 NET_IPV6_MTU = 1280,
414
415 /** IPv4 MTU length. We must be able to receive this size IPv4 packet
416 * without fragmentation.
417 */
418 NET_IPV4_MTU = 576,
419 };
420
421 /** Network packet priority settings described in IEEE 802.1Q Annex I.1 */
422 enum net_priority {
423 NET_PRIORITY_BK = 1, /**< Background (lowest) */
424 NET_PRIORITY_BE = 0, /**< Best effort (default) */
425 NET_PRIORITY_EE = 2, /**< Excellent effort */
426 NET_PRIORITY_CA = 3, /**< Critical applications */
427 NET_PRIORITY_VI = 4, /**< Video, < 100 ms latency and jitter */
428 NET_PRIORITY_VO = 5, /**< Voice, < 10 ms latency and jitter */
429 NET_PRIORITY_IC = 6, /**< Internetwork control */
430 NET_PRIORITY_NC = 7 /**< Network control (highest) */
431 } __packed;
432
433 #define NET_MAX_PRIORITIES 8 /* How many priority values there are */
434
435 /** IPv6/IPv4 network connection tuple */
436 struct net_tuple {
437 struct net_addr *remote_addr; /**< IPv6/IPv4 remote address */
438 struct net_addr *local_addr; /**< IPv6/IPv4 local address */
439 uint16_t remote_port; /**< UDP/TCP remote port */
440 uint16_t local_port; /**< UDP/TCP local port */
441 enum net_ip_protocol ip_proto; /**< IP protocol */
442 };
443
444 /** What is the current state of the network address */
445 enum net_addr_state {
446 NET_ADDR_ANY_STATE = -1, /**< Default (invalid) address type */
447 NET_ADDR_TENTATIVE = 0, /**< Tentative address */
448 NET_ADDR_PREFERRED, /**< Preferred address */
449 NET_ADDR_DEPRECATED, /**< Deprecated address */
450 } __packed;
451
452 /** How the network address is assigned to network interface */
453 enum net_addr_type {
454 /** Default value. This is not a valid value. */
455 NET_ADDR_ANY = 0,
456 /** Auto configured address */
457 NET_ADDR_AUTOCONF,
458 /** Address is from DHCP */
459 NET_ADDR_DHCP,
460 /** Manually set address */
461 NET_ADDR_MANUAL,
462 /** Manually set address which is overridable by DHCP */
463 NET_ADDR_OVERRIDABLE,
464 } __packed;
465
466 /** @cond INTERNAL_HIDDEN */
467
468 struct net_ipv6_hdr {
469 uint8_t vtc;
470 uint8_t tcflow;
471 uint16_t flow;
472 uint16_t len;
473 uint8_t nexthdr;
474 uint8_t hop_limit;
475 uint8_t src[NET_IPV6_ADDR_SIZE];
476 uint8_t dst[NET_IPV6_ADDR_SIZE];
477 } __packed;
478
479 struct net_ipv6_frag_hdr {
480 uint8_t nexthdr;
481 uint8_t reserved;
482 uint16_t offset;
483 uint32_t id;
484 } __packed;
485
486 struct net_ipv4_hdr {
487 uint8_t vhl;
488 uint8_t tos;
489 uint16_t len;
490 uint8_t id[2];
491 uint8_t offset[2];
492 uint8_t ttl;
493 uint8_t proto;
494 uint16_t chksum;
495 uint8_t src[NET_IPV4_ADDR_SIZE];
496 uint8_t dst[NET_IPV4_ADDR_SIZE];
497 } __packed;
498
499 struct net_icmp_hdr {
500 uint8_t type;
501 uint8_t code;
502 uint16_t chksum;
503 } __packed;
504
505 struct net_udp_hdr {
506 uint16_t src_port;
507 uint16_t dst_port;
508 uint16_t len;
509 uint16_t chksum;
510 } __packed;
511
512 struct net_tcp_hdr {
513 uint16_t src_port;
514 uint16_t dst_port;
515 uint8_t seq[4];
516 uint8_t ack[4];
517 uint8_t offset;
518 uint8_t flags;
519 uint8_t wnd[2];
520 uint16_t chksum;
521 uint8_t urg[2];
522 uint8_t optdata[0];
523 } __packed;
524
net_addr_type2str(enum net_addr_type type)525 static inline const char *net_addr_type2str(enum net_addr_type type)
526 {
527 switch (type) {
528 case NET_ADDR_AUTOCONF:
529 return "AUTO";
530 case NET_ADDR_DHCP:
531 return "DHCP";
532 case NET_ADDR_MANUAL:
533 return "MANUAL";
534 case NET_ADDR_OVERRIDABLE:
535 return "OVERRIDE";
536 case NET_ADDR_ANY:
537 default:
538 break;
539 }
540
541 return "<unknown>";
542 }
543
544 /* IPv6 extension headers types */
545 #define NET_IPV6_NEXTHDR_HBHO 0
546 #define NET_IPV6_NEXTHDR_DESTO 60
547 #define NET_IPV6_NEXTHDR_ROUTING 43
548 #define NET_IPV6_NEXTHDR_FRAG 44
549 #define NET_IPV6_NEXTHDR_NONE 59
550
551 /**
552 * This 2 unions are here temporarily, as long as net_context.h will
553 * be still public and not part of the core only.
554 */
555 union net_ip_header {
556 struct net_ipv4_hdr *ipv4;
557 struct net_ipv6_hdr *ipv6;
558 };
559
560 union net_proto_header {
561 struct net_udp_hdr *udp;
562 struct net_tcp_hdr *tcp;
563 };
564
565 #define NET_UDPH_LEN 8 /* Size of UDP header */
566 #define NET_TCPH_LEN 20 /* Size of TCP header */
567 #define NET_ICMPH_LEN 4 /* Size of ICMP header */
568
569 #define NET_IPV6H_LEN 40 /* Size of IPv6 header */
570 #define NET_ICMPV6H_LEN NET_ICMPH_LEN /* Size of ICMPv6 header */
571 #define NET_IPV6UDPH_LEN (NET_UDPH_LEN + NET_IPV6H_LEN) /* IPv6 + UDP */
572 #define NET_IPV6TCPH_LEN (NET_TCPH_LEN + NET_IPV6H_LEN) /* IPv6 + TCP */
573 #define NET_IPV6ICMPH_LEN (NET_IPV6H_LEN + NET_ICMPH_LEN) /* ICMPv6 + IPv6 */
574 #define NET_IPV6_FRAGH_LEN 8
575
576 #define NET_IPV4H_LEN 20 /* Size of IPv4 header */
577 #define NET_ICMPV4H_LEN NET_ICMPH_LEN /* Size of ICMPv4 header */
578 #define NET_IPV4UDPH_LEN (NET_UDPH_LEN + NET_IPV4H_LEN) /* IPv4 + UDP */
579 #define NET_IPV4TCPH_LEN (NET_TCPH_LEN + NET_IPV4H_LEN) /* IPv4 + TCP */
580 #define NET_IPV4ICMPH_LEN (NET_IPV4H_LEN + NET_ICMPH_LEN) /* ICMPv4 + IPv4 */
581
582 #define NET_IPV6H_LENGTH_OFFSET 0x04 /* Offset of the Length field in the IPv6 header */
583
584 #define NET_IPV6_FRAGH_OFFSET_MASK 0xfff8 /* Mask for the 13-bit Fragment Offset field */
585 #define NET_IPV4_FRAGH_OFFSET_MASK 0x1fff /* Mask for the 13-bit Fragment Offset field */
586 #define NET_IPV4_MORE_FRAG_MASK 0x2000 /* Mask for the 1-bit More Fragments field */
587 #define NET_IPV4_DO_NOT_FRAG_MASK 0x4000 /* Mask for the 1-bit Do Not Fragment field */
588
589 /** @endcond */
590
591 /**
592 * @brief Check if the IPv6 address is a loopback address (::1).
593 *
594 * @param addr IPv6 address
595 *
596 * @return True if address is a loopback address, False otherwise.
597 */
net_ipv6_is_addr_loopback(struct in6_addr * addr)598 static inline bool net_ipv6_is_addr_loopback(struct in6_addr *addr)
599 {
600 return UNALIGNED_GET(&addr->s6_addr32[0]) == 0 &&
601 UNALIGNED_GET(&addr->s6_addr32[1]) == 0 &&
602 UNALIGNED_GET(&addr->s6_addr32[2]) == 0 &&
603 ntohl(UNALIGNED_GET(&addr->s6_addr32[3])) == 1;
604 }
605
606 /**
607 * @brief Check if the IPv6 address is a multicast address.
608 *
609 * @param addr IPv6 address
610 *
611 * @return True if address is multicast address, False otherwise.
612 */
net_ipv6_is_addr_mcast(const struct in6_addr * addr)613 static inline bool net_ipv6_is_addr_mcast(const struct in6_addr *addr)
614 {
615 return addr->s6_addr[0] == 0xFF;
616 }
617
618 struct net_if;
619 struct net_if_config;
620
621 extern struct net_if_addr *net_if_ipv6_addr_lookup(const struct in6_addr *addr,
622 struct net_if **iface);
623
624 /**
625 * @brief Check if IPv6 address is found in one of the network interfaces.
626 *
627 * @param addr IPv6 address
628 *
629 * @return True if address was found, False otherwise.
630 */
net_ipv6_is_my_addr(struct in6_addr * addr)631 static inline bool net_ipv6_is_my_addr(struct in6_addr *addr)
632 {
633 return net_if_ipv6_addr_lookup(addr, NULL) != NULL;
634 }
635
636 extern struct net_if_mcast_addr *net_if_ipv6_maddr_lookup(
637 const struct in6_addr *addr, struct net_if **iface);
638
639 /**
640 * @brief Check if IPv6 multicast address is found in one of the
641 * network interfaces.
642 *
643 * @param maddr Multicast IPv6 address
644 *
645 * @return True if address was found, False otherwise.
646 */
net_ipv6_is_my_maddr(struct in6_addr * maddr)647 static inline bool net_ipv6_is_my_maddr(struct in6_addr *maddr)
648 {
649 return net_if_ipv6_maddr_lookup(maddr, NULL) != NULL;
650 }
651
652 /**
653 * @brief Check if two IPv6 addresses are same when compared after prefix mask.
654 *
655 * @param addr1 First IPv6 address.
656 * @param addr2 Second IPv6 address.
657 * @param length Prefix length (max length is 128).
658 *
659 * @return True if IPv6 prefixes are the same, False otherwise.
660 */
net_ipv6_is_prefix(const uint8_t * addr1,const uint8_t * addr2,uint8_t length)661 static inline bool net_ipv6_is_prefix(const uint8_t *addr1,
662 const uint8_t *addr2,
663 uint8_t length)
664 {
665 uint8_t bits = 128 - length;
666 uint8_t bytes = length / 8U;
667 uint8_t remain = bits % 8;
668 uint8_t mask;
669
670 if (length > 128) {
671 return false;
672 }
673
674 if (memcmp(addr1, addr2, bytes)) {
675 return false;
676 }
677
678 if (!remain) {
679 /* No remaining bits, the prefixes are the same as first
680 * bytes are the same.
681 */
682 return true;
683 }
684
685 /* Create a mask that has remaining most significant bits set */
686 mask = ((0xff << (8 - remain)) ^ 0xff) << remain;
687
688 return (addr1[bytes] & mask) == (addr2[bytes] & mask);
689 }
690
691 /**
692 * @brief Check if the IPv4 address is a loopback address (127.0.0.0/8).
693 *
694 * @param addr IPv4 address
695 *
696 * @return True if address is a loopback address, False otherwise.
697 */
net_ipv4_is_addr_loopback(struct in_addr * addr)698 static inline bool net_ipv4_is_addr_loopback(struct in_addr *addr)
699 {
700 return addr->s4_addr[0] == 127U;
701 }
702
703 /**
704 * @brief Check if the IPv4 address is unspecified (all bits zero)
705 *
706 * @param addr IPv4 address.
707 *
708 * @return True if the address is unspecified, false otherwise.
709 */
net_ipv4_is_addr_unspecified(const struct in_addr * addr)710 static inline bool net_ipv4_is_addr_unspecified(const struct in_addr *addr)
711 {
712 return UNALIGNED_GET(&addr->s_addr) == 0;
713 }
714
715 /**
716 * @brief Check if the IPv4 address is a multicast address.
717 *
718 * @param addr IPv4 address
719 *
720 * @return True if address is multicast address, False otherwise.
721 */
net_ipv4_is_addr_mcast(const struct in_addr * addr)722 static inline bool net_ipv4_is_addr_mcast(const struct in_addr *addr)
723 {
724 return (ntohl(UNALIGNED_GET(&addr->s_addr)) & 0xF0000000) == 0xE0000000;
725 }
726
727 /**
728 * @brief Check if the given IPv4 address is a link local address.
729 *
730 * @param addr A valid pointer on an IPv4 address
731 *
732 * @return True if it is, false otherwise.
733 */
net_ipv4_is_ll_addr(const struct in_addr * addr)734 static inline bool net_ipv4_is_ll_addr(const struct in_addr *addr)
735 {
736 return (ntohl(UNALIGNED_GET(&addr->s_addr)) & 0xFFFF0000) == 0xA9FE0000;
737 }
738
739 /**
740 * @brief Copy an IPv4 or IPv6 address
741 *
742 * @param dest Destination IP address.
743 * @param src Source IP address.
744 *
745 * @return Destination address.
746 */
747 #define net_ipaddr_copy(dest, src) \
748 UNALIGNED_PUT(UNALIGNED_GET(src), dest)
749
750 /**
751 * @brief Copy an IPv4 address raw buffer
752 *
753 * @param dest Destination IP address.
754 * @param src Source IP address.
755 */
net_ipv4_addr_copy_raw(uint8_t * dest,const uint8_t * src)756 static inline void net_ipv4_addr_copy_raw(uint8_t *dest,
757 const uint8_t *src)
758 {
759 net_ipaddr_copy((struct in_addr *)dest, (const struct in_addr *)src);
760 }
761
762 /**
763 * @brief Copy an IPv6 address raw buffer
764 *
765 * @param dest Destination IP address.
766 * @param src Source IP address.
767 */
net_ipv6_addr_copy_raw(uint8_t * dest,const uint8_t * src)768 static inline void net_ipv6_addr_copy_raw(uint8_t *dest,
769 const uint8_t *src)
770 {
771 memcpy(dest, src, sizeof(struct in6_addr));
772 }
773
774 /**
775 * @brief Compare two IPv4 addresses
776 *
777 * @param addr1 Pointer to IPv4 address.
778 * @param addr2 Pointer to IPv4 address.
779 *
780 * @return True if the addresses are the same, false otherwise.
781 */
net_ipv4_addr_cmp(const struct in_addr * addr1,const struct in_addr * addr2)782 static inline bool net_ipv4_addr_cmp(const struct in_addr *addr1,
783 const struct in_addr *addr2)
784 {
785 return UNALIGNED_GET(&addr1->s_addr) == UNALIGNED_GET(&addr2->s_addr);
786 }
787
788 /**
789 * @brief Compare two raw IPv4 address buffers
790 *
791 * @param addr1 Pointer to IPv4 address buffer.
792 * @param addr2 Pointer to IPv4 address buffer.
793 *
794 * @return True if the addresses are the same, false otherwise.
795 */
net_ipv4_addr_cmp_raw(const uint8_t * addr1,const uint8_t * addr2)796 static inline bool net_ipv4_addr_cmp_raw(const uint8_t *addr1,
797 const uint8_t *addr2)
798 {
799 return net_ipv4_addr_cmp((const struct in_addr *)addr1,
800 (const struct in_addr *)addr2);
801 }
802
803 /**
804 * @brief Compare two IPv6 addresses
805 *
806 * @param addr1 Pointer to IPv6 address.
807 * @param addr2 Pointer to IPv6 address.
808 *
809 * @return True if the addresses are the same, false otherwise.
810 */
net_ipv6_addr_cmp(const struct in6_addr * addr1,const struct in6_addr * addr2)811 static inline bool net_ipv6_addr_cmp(const struct in6_addr *addr1,
812 const struct in6_addr *addr2)
813 {
814 return !memcmp(addr1, addr2, sizeof(struct in6_addr));
815 }
816
817 /**
818 * @brief Compare two raw IPv6 address buffers
819 *
820 * @param addr1 Pointer to IPv6 address buffer.
821 * @param addr2 Pointer to IPv6 address buffer.
822 *
823 * @return True if the addresses are the same, false otherwise.
824 */
net_ipv6_addr_cmp_raw(const uint8_t * addr1,const uint8_t * addr2)825 static inline bool net_ipv6_addr_cmp_raw(const uint8_t *addr1,
826 const uint8_t *addr2)
827 {
828 return net_ipv6_addr_cmp((const struct in6_addr *)addr1,
829 (const struct in6_addr *)addr2);
830 }
831
832 /**
833 * @brief Check if the given IPv6 address is a link local address.
834 *
835 * @param addr A valid pointer on an IPv6 address
836 *
837 * @return True if it is, false otherwise.
838 */
net_ipv6_is_ll_addr(const struct in6_addr * addr)839 static inline bool net_ipv6_is_ll_addr(const struct in6_addr *addr)
840 {
841 return UNALIGNED_GET(&addr->s6_addr16[0]) == htons(0xFE80);
842 }
843
844 /**
845 * @brief Check if the given IPv6 address is a site local address.
846 *
847 * @param addr A valid pointer on an IPv6 address
848 *
849 * @return True if it is, false otherwise.
850 */
net_ipv6_is_sl_addr(const struct in6_addr * addr)851 static inline bool net_ipv6_is_sl_addr(const struct in6_addr *addr)
852 {
853 return UNALIGNED_GET(&addr->s6_addr16[0]) == htons(0xFEC0);
854 }
855
856
857 /**
858 * @brief Check if the given IPv6 address is a unique local address.
859 *
860 * @param addr A valid pointer on an IPv6 address
861 *
862 * @return True if it is, false otherwise.
863 */
net_ipv6_is_ula_addr(const struct in6_addr * addr)864 static inline bool net_ipv6_is_ula_addr(const struct in6_addr *addr)
865 {
866 return addr->s6_addr[0] == 0xFD;
867 }
868
869 /**
870 * @brief Check if the given IPv6 address is a global address.
871 *
872 * @param addr A valid pointer on an IPv6 address
873 *
874 * @return True if it is, false otherwise.
875 */
net_ipv6_is_global_addr(const struct in6_addr * addr)876 static inline bool net_ipv6_is_global_addr(const struct in6_addr *addr)
877 {
878 return (addr->s6_addr[0] & 0xE0) == 0x20;
879 }
880
881 /**
882 * @brief Return pointer to any (all bits zeros) IPv6 address.
883 *
884 * @return Any IPv6 address.
885 */
886 const struct in6_addr *net_ipv6_unspecified_address(void);
887
888 /**
889 * @brief Return pointer to any (all bits zeros) IPv4 address.
890 *
891 * @return Any IPv4 address.
892 */
893 const struct in_addr *net_ipv4_unspecified_address(void);
894
895 /**
896 * @brief Return pointer to broadcast (all bits ones) IPv4 address.
897 *
898 * @return Broadcast IPv4 address.
899 */
900 const struct in_addr *net_ipv4_broadcast_address(void);
901
902 struct net_if;
903 extern bool net_if_ipv4_addr_mask_cmp(struct net_if *iface,
904 const struct in_addr *addr);
905
906 /**
907 * @brief Check if the given address belongs to same subnet that
908 * has been configured for the interface.
909 *
910 * @param iface A valid pointer on an interface
911 * @param addr IPv4 address
912 *
913 * @return True if address is in same subnet, false otherwise.
914 */
net_ipv4_addr_mask_cmp(struct net_if * iface,const struct in_addr * addr)915 static inline bool net_ipv4_addr_mask_cmp(struct net_if *iface,
916 const struct in_addr *addr)
917 {
918 return net_if_ipv4_addr_mask_cmp(iface, addr);
919 }
920
921 extern bool net_if_ipv4_is_addr_bcast(struct net_if *iface,
922 const struct in_addr *addr);
923
924 /**
925 * @brief Check if the given IPv4 address is a broadcast address.
926 *
927 * @param iface Interface to use. Must be a valid pointer to an interface.
928 * @param addr IPv4 address
929 *
930 * @return True if address is a broadcast address, false otherwise.
931 */
932 #if defined(CONFIG_NET_NATIVE_IPV4)
net_ipv4_is_addr_bcast(struct net_if * iface,const struct in_addr * addr)933 static inline bool net_ipv4_is_addr_bcast(struct net_if *iface,
934 const struct in_addr *addr)
935 {
936 if (net_ipv4_addr_cmp(addr, net_ipv4_broadcast_address())) {
937 return true;
938 }
939
940 return net_if_ipv4_is_addr_bcast(iface, addr);
941 }
942 #else
net_ipv4_is_addr_bcast(struct net_if * iface,const struct in_addr * addr)943 static inline bool net_ipv4_is_addr_bcast(struct net_if *iface,
944 const struct in_addr *addr)
945 {
946 ARG_UNUSED(iface);
947 ARG_UNUSED(addr);
948
949 return false;
950 }
951 #endif
952
953 extern struct net_if_addr *net_if_ipv4_addr_lookup(const struct in_addr *addr,
954 struct net_if **iface);
955
956 /**
957 * @brief Check if the IPv4 address is assigned to any network interface
958 * in the system.
959 *
960 * @param addr A valid pointer on an IPv4 address
961 *
962 * @return True if IPv4 address is found in one of the network interfaces,
963 * False otherwise.
964 */
net_ipv4_is_my_addr(const struct in_addr * addr)965 static inline bool net_ipv4_is_my_addr(const struct in_addr *addr)
966 {
967 bool ret;
968
969 ret = net_if_ipv4_addr_lookup(addr, NULL) != NULL;
970 if (!ret) {
971 ret = net_ipv4_is_addr_bcast(NULL, addr);
972 }
973
974 return ret;
975 }
976
977 /**
978 * @brief Check if the IPv6 address is unspecified (all bits zero)
979 *
980 * @param addr IPv6 address.
981 *
982 * @return True if the address is unspecified, false otherwise.
983 */
net_ipv6_is_addr_unspecified(const struct in6_addr * addr)984 static inline bool net_ipv6_is_addr_unspecified(const struct in6_addr *addr)
985 {
986 return UNALIGNED_GET(&addr->s6_addr32[0]) == 0 &&
987 UNALIGNED_GET(&addr->s6_addr32[1]) == 0 &&
988 UNALIGNED_GET(&addr->s6_addr32[2]) == 0 &&
989 UNALIGNED_GET(&addr->s6_addr32[3]) == 0;
990 }
991
992 /**
993 * @brief Check if the IPv6 address is solicited node multicast address
994 * FF02:0:0:0:0:1:FFXX:XXXX defined in RFC 3513
995 *
996 * @param addr IPv6 address.
997 *
998 * @return True if the address is solicited node address, false otherwise.
999 */
net_ipv6_is_addr_solicited_node(const struct in6_addr * addr)1000 static inline bool net_ipv6_is_addr_solicited_node(const struct in6_addr *addr)
1001 {
1002 return UNALIGNED_GET(&addr->s6_addr32[0]) == htonl(0xff020000) &&
1003 UNALIGNED_GET(&addr->s6_addr32[1]) == 0x00000000 &&
1004 UNALIGNED_GET(&addr->s6_addr32[2]) == htonl(0x00000001) &&
1005 ((UNALIGNED_GET(&addr->s6_addr32[3]) & htonl(0xff000000)) ==
1006 htonl(0xff000000));
1007 }
1008
1009 /**
1010 * @brief Check if the IPv6 address is a given scope multicast
1011 * address (FFyx::).
1012 *
1013 * @param addr IPv6 address
1014 * @param scope Scope to check
1015 *
1016 * @return True if the address is in given scope multicast address,
1017 * false otherwise.
1018 */
net_ipv6_is_addr_mcast_scope(const struct in6_addr * addr,int scope)1019 static inline bool net_ipv6_is_addr_mcast_scope(const struct in6_addr *addr,
1020 int scope)
1021 {
1022 return (addr->s6_addr[0] == 0xff) && (addr->s6_addr[1] == scope);
1023 }
1024
1025 /**
1026 * @brief Check if the IPv6 addresses have the same multicast scope (FFyx::).
1027 *
1028 * @param addr_1 IPv6 address 1
1029 * @param addr_2 IPv6 address 2
1030 *
1031 * @return True if both addresses have same multicast scope,
1032 * false otherwise.
1033 */
net_ipv6_is_same_mcast_scope(const struct in6_addr * addr_1,const struct in6_addr * addr_2)1034 static inline bool net_ipv6_is_same_mcast_scope(const struct in6_addr *addr_1,
1035 const struct in6_addr *addr_2)
1036 {
1037 return (addr_1->s6_addr[0] == 0xff) && (addr_2->s6_addr[0] == 0xff) &&
1038 (addr_1->s6_addr[1] == addr_2->s6_addr[1]);
1039 }
1040
1041 /**
1042 * @brief Check if the IPv6 address is a global multicast address (FFxE::/16).
1043 *
1044 * @param addr IPv6 address.
1045 *
1046 * @return True if the address is global multicast address, false otherwise.
1047 */
net_ipv6_is_addr_mcast_global(const struct in6_addr * addr)1048 static inline bool net_ipv6_is_addr_mcast_global(const struct in6_addr *addr)
1049 {
1050 return net_ipv6_is_addr_mcast_scope(addr, 0x0e);
1051 }
1052
1053 /**
1054 * @brief Check if the IPv6 address is a interface scope multicast
1055 * address (FFx1::).
1056 *
1057 * @param addr IPv6 address.
1058 *
1059 * @return True if the address is a interface scope multicast address,
1060 * false otherwise.
1061 */
net_ipv6_is_addr_mcast_iface(const struct in6_addr * addr)1062 static inline bool net_ipv6_is_addr_mcast_iface(const struct in6_addr *addr)
1063 {
1064 return net_ipv6_is_addr_mcast_scope(addr, 0x01);
1065 }
1066
1067 /**
1068 * @brief Check if the IPv6 address is a link local scope multicast
1069 * address (FFx2::).
1070 *
1071 * @param addr IPv6 address.
1072 *
1073 * @return True if the address is a link local scope multicast address,
1074 * false otherwise.
1075 */
net_ipv6_is_addr_mcast_link(const struct in6_addr * addr)1076 static inline bool net_ipv6_is_addr_mcast_link(const struct in6_addr *addr)
1077 {
1078 return net_ipv6_is_addr_mcast_scope(addr, 0x02);
1079 }
1080
1081 /**
1082 * @brief Check if the IPv6 address is a mesh-local scope multicast
1083 * address (FFx3::).
1084 *
1085 * @param addr IPv6 address.
1086 *
1087 * @return True if the address is a mesh-local scope multicast address,
1088 * false otherwise.
1089 */
net_ipv6_is_addr_mcast_mesh(const struct in6_addr * addr)1090 static inline bool net_ipv6_is_addr_mcast_mesh(const struct in6_addr *addr)
1091 {
1092 return net_ipv6_is_addr_mcast_scope(addr, 0x03);
1093 }
1094
1095 /**
1096 * @brief Check if the IPv6 address is a site scope multicast
1097 * address (FFx5::).
1098 *
1099 * @param addr IPv6 address.
1100 *
1101 * @return True if the address is a site scope multicast address,
1102 * false otherwise.
1103 */
net_ipv6_is_addr_mcast_site(const struct in6_addr * addr)1104 static inline bool net_ipv6_is_addr_mcast_site(const struct in6_addr *addr)
1105 {
1106 return net_ipv6_is_addr_mcast_scope(addr, 0x05);
1107 }
1108
1109 /**
1110 * @brief Check if the IPv6 address is an organization scope multicast
1111 * address (FFx8::).
1112 *
1113 * @param addr IPv6 address.
1114 *
1115 * @return True if the address is an organization scope multicast address,
1116 * false otherwise.
1117 */
net_ipv6_is_addr_mcast_org(const struct in6_addr * addr)1118 static inline bool net_ipv6_is_addr_mcast_org(const struct in6_addr *addr)
1119 {
1120 return net_ipv6_is_addr_mcast_scope(addr, 0x08);
1121 }
1122
1123 /**
1124 * @brief Check if the IPv6 address belongs to certain multicast group
1125 *
1126 * @param addr IPv6 address.
1127 * @param group Group id IPv6 address, the values must be in network
1128 * byte order
1129 *
1130 * @return True if the IPv6 multicast address belongs to given multicast
1131 * group, false otherwise.
1132 */
net_ipv6_is_addr_mcast_group(const struct in6_addr * addr,const struct in6_addr * group)1133 static inline bool net_ipv6_is_addr_mcast_group(const struct in6_addr *addr,
1134 const struct in6_addr *group)
1135 {
1136 return UNALIGNED_GET(&addr->s6_addr16[1]) == group->s6_addr16[1] &&
1137 UNALIGNED_GET(&addr->s6_addr16[2]) == group->s6_addr16[2] &&
1138 UNALIGNED_GET(&addr->s6_addr16[3]) == group->s6_addr16[3] &&
1139 UNALIGNED_GET(&addr->s6_addr32[1]) == group->s6_addr32[1] &&
1140 UNALIGNED_GET(&addr->s6_addr32[2]) == group->s6_addr32[1] &&
1141 UNALIGNED_GET(&addr->s6_addr32[3]) == group->s6_addr32[3];
1142 }
1143
1144 /**
1145 * @brief Check if the IPv6 address belongs to the all nodes multicast group
1146 *
1147 * @param addr IPv6 address
1148 *
1149 * @return True if the IPv6 multicast address belongs to the all nodes multicast
1150 * group, false otherwise
1151 */
1152 static inline bool
net_ipv6_is_addr_mcast_all_nodes_group(const struct in6_addr * addr)1153 net_ipv6_is_addr_mcast_all_nodes_group(const struct in6_addr *addr)
1154 {
1155 static const struct in6_addr all_nodes_mcast_group = {
1156 { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1157 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
1158 };
1159
1160 return net_ipv6_is_addr_mcast_group(addr, &all_nodes_mcast_group);
1161 }
1162
1163 /**
1164 * @brief Check if the IPv6 address is a interface scope all nodes multicast
1165 * address (FF01::1).
1166 *
1167 * @param addr IPv6 address.
1168 *
1169 * @return True if the address is a interface scope all nodes multicast address,
1170 * false otherwise.
1171 */
1172 static inline bool
net_ipv6_is_addr_mcast_iface_all_nodes(const struct in6_addr * addr)1173 net_ipv6_is_addr_mcast_iface_all_nodes(const struct in6_addr *addr)
1174 {
1175 return net_ipv6_is_addr_mcast_iface(addr) &&
1176 net_ipv6_is_addr_mcast_all_nodes_group(addr);
1177 }
1178
1179 /**
1180 * @brief Check if the IPv6 address is a link local scope all nodes multicast
1181 * address (FF02::1).
1182 *
1183 * @param addr IPv6 address.
1184 *
1185 * @return True if the address is a link local scope all nodes multicast
1186 * address, false otherwise.
1187 */
1188 static inline bool
net_ipv6_is_addr_mcast_link_all_nodes(const struct in6_addr * addr)1189 net_ipv6_is_addr_mcast_link_all_nodes(const struct in6_addr *addr)
1190 {
1191 return net_ipv6_is_addr_mcast_link(addr) &&
1192 net_ipv6_is_addr_mcast_all_nodes_group(addr);
1193 }
1194
1195 /**
1196 * @brief Create solicited node IPv6 multicast address
1197 * FF02:0:0:0:0:1:FFXX:XXXX defined in RFC 3513
1198 *
1199 * @param src IPv6 address.
1200 * @param dst IPv6 address.
1201 */
1202 static inline
net_ipv6_addr_create_solicited_node(const struct in6_addr * src,struct in6_addr * dst)1203 void net_ipv6_addr_create_solicited_node(const struct in6_addr *src,
1204 struct in6_addr *dst)
1205 {
1206 dst->s6_addr[0] = 0xFF;
1207 dst->s6_addr[1] = 0x02;
1208 UNALIGNED_PUT(0, &dst->s6_addr16[1]);
1209 UNALIGNED_PUT(0, &dst->s6_addr16[2]);
1210 UNALIGNED_PUT(0, &dst->s6_addr16[3]);
1211 UNALIGNED_PUT(0, &dst->s6_addr16[4]);
1212 dst->s6_addr[10] = 0U;
1213 dst->s6_addr[11] = 0x01;
1214 dst->s6_addr[12] = 0xFF;
1215 dst->s6_addr[13] = src->s6_addr[13];
1216 UNALIGNED_PUT(UNALIGNED_GET(&src->s6_addr16[7]), &dst->s6_addr16[7]);
1217 }
1218
1219 /** @brief Construct an IPv6 address from eight 16-bit words.
1220 *
1221 * @param addr IPv6 address
1222 * @param addr0 16-bit word which is part of the address
1223 * @param addr1 16-bit word which is part of the address
1224 * @param addr2 16-bit word which is part of the address
1225 * @param addr3 16-bit word which is part of the address
1226 * @param addr4 16-bit word which is part of the address
1227 * @param addr5 16-bit word which is part of the address
1228 * @param addr6 16-bit word which is part of the address
1229 * @param addr7 16-bit word which is part of the address
1230 */
net_ipv6_addr_create(struct in6_addr * addr,uint16_t addr0,uint16_t addr1,uint16_t addr2,uint16_t addr3,uint16_t addr4,uint16_t addr5,uint16_t addr6,uint16_t addr7)1231 static inline void net_ipv6_addr_create(struct in6_addr *addr,
1232 uint16_t addr0, uint16_t addr1,
1233 uint16_t addr2, uint16_t addr3,
1234 uint16_t addr4, uint16_t addr5,
1235 uint16_t addr6, uint16_t addr7)
1236 {
1237 UNALIGNED_PUT(htons(addr0), &addr->s6_addr16[0]);
1238 UNALIGNED_PUT(htons(addr1), &addr->s6_addr16[1]);
1239 UNALIGNED_PUT(htons(addr2), &addr->s6_addr16[2]);
1240 UNALIGNED_PUT(htons(addr3), &addr->s6_addr16[3]);
1241 UNALIGNED_PUT(htons(addr4), &addr->s6_addr16[4]);
1242 UNALIGNED_PUT(htons(addr5), &addr->s6_addr16[5]);
1243 UNALIGNED_PUT(htons(addr6), &addr->s6_addr16[6]);
1244 UNALIGNED_PUT(htons(addr7), &addr->s6_addr16[7]);
1245 }
1246
1247 /**
1248 * @brief Create link local allnodes multicast IPv6 address
1249 *
1250 * @param addr IPv6 address
1251 */
net_ipv6_addr_create_ll_allnodes_mcast(struct in6_addr * addr)1252 static inline void net_ipv6_addr_create_ll_allnodes_mcast(struct in6_addr *addr)
1253 {
1254 net_ipv6_addr_create(addr, 0xff02, 0, 0, 0, 0, 0, 0, 0x0001);
1255 }
1256
1257 /**
1258 * @brief Create link local allrouters multicast IPv6 address
1259 *
1260 * @param addr IPv6 address
1261 */
net_ipv6_addr_create_ll_allrouters_mcast(struct in6_addr * addr)1262 static inline void net_ipv6_addr_create_ll_allrouters_mcast(struct in6_addr *addr)
1263 {
1264 net_ipv6_addr_create(addr, 0xff02, 0, 0, 0, 0, 0, 0, 0x0002);
1265 }
1266
1267 /**
1268 * @brief Create IPv4 mapped IPv6 address
1269 *
1270 * @param addr4 IPv4 address
1271 * @param addr6 IPv6 address to be created
1272 */
net_ipv6_addr_create_v4_mapped(const struct in_addr * addr4,struct in6_addr * addr6)1273 static inline void net_ipv6_addr_create_v4_mapped(const struct in_addr *addr4,
1274 struct in6_addr *addr6)
1275 {
1276 net_ipv6_addr_create(addr6, 0, 0, 0, 0, 0, 0xffff,
1277 ntohs(addr4->s4_addr16[0]),
1278 ntohs(addr4->s4_addr16[1]));
1279 }
1280
1281 /**
1282 * @brief Is the IPv6 address an IPv4 mapped one. The v4 mapped addresses
1283 * look like \::ffff:a.b.c.d
1284 *
1285 * @param addr IPv6 address
1286 *
1287 * @return True if IPv6 address is a IPv4 mapped address, False otherwise.
1288 */
net_ipv6_addr_is_v4_mapped(const struct in6_addr * addr)1289 static inline bool net_ipv6_addr_is_v4_mapped(const struct in6_addr *addr)
1290 {
1291 if (UNALIGNED_GET(&addr->s6_addr32[0]) == 0 &&
1292 UNALIGNED_GET(&addr->s6_addr32[1]) == 0 &&
1293 UNALIGNED_GET(&addr->s6_addr16[5]) == 0xffff) {
1294 return true;
1295 }
1296
1297 return false;
1298 }
1299
1300 /**
1301 * @brief Create IPv6 address interface identifier
1302 *
1303 * @param addr IPv6 address
1304 * @param lladdr Link local address
1305 */
net_ipv6_addr_create_iid(struct in6_addr * addr,struct net_linkaddr * lladdr)1306 static inline void net_ipv6_addr_create_iid(struct in6_addr *addr,
1307 struct net_linkaddr *lladdr)
1308 {
1309 UNALIGNED_PUT(htonl(0xfe800000), &addr->s6_addr32[0]);
1310 UNALIGNED_PUT(0, &addr->s6_addr32[1]);
1311
1312 switch (lladdr->len) {
1313 case 2:
1314 /* The generated IPv6 shall not toggle the
1315 * Universal/Local bit. RFC 6282 ch 3.2.2
1316 */
1317 if (lladdr->type == NET_LINK_IEEE802154) {
1318 UNALIGNED_PUT(0, &addr->s6_addr32[2]);
1319 addr->s6_addr[11] = 0xff;
1320 addr->s6_addr[12] = 0xfe;
1321 addr->s6_addr[13] = 0U;
1322 addr->s6_addr[14] = lladdr->addr[0];
1323 addr->s6_addr[15] = lladdr->addr[1];
1324 }
1325
1326 break;
1327 case 6:
1328 /* We do not toggle the Universal/Local bit
1329 * in Bluetooth. See RFC 7668 ch 3.2.2
1330 */
1331 memcpy(&addr->s6_addr[8], lladdr->addr, 3);
1332 addr->s6_addr[11] = 0xff;
1333 addr->s6_addr[12] = 0xfe;
1334 memcpy(&addr->s6_addr[13], lladdr->addr + 3, 3);
1335
1336 #if defined(CONFIG_NET_L2_BT_ZEP1656)
1337 /* Workaround against older Linux kernel BT IPSP code.
1338 * This will be removed eventually.
1339 */
1340 if (lladdr->type == NET_LINK_BLUETOOTH) {
1341 addr->s6_addr[8] ^= 0x02;
1342 }
1343 #endif
1344
1345 if (lladdr->type == NET_LINK_ETHERNET) {
1346 addr->s6_addr[8] ^= 0x02;
1347 }
1348
1349 break;
1350 case 8:
1351 memcpy(&addr->s6_addr[8], lladdr->addr, lladdr->len);
1352 addr->s6_addr[8] ^= 0x02;
1353 break;
1354 }
1355 }
1356
1357 /**
1358 * @brief Check if given address is based on link layer address
1359 *
1360 * @return True if it is, False otherwise
1361 */
net_ipv6_addr_based_on_ll(const struct in6_addr * addr,const struct net_linkaddr * lladdr)1362 static inline bool net_ipv6_addr_based_on_ll(const struct in6_addr *addr,
1363 const struct net_linkaddr *lladdr)
1364 {
1365 if (!addr || !lladdr) {
1366 return false;
1367 }
1368
1369 switch (lladdr->len) {
1370 case 2:
1371 if (!memcmp(&addr->s6_addr[14], lladdr->addr, lladdr->len) &&
1372 addr->s6_addr[8] == 0U &&
1373 addr->s6_addr[9] == 0U &&
1374 addr->s6_addr[10] == 0U &&
1375 addr->s6_addr[11] == 0xff &&
1376 addr->s6_addr[12] == 0xfe) {
1377 return true;
1378 }
1379
1380 break;
1381 case 6:
1382 if (lladdr->type == NET_LINK_ETHERNET) {
1383 if (!memcmp(&addr->s6_addr[9], &lladdr->addr[1], 2) &&
1384 !memcmp(&addr->s6_addr[13], &lladdr->addr[3], 3) &&
1385 addr->s6_addr[11] == 0xff &&
1386 addr->s6_addr[12] == 0xfe &&
1387 (addr->s6_addr[8] ^ 0x02) == lladdr->addr[0]) {
1388 return true;
1389 }
1390 } else if (lladdr->type == NET_LINK_BLUETOOTH) {
1391 if (!memcmp(&addr->s6_addr[9], &lladdr->addr[1], 2) &&
1392 !memcmp(&addr->s6_addr[13], &lladdr->addr[3], 3) &&
1393 addr->s6_addr[11] == 0xff &&
1394 addr->s6_addr[12] == 0xfe
1395 #if defined(CONFIG_NET_L2_BT_ZEP1656)
1396 /* Workaround against older Linux kernel BT IPSP
1397 * code. This will be removed eventually.
1398 */
1399 && (addr->s6_addr[8] ^ 0x02) == lladdr->addr[0]
1400 #endif
1401 ) {
1402 return true;
1403 }
1404 }
1405
1406 break;
1407 case 8:
1408 if (!memcmp(&addr->s6_addr[9], &lladdr->addr[1],
1409 lladdr->len - 1) &&
1410 (addr->s6_addr[8] ^ 0x02) == lladdr->addr[0]) {
1411 return true;
1412 }
1413
1414 break;
1415 }
1416
1417 return false;
1418 }
1419
1420 /**
1421 * @brief Get sockaddr_in6 from sockaddr. This is a helper so that
1422 * the code calling this function can be made shorter.
1423 *
1424 * @param addr Socket address
1425 *
1426 * @return Pointer to IPv6 socket address
1427 */
net_sin6(const struct sockaddr * addr)1428 static inline struct sockaddr_in6 *net_sin6(const struct sockaddr *addr)
1429 {
1430 return (struct sockaddr_in6 *)addr;
1431 }
1432
1433 /**
1434 * @brief Get sockaddr_in from sockaddr. This is a helper so that
1435 * the code calling this function can be made shorter.
1436 *
1437 * @param addr Socket address
1438 *
1439 * @return Pointer to IPv4 socket address
1440 */
net_sin(const struct sockaddr * addr)1441 static inline struct sockaddr_in *net_sin(const struct sockaddr *addr)
1442 {
1443 return (struct sockaddr_in *)addr;
1444 }
1445
1446 /**
1447 * @brief Get sockaddr_in6_ptr from sockaddr_ptr. This is a helper so that
1448 * the code calling this function can be made shorter.
1449 *
1450 * @param addr Socket address
1451 *
1452 * @return Pointer to IPv6 socket address
1453 */
1454 static inline
net_sin6_ptr(const struct sockaddr_ptr * addr)1455 struct sockaddr_in6_ptr *net_sin6_ptr(const struct sockaddr_ptr *addr)
1456 {
1457 return (struct sockaddr_in6_ptr *)addr;
1458 }
1459
1460 /**
1461 * @brief Get sockaddr_in_ptr from sockaddr_ptr. This is a helper so that
1462 * the code calling this function can be made shorter.
1463 *
1464 * @param addr Socket address
1465 *
1466 * @return Pointer to IPv4 socket address
1467 */
1468 static inline
net_sin_ptr(const struct sockaddr_ptr * addr)1469 struct sockaddr_in_ptr *net_sin_ptr(const struct sockaddr_ptr *addr)
1470 {
1471 return (struct sockaddr_in_ptr *)addr;
1472 }
1473
1474 /**
1475 * @brief Get sockaddr_ll_ptr from sockaddr_ptr. This is a helper so that
1476 * the code calling this function can be made shorter.
1477 *
1478 * @param addr Socket address
1479 *
1480 * @return Pointer to linklayer socket address
1481 */
1482 static inline
net_sll_ptr(const struct sockaddr_ptr * addr)1483 struct sockaddr_ll_ptr *net_sll_ptr(const struct sockaddr_ptr *addr)
1484 {
1485 return (struct sockaddr_ll_ptr *)addr;
1486 }
1487
1488 /**
1489 * @brief Get sockaddr_can_ptr from sockaddr_ptr. This is a helper so that
1490 * the code needing this functionality can be made shorter.
1491 *
1492 * @param addr Socket address
1493 *
1494 * @return Pointer to CAN socket address
1495 */
1496 static inline
net_can_ptr(const struct sockaddr_ptr * addr)1497 struct sockaddr_can_ptr *net_can_ptr(const struct sockaddr_ptr *addr)
1498 {
1499 return (struct sockaddr_can_ptr *)addr;
1500 }
1501
1502 /**
1503 * @brief Convert a string to IP address.
1504 *
1505 * @param family IP address family (AF_INET or AF_INET6)
1506 * @param src IP address in a null terminated string
1507 * @param dst Pointer to struct in_addr if family is AF_INET or
1508 * pointer to struct in6_addr if family is AF_INET6
1509 *
1510 * @note This function doesn't do precise error checking,
1511 * do not use for untrusted strings.
1512 *
1513 * @return 0 if ok, < 0 if error
1514 */
1515 __syscall int net_addr_pton(sa_family_t family, const char *src, void *dst);
1516
1517 /**
1518 * @brief Convert IP address to string form.
1519 *
1520 * @param family IP address family (AF_INET or AF_INET6)
1521 * @param src Pointer to struct in_addr if family is AF_INET or
1522 * pointer to struct in6_addr if family is AF_INET6
1523 * @param dst Buffer for IP address as a null terminated string
1524 * @param size Number of bytes available in the buffer
1525 *
1526 * @return dst pointer if ok, NULL if error
1527 */
1528 __syscall char *net_addr_ntop(sa_family_t family, const void *src,
1529 char *dst, size_t size);
1530
1531 /**
1532 * @brief Parse a string that contains either IPv4 or IPv6 address
1533 * and optional port, and store the information in user supplied
1534 * sockaddr struct.
1535 *
1536 * @details Syntax of the IP address string:
1537 * 192.0.2.1:80
1538 * 192.0.2.42
1539 * [2001:db8::1]:8080
1540 * [2001:db8::2]
1541 * 2001:db::42
1542 * Note that the str_len parameter is used to restrict the amount of
1543 * characters that are checked. If the string does not contain port
1544 * number, then the port number in sockaddr is not modified.
1545 *
1546 * @param str String that contains the IP address.
1547 * @param str_len Length of the string to be parsed.
1548 * @param addr Pointer to user supplied struct sockaddr.
1549 *
1550 * @return True if parsing could be done, false otherwise.
1551 */
1552 bool net_ipaddr_parse(const char *str, size_t str_len,
1553 struct sockaddr *addr);
1554
1555 /**
1556 * @brief Compare TCP sequence numbers.
1557 *
1558 * @details This function compares TCP sequence numbers,
1559 * accounting for wraparound effects.
1560 *
1561 * @param seq1 First sequence number
1562 * @param seq2 Seconds sequence number
1563 *
1564 * @return < 0 if seq1 < seq2, 0 if seq1 == seq2, > 0 if seq > seq2
1565 */
net_tcp_seq_cmp(uint32_t seq1,uint32_t seq2)1566 static inline int32_t net_tcp_seq_cmp(uint32_t seq1, uint32_t seq2)
1567 {
1568 return (int32_t)(seq1 - seq2);
1569 }
1570
1571 /**
1572 * @brief Check that one TCP sequence number is greater.
1573 *
1574 * @details This is convenience function on top of net_tcp_seq_cmp().
1575 *
1576 * @param seq1 First sequence number
1577 * @param seq2 Seconds sequence number
1578 *
1579 * @return True if seq > seq2
1580 */
net_tcp_seq_greater(uint32_t seq1,uint32_t seq2)1581 static inline bool net_tcp_seq_greater(uint32_t seq1, uint32_t seq2)
1582 {
1583 return net_tcp_seq_cmp(seq1, seq2) > 0;
1584 }
1585
1586 /**
1587 * @brief Convert a string of hex values to array of bytes.
1588 *
1589 * @details The syntax of the string is "ab:02:98:fa:42:01"
1590 *
1591 * @param buf Pointer to memory where the bytes are written.
1592 * @param buf_len Length of the memory area.
1593 * @param src String of bytes.
1594 *
1595 * @return 0 if ok, <0 if error
1596 */
1597 int net_bytes_from_str(uint8_t *buf, int buf_len, const char *src);
1598
1599 /**
1600 * @brief Convert Tx network packet priority to traffic class so we can place
1601 * the packet into correct Tx queue.
1602 *
1603 * @param prio Network priority
1604 *
1605 * @return Tx traffic class that handles that priority network traffic.
1606 */
1607 int net_tx_priority2tc(enum net_priority prio);
1608
1609 /**
1610 * @brief Convert Rx network packet priority to traffic class so we can place
1611 * the packet into correct Rx queue.
1612 *
1613 * @param prio Network priority
1614 *
1615 * @return Rx traffic class that handles that priority network traffic.
1616 */
1617 int net_rx_priority2tc(enum net_priority prio);
1618
1619 /**
1620 * @brief Convert network packet VLAN priority to network packet priority so we
1621 * can place the packet into correct queue.
1622 *
1623 * @param priority VLAN priority
1624 *
1625 * @return Network priority
1626 */
net_vlan2priority(uint8_t priority)1627 static inline enum net_priority net_vlan2priority(uint8_t priority)
1628 {
1629 /* Map according to IEEE 802.1Q */
1630 static const uint8_t vlan2priority[] = {
1631 NET_PRIORITY_BE,
1632 NET_PRIORITY_BK,
1633 NET_PRIORITY_EE,
1634 NET_PRIORITY_CA,
1635 NET_PRIORITY_VI,
1636 NET_PRIORITY_VO,
1637 NET_PRIORITY_IC,
1638 NET_PRIORITY_NC
1639 };
1640
1641 if (priority >= ARRAY_SIZE(vlan2priority)) {
1642 /* Use Best Effort as the default priority */
1643 return NET_PRIORITY_BE;
1644 }
1645
1646 return (enum net_priority)vlan2priority[priority];
1647 }
1648
1649 /**
1650 * @brief Convert network packet priority to network packet VLAN priority.
1651 *
1652 * @param priority Packet priority
1653 *
1654 * @return VLAN priority (PCP)
1655 */
net_priority2vlan(enum net_priority priority)1656 static inline uint8_t net_priority2vlan(enum net_priority priority)
1657 {
1658 /* The conversion works both ways */
1659 return (uint8_t)net_vlan2priority(priority);
1660 }
1661
1662 /**
1663 * @brief Return network address family value as a string. This is only usable
1664 * for debugging.
1665 *
1666 * @param family Network address family code
1667 *
1668 * @return Network address family as a string, or NULL if family is unknown.
1669 */
1670 const char *net_family2str(sa_family_t family);
1671
1672 #ifdef __cplusplus
1673 }
1674 #endif
1675
1676 #include <syscalls/net_ip.h>
1677
1678 /**
1679 * @}
1680 */
1681
1682
1683 #endif /* ZEPHYR_INCLUDE_NET_NET_IP_H_ */
1684