addr.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
3  *
4  * This file is subject to the terms and conditions of the GNU Lesser General
5  * Public License v2.1. See the file LICENSE in the top level directory for
6  * more details.
7  */
8 
24 #ifndef NET_IPV6_ADDR_H
25 #define NET_IPV6_ADDR_H
26 
27 #include <stdbool.h>
28 #include <string.h>
29 
30 #include "byteorder.h"
31 #include "net/ipv4/addr.h"
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
40 #define IPV6_ADDR_BIT_LEN (128)
41 
42 #ifdef MODULE_IPV4_ADDR
46 #define IPV6_ADDR_MAX_STR_LEN (sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"))
47 #else
51 #define IPV6_ADDR_MAX_STR_LEN (sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"))
52 #endif
53 
63 #define IPV6_ADDR_SITE_LOCAL_PREFIX (0xfec0)
64 
68 typedef union {
69  uint8_t u8[16];
73 } ipv6_addr_t;
74 
80 #define IPV6_ADDR_UNSPECIFIED {{ 0x00, 0x00, 0x00, 0x00, \
81  0x00, 0x00, 0x00, 0x00, \
82  0x00, 0x00, 0x00, 0x00, \
83  0x00, 0x00, 0x00, 0x00 }}
84 
90 #define IPV6_ADDR_LOOPBACK {{ 0x00, 0x00, 0x00, 0x00, \
91  0x00, 0x00, 0x00, 0x00, \
92  0x00, 0x00, 0x00, 0x00, \
93  0x00, 0x00, 0x00, 0x01 }}
99 #define IPV6_ADDR_LINK_LOCAL_PREFIX {{ 0xfe, 0x80, 0x00, 0x00, \
100  0x00, 0x00, 0x00, 0x00, \
101  0x00, 0x00, 0x00, 0x00, \
102  0x00, 0x00, 0x00, 0x00 }}
103 
110 #define IPV6_ADDR_ALL_NODES_IF_LOCAL {{ 0xff, 0x01, 0x00, 0x00, \
111  0x00, 0x00, 0x00, 0x00, \
112  0x00, 0x00, 0x00, 0x00, \
113  0x00, 0x00, 0x00, 0x01 }}
114 
121 #define IPV6_ADDR_ALL_NODES_LINK_LOCAL {{ 0xff, 0x02, 0x00, 0x00, \
122  0x00, 0x00, 0x00, 0x00, \
123  0x00, 0x00, 0x00, 0x00, \
124  0x00, 0x00, 0x00, 0x01 }}
125 
132 #define IPV6_ADDR_ALL_ROUTERS_IF_LOCAL {{ 0xff, 0x01, 0x00, 0x00, \
133  0x00, 0x00, 0x00, 0x00, \
134  0x00, 0x00, 0x00, 0x00, \
135  0x00, 0x00, 0x00, 0x02 }}
136 
143 #define IPV6_ADDR_ALL_ROUTERS_LINK_LOCAL {{ 0xff, 0x02, 0x00, 0x00, \
144  0x00, 0x00, 0x00, 0x00, \
145  0x00, 0x00, 0x00, 0x00, \
146  0x00, 0x00, 0x00, 0x02 }}
147 
154 #define IPV6_ADDR_ALL_ROUTERS_SITE_LOCAL {{ 0xff, 0x05, 0x00, 0x00, \
155  0x00, 0x00, 0x00, 0x00, \
156  0x00, 0x00, 0x00, 0x00, \
157  0x00, 0x00, 0x00, 0x02 }}
158 
165 #define IPV6_ADDR_SOLICITED_NODE_PREFIX {{ 0xff, 0x02, 0x00, 0x00, \
166  0x00, 0x00, 0x00, 0x00, \
167  0x00, 0x00, 0x00, 0x01, \
168  0xff, 0x00, 0x00, 0x00 }}
169 
181 #define IPV6_ADDR_MCAST_FLAG_TRANSIENT (0x01)
182 
188 #define IPV6_ADDR_MCAST_FLAG_PREFIX_BASED (0x02)
189 
195 #define IPV6_ADDR_MCAST_FLAG_EMBED_ON_RP (0x04)
205 #define IPV6_ADDR_MCAST_SCP_IF_LOCAL (0x1)
206 #define IPV6_ADDR_MCAST_SCP_LINK_LOCAL (0x2)
214 #define IPV6_ADDR_MCAST_SCP_REALM_LOCAL (0x3)
215 #define IPV6_ADDR_MCAST_SCP_ADMIN_LOCAL (0x4)
216 #define IPV6_ADDR_MCAST_SCP_SITE_LOCAL (0x5)
217 #define IPV6_ADDR_MCAST_SCP_ORG_LOCAL (0x8)
218 #define IPV6_ADDR_MCAST_SCP_GLOBAL (0xe)
229 
233 extern const ipv6_addr_t ipv6_addr_loopback;
234 
239 
244 
249 
254 
259 
264 
283 static inline bool ipv6_addr_is_unspecified(const ipv6_addr_t *addr)
284 {
285  return (memcmp(addr, &ipv6_addr_unspecified, sizeof(ipv6_addr_t)) == 0);
286 }
287 
298 static inline bool ipv6_addr_is_loopback(const ipv6_addr_t *addr)
299 {
300  return (memcmp(addr, &ipv6_addr_loopback, sizeof(ipv6_addr_t)) == 0);
301 }
302 
313 static inline bool ipv6_addr_is_ipv4_compat(const ipv6_addr_t *addr)
314 {
315  return (memcmp(addr, &ipv6_addr_unspecified,
316  sizeof(ipv6_addr_t) - sizeof(ipv4_addr_t)) == 0);
317 }
318 
329 static inline bool ipv6_addr_is_ipv4_mapped(const ipv6_addr_t *addr)
330 {
331  return ((memcmp(addr, &ipv6_addr_unspecified,
332  sizeof(ipv6_addr_t) - sizeof(ipv4_addr_t) - 2) == 0) &&
333  (addr->u16[5].u16 == 0xffff));
334 }
335 
346 static inline bool ipv6_addr_is_multicast(const ipv6_addr_t *addr)
347 {
348  return (addr->u8[0] == 0xff);
349 }
350 
362 static inline bool ipv6_addr_is_link_local(const ipv6_addr_t *addr)
363 {
364  return (memcmp(addr, &ipv6_addr_link_local_prefix, sizeof(addr->u64[0])) == 0) ||
365  (ipv6_addr_is_multicast(addr) &&
366  (addr->u8[1] & 0x0f) == IPV6_ADDR_MCAST_SCP_LINK_LOCAL);
367 }
368 
383 static inline bool ipv6_addr_is_site_local(const ipv6_addr_t *addr)
384 {
385  return (((byteorder_ntohs(addr->u16[0]) & 0xffc0) ==
387  (ipv6_addr_is_multicast(addr) &&
388  (addr->u8[1] & 0x0f) == IPV6_ADDR_MCAST_SCP_SITE_LOCAL));
389 }
390 
401 static inline bool ipv6_addr_is_unique_local_unicast(const ipv6_addr_t *addr)
402 {
403  return ((addr->u8[0] == 0xfc) || (addr->u8[0] == 0xfd));
404 }
405 
416 static inline bool ipv6_addr_is_global(const ipv6_addr_t *addr)
417 {
418  /* first check for multicast with global scope */
419  if (ipv6_addr_is_multicast(addr)) {
420  return ((addr->u8[1] & 0x0f) == IPV6_ADDR_MCAST_SCP_GLOBAL);
421  }
422  else {
423  return !(ipv6_addr_is_link_local(addr) ||
424  ipv6_addr_is_unspecified(addr) ||
425  ipv6_addr_is_loopback(addr));
426  }
427 }
428 
439 static inline bool ipv6_addr_is_solicited_node(const ipv6_addr_t *addr)
440 {
441  return (memcmp(addr, &ipv6_addr_solicited_node_prefix,
442  sizeof(ipv6_addr_t) - 3) == 0);
443 }
444 
454 bool ipv6_addr_equal(const ipv6_addr_t *a, const ipv6_addr_t *b);
455 
465 uint8_t ipv6_addr_match_prefix(const ipv6_addr_t *a, const ipv6_addr_t *b);
466 
476 void ipv6_addr_init_prefix(ipv6_addr_t *out, const ipv6_addr_t *prefix, uint8_t bits);
477 
485 static inline void ipv6_addr_init(ipv6_addr_t *out, uint64_t prefix, uint64_t iid)
486 {
487  out->u64[0] = byteorder_htonll(prefix);
488  out->u64[1] = byteorder_htonll(iid);
489 }
490 
500 void ipv6_addr_init_iid(ipv6_addr_t *out, const uint8_t *iid, uint8_t bits);
501 
509 static inline void ipv6_addr_set_unspecified(ipv6_addr_t *addr)
510 {
511  memset(addr, 0, sizeof(ipv6_addr_t));
512 }
513 
521 static inline void ipv6_addr_set_loopback(ipv6_addr_t *addr)
522 {
523  memset(addr, 0, sizeof(ipv6_addr_t));
524  addr->u8[15] = 1;
525 }
526 
535 {
536  memcpy(addr, &ipv6_addr_link_local_prefix, sizeof(addr->u64[0]));
537 }
538 
548 static inline void ipv6_addr_set_iid(ipv6_addr_t *addr, uint64_t iid)
549 {
550  addr->u64[1] = byteorder_htonll(iid);
551 }
552 
562 static inline void ipv6_addr_set_aiid(ipv6_addr_t *addr, uint8_t *iid)
563 {
564  memcpy(&addr->u64[1], iid, sizeof(addr->u64[1]));
565 }
566 
576 static inline void ipv6_addr_set_multicast(ipv6_addr_t *addr, unsigned int flags,
577  unsigned int scope)
578 {
579  addr->u8[0] = 0xff;
580  addr->u8[1] = (((uint8_t)flags) << 4) | (((uint8_t) scope) & 0x0f);
581 }
582 
592 static inline void ipv6_addr_set_all_nodes_multicast(ipv6_addr_t *addr, unsigned int scope)
593 {
594  memcpy(addr, &ipv6_addr_all_nodes_if_local, sizeof(ipv6_addr_t));
595  addr->u8[1] = (uint8_t)scope;
596 }
597 
607 static inline void ipv6_addr_set_all_routers_multicast(ipv6_addr_t *addr, unsigned int scope)
608 {
609  memcpy(addr, &ipv6_addr_all_routers_if_local, sizeof(ipv6_addr_t));
610  addr->u8[1] = (uint8_t)scope;
611 }
612 
622 static inline void ipv6_addr_set_solicited_nodes(ipv6_addr_t *out, const ipv6_addr_t *in)
623 {
624  out->u64[0] = byteorder_htonll(0xff02000000000000ull);
625  out->u32[2] = byteorder_htonl(1);
626  out->u8[12] = 0xff;
627  out->u8[13] = in->u8[13];
628  out->u16[7] = in->u16[7];
629 }
630 
645 char *ipv6_addr_to_str(char *result, const ipv6_addr_t *addr, uint8_t result_len);
646 
660 ipv6_addr_t *ipv6_addr_from_str(ipv6_addr_t *result, const char *addr);
661 
674 int ipv6_prefix_from_str(ipv6_addr_t *result, const char *prefix);
675 
692 ipv6_addr_t *ipv6_addr_from_buf(ipv6_addr_t *result, const char *addr,
693  size_t addr_len);
694 
707 char *ipv6_addr_split_str(char *addr_str, char separator);
708 
721 int ipv6_addr_split_int(char *addr_str, char separator, int _default);
722 
731 static inline int ipv6_addr_split_prefix(char *addr_str)
732 {
733  return ipv6_addr_split_int(addr_str, '/', 128);
734 }
735 
745 static inline char *ipv6_addr_split_iface(char *addr_str)
746 {
747  return ipv6_addr_split_str(addr_str, '%');
748 }
749 
755 void ipv6_addr_print(const ipv6_addr_t *addr);
756 
764 void ipv6_addrs_print(const ipv6_addr_t *addrs, size_t num,
765  const char *separator);
766 
767 #ifdef __cplusplus
768 }
769 #endif
770 
771 #endif /* NET_IPV6_ADDR_H */
Functions to work with different byte orders.
static network_uint64_t byteorder_htonll(uint64_t v)
Convert from host byte order to network byte order, 64 bit.
Definition: byteorder.h:499
static uint16_t byteorder_ntohs(network_uint16_t v)
Convert from network byte order to host byte order, 16 bit.
Definition: byteorder.h:506
static network_uint32_t byteorder_htonl(uint32_t v)
Convert from host byte order to network byte order, 32 bit.
Definition: byteorder.h:492
static void ipv6_addr_set_unspecified(ipv6_addr_t *addr)
Sets addr dynamically to the unspecified IPv6 address (::).
Definition: addr.h:509
static bool ipv6_addr_is_multicast(const ipv6_addr_t *addr)
Check if addr is a multicast address.
Definition: addr.h:346
const ipv6_addr_t ipv6_addr_all_routers_link_local
static void ipv6_addr_set_loopback(ipv6_addr_t *addr)
Sets addr dynamically to the loopback IPv6 address (::1).
Definition: addr.h:521
static bool ipv6_addr_is_loopback(const ipv6_addr_t *addr)
Checks if addr is a loopback address.
Definition: addr.h:298
static bool ipv6_addr_is_global(const ipv6_addr_t *addr)
Check if addr is global unicast address.
Definition: addr.h:416
void ipv6_addrs_print(const ipv6_addr_t *addrs, size_t num, const char *separator)
Print IPv6 addresses to stdout.
#define IPV6_ADDR_MCAST_SCP_SITE_LOCAL
site-local scope
Definition: addr.h:216
const ipv6_addr_t ipv6_addr_all_nodes_link_local
static void ipv6_addr_set_solicited_nodes(ipv6_addr_t *out, const ipv6_addr_t *in)
Set out to the solicited-node multicast address computed from in.
Definition: addr.h:622
static void ipv6_addr_set_link_local_prefix(ipv6_addr_t *addr)
Sets the first 64 bit of addr to link local prefix (fe08::/64).
Definition: addr.h:534
#define IPV6_ADDR_MCAST_SCP_LINK_LOCAL
link-local scope
Definition: addr.h:206
static void ipv6_addr_set_aiid(ipv6_addr_t *addr, uint8_t *iid)
Sets the 64-bit interface ID (as array) of a unicast or anycast IPv6 address.
Definition: addr.h:562
#define IPV6_ADDR_SITE_LOCAL_PREFIX
The first 10 bits of a site-local IPv6 unicast address.
Definition: addr.h:63
static int ipv6_addr_split_prefix(char *addr_str)
split IPv6 prefix string representation
Definition: addr.h:731
const ipv6_addr_t ipv6_addr_all_routers_site_local
void ipv6_addr_print(const ipv6_addr_t *addr)
Print IPv6 address to stdout.
const ipv6_addr_t ipv6_addr_all_nodes_if_local
const ipv6_addr_t ipv6_addr_loopback
static char * ipv6_addr_split_iface(char *addr_str)
split IPv6 address + interface specifier
Definition: addr.h:745
void ipv6_addr_init_iid(ipv6_addr_t *out, const uint8_t *iid, uint8_t bits)
Sets the last bits of IPv6 address out to iid.
ipv6_addr_t * ipv6_addr_from_str(ipv6_addr_t *result, const char *addr)
Converts an IPv6 address string representation to a byte-represented IPv6 address.
#define IPV6_ADDR_MCAST_SCP_GLOBAL
global scope
Definition: addr.h:218
static bool ipv6_addr_is_link_local(const ipv6_addr_t *addr)
Check if addr is a link-local address.
Definition: addr.h:362
ipv6_addr_t * ipv6_addr_from_buf(ipv6_addr_t *result, const char *addr, size_t addr_len)
Converts an IPv6 address from a buffer of characters to a byte-represented IPv6 address.
static bool ipv6_addr_is_site_local(const ipv6_addr_t *addr)
Checks if addr is a site-local address.
Definition: addr.h:383
static void ipv6_addr_set_all_nodes_multicast(ipv6_addr_t *addr, unsigned int scope)
Sets addr dynamically to an all nodes multicast IPv6 address (ff0S::1, where S is the scope).
Definition: addr.h:592
static void ipv6_addr_init(ipv6_addr_t *out, uint64_t prefix, uint64_t iid)
Sets IPv6 address out with a given prefix and interface ID.
Definition: addr.h:485
bool ipv6_addr_equal(const ipv6_addr_t *a, const ipv6_addr_t *b)
Checks if two IPv6 addresses are equal.
const ipv6_addr_t ipv6_addr_link_local_prefix
char * ipv6_addr_to_str(char *result, const ipv6_addr_t *addr, uint8_t result_len)
Converts an IPv6 address to its string representation.
char * ipv6_addr_split_str(char *addr_str, char separator)
split IPv6 address string representation and return remaining string
static bool ipv6_addr_is_ipv4_compat(const ipv6_addr_t *addr)
Checks if addr is a IPv4-compatible IPv6 address.
Definition: addr.h:313
int ipv6_prefix_from_str(ipv6_addr_t *result, const char *prefix)
Converts an IPv6 prefix string representation to a byte-represented IPv6 address.
static void ipv6_addr_set_all_routers_multicast(ipv6_addr_t *addr, unsigned int scope)
Sets addr dynamically to an all routers multicast IPv6 address (ff0S::2, where S is the scope).
Definition: addr.h:607
static bool ipv6_addr_is_unique_local_unicast(const ipv6_addr_t *addr)
Check if addr is unique local unicast address.
Definition: addr.h:401
void ipv6_addr_init_prefix(ipv6_addr_t *out, const ipv6_addr_t *prefix, uint8_t bits)
Sets IPv6 address out with the first bits taken from prefix and leaves the remaining bits untouched.
const ipv6_addr_t ipv6_addr_unspecified
In-memory constants of defined addresses and prefixes.
static bool ipv6_addr_is_solicited_node(const ipv6_addr_t *addr)
Check if addr is solicited-node multicast address.
Definition: addr.h:439
const ipv6_addr_t ipv6_addr_solicited_node_prefix
int ipv6_addr_split_int(char *addr_str, char separator, int _default)
split IPv6 address string representation
static bool ipv6_addr_is_ipv4_mapped(const ipv6_addr_t *addr)
Checks if addr is a IPv4-mapped IPv6 address.
Definition: addr.h:329
static void ipv6_addr_set_multicast(ipv6_addr_t *addr, unsigned int flags, unsigned int scope)
Sets the bits for an address required to be a multicast address.
Definition: addr.h:576
uint8_t ipv6_addr_match_prefix(const ipv6_addr_t *a, const ipv6_addr_t *b)
Checks up to which bit-count two IPv6 addresses match in their prefix.
static void ipv6_addr_set_iid(ipv6_addr_t *addr, uint64_t iid)
Sets the 64-bit interface ID (as integer) of a unicast or anycast IPv6 address.
Definition: addr.h:548
static bool ipv6_addr_is_unspecified(const ipv6_addr_t *addr)
Checks if addr is unspecified (all zero).
Definition: addr.h:283
const ipv6_addr_t ipv6_addr_all_routers_if_local
IPv4 address type and helper functions definitions.
A 16 bit integer in big endian aka network byte order.
Definition: byteorder.h:74
uint16_t u16
16 bit representation
Definition: byteorder.h:75
A 32 bit integer in big endian aka network byte order.
Definition: byteorder.h:84
A 64 bit integer in big endian aka network byte order.
Definition: byteorder.h:96
Data type to represent an IPv4 address.
Definition: addr.h:53
Data type to represent an IPv6 address.
Definition: addr.h:68
uint8_t u8[16]
divided by 16 8-bit words.
Definition: addr.h:69
network_uint64_t u64[2]
divided by 2 64-bit words.
Definition: addr.h:72
network_uint32_t u32[4]
divided by 4 32-bit words.
Definition: addr.h:71
network_uint16_t u16[8]
divided by 8 16-bit words.
Definition: addr.h:70