Loading...
Searching...
No Matches
addr.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
3 * SPDX-License-Identifier: LGPL-2.1-only
4 */
5
6#pragma once
7
22
23#include <stdbool.h>
24#include <string.h>
25
26#include "byteorder.h"
27#include "net/ipv4/addr.h"
28
29#ifdef __cplusplus
30extern "C" {
31#endif
32
36#define IPV6_ADDR_BIT_LEN (128)
37
38#ifdef MODULE_IPV4_ADDR
42#define IPV6_ADDR_MAX_STR_LEN (sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"))
43#else
47#define IPV6_ADDR_MAX_STR_LEN (sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"))
48#endif
49
59#define IPV6_ADDR_SITE_LOCAL_PREFIX (0xfec0)
60
70
76#define IPV6_ADDR_UNSPECIFIED {{ 0x00, 0x00, 0x00, 0x00, \
77 0x00, 0x00, 0x00, 0x00, \
78 0x00, 0x00, 0x00, 0x00, \
79 0x00, 0x00, 0x00, 0x00 }}
80
86#define IPV6_ADDR_LOOPBACK {{ 0x00, 0x00, 0x00, 0x00, \
87 0x00, 0x00, 0x00, 0x00, \
88 0x00, 0x00, 0x00, 0x00, \
89 0x00, 0x00, 0x00, 0x01 }}
90
95#define IPV6_ADDR_LINK_LOCAL_PREFIX {{ 0xfe, 0x80, 0x00, 0x00, \
96 0x00, 0x00, 0x00, 0x00, \
97 0x00, 0x00, 0x00, 0x00, \
98 0x00, 0x00, 0x00, 0x00 }}
99
106#define IPV6_ADDR_ALL_NODES_IF_LOCAL {{ 0xff, 0x01, 0x00, 0x00, \
107 0x00, 0x00, 0x00, 0x00, \
108 0x00, 0x00, 0x00, 0x00, \
109 0x00, 0x00, 0x00, 0x01 }}
110
117#define IPV6_ADDR_ALL_NODES_LINK_LOCAL {{ 0xff, 0x02, 0x00, 0x00, \
118 0x00, 0x00, 0x00, 0x00, \
119 0x00, 0x00, 0x00, 0x00, \
120 0x00, 0x00, 0x00, 0x01 }}
121
128#define IPV6_ADDR_ALL_ROUTERS_IF_LOCAL {{ 0xff, 0x01, 0x00, 0x00, \
129 0x00, 0x00, 0x00, 0x00, \
130 0x00, 0x00, 0x00, 0x00, \
131 0x00, 0x00, 0x00, 0x02 }}
132
139#define IPV6_ADDR_ALL_ROUTERS_LINK_LOCAL {{ 0xff, 0x02, 0x00, 0x00, \
140 0x00, 0x00, 0x00, 0x00, \
141 0x00, 0x00, 0x00, 0x00, \
142 0x00, 0x00, 0x00, 0x02 }}
143
150#define IPV6_ADDR_ALL_ROUTERS_SITE_LOCAL {{ 0xff, 0x05, 0x00, 0x00, \
151 0x00, 0x00, 0x00, 0x00, \
152 0x00, 0x00, 0x00, 0x00, \
153 0x00, 0x00, 0x00, 0x02 }}
154
161#define IPV6_ADDR_SOLICITED_NODE_PREFIX {{ 0xff, 0x02, 0x00, 0x00, \
162 0x00, 0x00, 0x00, 0x00, \
163 0x00, 0x00, 0x00, 0x01, \
164 0xff, 0x00, 0x00, 0x00 }}
165
177#define IPV6_ADDR_MCAST_FLAG_TRANSIENT (0x01)
178
184#define IPV6_ADDR_MCAST_FLAG_PREFIX_BASED (0x02)
185
191#define IPV6_ADDR_MCAST_FLAG_EMBED_ON_RP (0x04)
193
201#define IPV6_ADDR_MCAST_SCP_IF_LOCAL (0x1)
202#define IPV6_ADDR_MCAST_SCP_LINK_LOCAL (0x2)
203
210#define IPV6_ADDR_MCAST_SCP_REALM_LOCAL (0x3)
211#define IPV6_ADDR_MCAST_SCP_ADMIN_LOCAL (0x4)
212#define IPV6_ADDR_MCAST_SCP_SITE_LOCAL (0x5)
213#define IPV6_ADDR_MCAST_SCP_ORG_LOCAL (0x8)
214#define IPV6_ADDR_MCAST_SCP_GLOBAL (0xe)
216
225
230
235
240
245
250
255
260
268
279static inline bool ipv6_addr_is_unspecified(const ipv6_addr_t *addr)
280{
281 return (memcmp(addr, &ipv6_addr_unspecified, sizeof(ipv6_addr_t)) == 0);
282}
283
294static inline bool ipv6_addr_is_loopback(const ipv6_addr_t *addr)
295{
296 return (memcmp(addr, &ipv6_addr_loopback, sizeof(ipv6_addr_t)) == 0);
297}
298
309static inline bool ipv6_addr_is_ipv4_compat(const ipv6_addr_t *addr)
310{
311 return (memcmp(addr, &ipv6_addr_unspecified,
312 sizeof(ipv6_addr_t) - sizeof(ipv4_addr_t)) == 0);
313}
314
325static inline bool ipv6_addr_is_ipv4_mapped(const ipv6_addr_t *addr)
326{
327 return ((memcmp(addr, &ipv6_addr_unspecified,
328 sizeof(ipv6_addr_t) - sizeof(ipv4_addr_t) - 2) == 0) &&
329 (addr->u16[5].u16 == 0xffff));
330}
331
342static inline bool ipv6_addr_is_multicast(const ipv6_addr_t *addr)
343{
344 return (addr->u8[0] == 0xff);
345}
346
358static inline bool ipv6_addr_is_link_local(const ipv6_addr_t *addr)
359{
360 return (memcmp(addr, &ipv6_addr_link_local_prefix, sizeof(addr->u64[0])) == 0) ||
361 (ipv6_addr_is_multicast(addr) &&
362 (addr->u8[1] & 0x0f) == IPV6_ADDR_MCAST_SCP_LINK_LOCAL);
363}
364
379static inline bool ipv6_addr_is_site_local(const ipv6_addr_t *addr)
380{
381 return (((byteorder_ntohs(addr->u16[0]) & 0xffc0) ==
383 (ipv6_addr_is_multicast(addr) &&
384 (addr->u8[1] & 0x0f) == IPV6_ADDR_MCAST_SCP_SITE_LOCAL));
385}
386
397static inline bool ipv6_addr_is_unique_local_unicast(const ipv6_addr_t *addr)
398{
399 return ((addr->u8[0] == 0xfc) || (addr->u8[0] == 0xfd));
400}
401
412static inline bool ipv6_addr_is_global(const ipv6_addr_t *addr)
413{
414 /* first check for multicast with global scope */
415 if (ipv6_addr_is_multicast(addr)) {
416 return ((addr->u8[1] & 0x0f) == IPV6_ADDR_MCAST_SCP_GLOBAL);
417 }
418 else {
419 return !(ipv6_addr_is_link_local(addr) ||
422 }
423}
424
435static inline bool ipv6_addr_is_solicited_node(const ipv6_addr_t *addr)
436{
437 return (memcmp(addr, &ipv6_addr_solicited_node_prefix,
438 sizeof(ipv6_addr_t) - 3) == 0);
439}
440
450bool ipv6_addr_equal(const ipv6_addr_t *a, const ipv6_addr_t *b);
451
462
472void ipv6_addr_init_prefix(ipv6_addr_t *out, const ipv6_addr_t *prefix, uint8_t bits);
473
481static inline void ipv6_addr_init(ipv6_addr_t *out, uint64_t prefix, uint64_t iid)
482{
483 out->u64[0] = byteorder_htonll(prefix);
484 out->u64[1] = byteorder_htonll(iid);
485}
486
496void ipv6_addr_init_iid(ipv6_addr_t *out, const uint8_t *iid, uint8_t bits);
497
505static inline void ipv6_addr_set_unspecified(ipv6_addr_t *addr)
506{
507 memset(addr, 0, sizeof(ipv6_addr_t));
508}
509
517static inline void ipv6_addr_set_loopback(ipv6_addr_t *addr)
518{
519 memset(addr, 0, sizeof(ipv6_addr_t));
520 addr->u8[15] = 1;
521}
522
531{
532 memcpy(addr, &ipv6_addr_link_local_prefix, sizeof(addr->u64[0]));
533}
534
544static inline void ipv6_addr_set_iid(ipv6_addr_t *addr, uint64_t iid)
545{
546 addr->u64[1] = byteorder_htonll(iid);
547}
548
558static inline void ipv6_addr_set_aiid(ipv6_addr_t *addr, uint8_t *iid)
559{
560 memcpy(&addr->u64[1], iid, sizeof(addr->u64[1]));
561}
562
572static inline void ipv6_addr_set_multicast(ipv6_addr_t *addr, unsigned int flags,
573 unsigned int scope)
574{
575 addr->u8[0] = 0xff;
576 addr->u8[1] = (((uint8_t)flags) << 4) | (((uint8_t) scope) & 0x0f);
577}
578
588static inline void ipv6_addr_set_all_nodes_multicast(ipv6_addr_t *addr, unsigned int scope)
589{
590 memcpy(addr, &ipv6_addr_all_nodes_if_local, sizeof(ipv6_addr_t));
591 addr->u8[1] = (uint8_t)scope;
592}
593
603static inline void ipv6_addr_set_all_routers_multicast(ipv6_addr_t *addr, unsigned int scope)
604{
605 memcpy(addr, &ipv6_addr_all_routers_if_local, sizeof(ipv6_addr_t));
606 addr->u8[1] = (uint8_t)scope;
607}
608
618static inline void ipv6_addr_set_solicited_nodes(ipv6_addr_t *out, const ipv6_addr_t *in)
619{
620 out->u64[0] = byteorder_htonll(0xff02000000000000ull);
621 out->u32[2] = byteorder_htonl(1);
622 out->u8[12] = 0xff;
623 out->u8[13] = in->u8[13];
624 out->u16[7] = in->u16[7];
625}
626
641char *ipv6_addr_to_str(char *result, const ipv6_addr_t *addr, uint8_t result_len);
642
656ipv6_addr_t *ipv6_addr_from_str(ipv6_addr_t *result, const char *addr);
657
670int ipv6_prefix_from_str(ipv6_addr_t *result, const char *prefix);
671
688ipv6_addr_t *ipv6_addr_from_buf(ipv6_addr_t *result, const char *addr,
689 size_t addr_len);
690
703char *ipv6_addr_split_str(char *addr_str, char separator);
704
717int ipv6_addr_split_int(char *addr_str, char separator, int _default);
718
727static inline int ipv6_addr_split_prefix(char *addr_str)
728{
729 return ipv6_addr_split_int(addr_str, '/', 128);
730}
731
741static inline char *ipv6_addr_split_iface(char *addr_str)
742{
743 return ipv6_addr_split_str(addr_str, '%');
744}
745
751void ipv6_addr_print(const ipv6_addr_t *addr);
752
760void ipv6_addrs_print(const ipv6_addr_t *addrs, size_t num,
761 const char *separator);
762
769void ipv6_prefix_print(const ipv6_addr_t *prefix, uint8_t bits);
770
771#ifdef __cplusplus
772}
773#endif
774
Functions to work with different byte orders.
be_uint32_t network_uint32_t
A 32 bit integer in network byte order.
Definition byteorder.h:109
static network_uint64_t byteorder_htonll(uint64_t v)
Convert from host byte order to network byte order, 64 bit.
Definition byteorder.h:495
be_uint16_t network_uint16_t
A 16 bit integer in network byte order.
Definition byteorder.h:104
static uint16_t byteorder_ntohs(network_uint16_t v)
Convert from network byte order to host byte order, 16 bit.
Definition byteorder.h:502
be_uint64_t network_uint64_t
A 64 bit integer in network byte order.
Definition byteorder.h:114
static network_uint32_t byteorder_htonl(uint32_t v)
Convert from host byte order to network byte order, 32 bit.
Definition byteorder.h:488
static void ipv6_addr_set_unspecified(ipv6_addr_t *addr)
Sets addr dynamically to the unspecified IPv6 address (::).
Definition addr.h:505
static bool ipv6_addr_is_multicast(const ipv6_addr_t *addr)
Check if addr is a multicast address.
Definition addr.h:342
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:517
static bool ipv6_addr_is_loopback(const ipv6_addr_t *addr)
Checks if addr is a loopback address.
Definition addr.h:294
static bool ipv6_addr_is_global(const ipv6_addr_t *addr)
Check if addr is global unicast address.
Definition addr.h:412
char * ipv6_addr_to_str(char *result, const ipv6_addr_t *addr, uint8_t result_len)
Converts an IPv6 address to its string representation.
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:212
const ipv6_addr_t ipv6_addr_all_nodes_link_local
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 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:618
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:530
#define IPV6_ADDR_MCAST_SCP_LINK_LOCAL
link-local scope
Definition addr.h:202
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:558
#define IPV6_ADDR_SITE_LOCAL_PREFIX
The first 10 bits of a site-local IPv6 unicast address.
Definition addr.h:59
static int ipv6_addr_split_prefix(char *addr_str)
split IPv6 prefix string representation
Definition addr.h:727
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
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.
#define IPV6_ADDR_MCAST_SCP_GLOBAL
global scope
Definition addr.h:214
void ipv6_prefix_print(const ipv6_addr_t *prefix, uint8_t bits)
Print IPv6 prefix to stdout.
static bool ipv6_addr_is_link_local(const ipv6_addr_t *addr)
Check if addr is a link-local address.
Definition addr.h:358
static bool ipv6_addr_is_site_local(const ipv6_addr_t *addr)
Checks if addr is a site-local address.
Definition addr.h:379
char * ipv6_addr_split_str(char *addr_str, char separator)
split IPv6 address string representation and return remaining string
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:588
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:481
bool ipv6_addr_equal(const ipv6_addr_t *a, const ipv6_addr_t *b)
Checks if two IPv6 addresses are equal.
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.
const ipv6_addr_t ipv6_addr_link_local_prefix
static bool ipv6_addr_is_ipv4_compat(const ipv6_addr_t *addr)
Checks if addr is a IPv4-compatible IPv6 address.
Definition addr.h:309
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:603
static bool ipv6_addr_is_unique_local_unicast(const ipv6_addr_t *addr)
Check if addr is unique local unicast address.
Definition addr.h:397
static char * ipv6_addr_split_iface(char *addr_str)
split IPv6 address + interface specifier
Definition addr.h:741
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:435
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:325
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:572
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:544
static bool ipv6_addr_is_unspecified(const ipv6_addr_t *addr)
Checks if addr is unspecified (all zero).
Definition addr.h:279
const ipv6_addr_t ipv6_addr_all_routers_if_local
IPv4 address type and helper functions definitions.
uint16_t u16
16 bit representation
Definition byteorder.h:71
Data type to represent an IPv4 address.
Definition addr.h:55
Data type to represent an IPv6 address.
Definition addr.h:64
uint8_t u8[16]
divided by 16 8-bit words.
Definition addr.h:65
network_uint64_t u64[2]
divided by 2 64-bit words.
Definition addr.h:68
network_uint32_t u32[4]
divided by 4 32-bit words.
Definition addr.h:67
network_uint16_t u16[8]
divided by 8 16-bit words.
Definition addr.h:66