From ff36abb2cf84d08413632468c1ae0ba25150054e Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Wed, 11 Feb 2015 11:46:48 +0100 Subject: [PATCH] ng_ipv6_addr: initial import The motivation behind this module is to allow for address handling functions where they, but not the full IPv6 functionality might be needed. This new version of the IPv6 address data type utilizes the byteorder.h header to enforce network byte-order on its members. --- sys/Makefile | 3 + sys/include/net/ng_ipv6.h | 40 + sys/include/net/ng_ipv6/addr.h | 507 +++++++++++++ sys/net/network_layer/ng_ipv6/addr/Makefile | 3 + .../network_layer/ng_ipv6/addr/ng_ipv6_addr.c | 84 +++ tests/unittests/tests-ipv6_addr/Makefile | 3 + .../tests-ipv6_addr/Makefile.include | 1 + .../tests-ipv6_addr/tests-ipv6_addr.c | 687 ++++++++++++++++++ .../tests-ipv6_addr/tests-ipv6_addr.h | 37 + 9 files changed, 1365 insertions(+) create mode 100644 sys/include/net/ng_ipv6.h create mode 100644 sys/include/net/ng_ipv6/addr.h create mode 100644 sys/net/network_layer/ng_ipv6/addr/Makefile create mode 100644 sys/net/network_layer/ng_ipv6/addr/ng_ipv6_addr.c create mode 100644 tests/unittests/tests-ipv6_addr/Makefile create mode 100644 tests/unittests/tests-ipv6_addr/Makefile.include create mode 100644 tests/unittests/tests-ipv6_addr/tests-ipv6_addr.c create mode 100644 tests/unittests/tests-ipv6_addr/tests-ipv6_addr.h diff --git a/sys/Makefile b/sys/Makefile index bb960d61f5c2..dac040342b8e 100644 --- a/sys/Makefile +++ b/sys/Makefile @@ -68,6 +68,9 @@ endif ifneq (,$(filter oneway_malloc,$(USEMODULE))) DIRS += oneway-malloc endif +ifneq (,$(filter ng_ipv6_addr,$(USEMODULE))) + DIRS += net/network_layer/ng_ipv6/addr +endif ifneq (,$(filter ng_netif,$(USEMODULE))) DIRS += net/crosslayer/ng_netif endif diff --git a/sys/include/net/ng_ipv6.h b/sys/include/net/ng_ipv6.h new file mode 100644 index 000000000000..8990be2d35f5 --- /dev/null +++ b/sys/include/net/ng_ipv6.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2015 Martine Lenders + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for + * more details. + */ + +/** + * @defgroup net_ng_ipv6 IPv6 + * @ingroup net + * @brief New IPv6 implementation + * @{ + * + * @file + * @brief Definitions for IPv6 + * + * @author Martine Lenders + */ + + +#ifndef NG_IPV6_H_ +#define NG_IPV6_H_ + +#include "net/ng_ipv6/addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif + +#endif /* NG_IPV6_H_ */ +/** + * @} + */ diff --git a/sys/include/net/ng_ipv6/addr.h b/sys/include/net/ng_ipv6/addr.h new file mode 100644 index 000000000000..be7114dbb3f8 --- /dev/null +++ b/sys/include/net/ng_ipv6/addr.h @@ -0,0 +1,507 @@ +/* + * Copyright (C) 2015 Martine Lenders + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for + * more details. + */ + +/** + * @defgroup net_ng_ipv6_addr IPv6 addresses + * @ingroup net_ng_ipv6 + * @brief IPv6 address architecture + * + * @see + * RFC 4291 + * + * + * @{ + * + * @file + * @brief Definitions for IPv6 addresses + * + * @author Martine Lenders + */ + + +#ifndef NG_IPV6_ADDR_H_ +#define NG_IPV6_ADDR_H_ + +#include + +#include "byteorder.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Length of an IPv6 address in bit. + */ +#define NG_IPV6_ADDR_BIT_LEN (128) + +/** + * @brief Data type to represent an IPv6 address. + */ +typedef union __attribute__((packed)) { + uint8_t u8[16]; /**< devided by 16 8-bit words. */ + network_uint16_t u16[8]; /**< devided by 8 16-bit words. */ + network_uint32_t u32[4]; /**< devided by 4 32-bit words. */ + network_uint64_t u64[2]; /**< devided by 2 64-bit words. */ +} ng_ipv6_addr_t; + +/** + * @brief Static initializer for the unspecified IPv6 address (::) + * + * @see + * RFC 4291, section 2.5.2 + * + */ +#define NG_IPV6_ADDR_UNSPECIFIED {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }} + +/** + * @brief Static initializer for the loopback IPv6 address (::1) + * + * @see + * RFC 4291, section 2.5.3 + * + */ +#define NG_IPV6_ADDR_LOOPBACK {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }} + +/** + * @brief Static initializer for the interface-local all nodes multicast IPv6 + * address (ff01::1) + * + * @see + * RFC 4291, section 2.7 + * + */ +#define NG_IPV6_ADDR_ALL_NODES_IF_LOCAL {{ 0xff, 0x01, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 1 }} + +/** + * @brief Static initializer for the link-local all nodes multicast IPv6 + * address (ff02::1) + * + * @see + * RFC 4291, section 2.7 + * + */ +#define NG_IPV6_ADDR_ALL_NODES_LINK_LOCAL {{ 0xff, 0x02, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 1 }} + +/** + * @brief Static initializer for the interface-local all routers multicast IPv6 + * address (ff01::2) + * + * @see + * RFC 4291, section 2.7 + * + */ +#define NG_IPV6_ADDR_ALL_ROUTERS_IF_LOCAL {{ 0xff, 0x01, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 2 }} + +/** + * @brief Static initializer for the link-local all routers multicast IPv6 + * address (ff02::2) + * + * @see + * RFC 4291, section 2.7 + * + */ +#define NG_IPV6_ADDR_ALL_ROUTERS_LINK_LOCAL {{ 0xff, 0x02, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 2 }} + + +/** + * @brief Static initializer for the site-local all routers multicast IPv6 + * address (ff05::2) + * + * @see + * RFC 4291, section 2.7 + * + */ +#define NG_IPV6_ADDR_ALL_ROUTERS_SITE_LOCAL {{ 0xff, 0x05, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 2 }} + +/** + * @brief Values for the flag field in multicast addresses. + * + * @see + * RFC 4291, section 2.7 + * + */ +typedef enum { + /** + * @brief The address is transient, i.e. not well-known, permanantly + * assigned address by IANA. + */ + NG_IPV6_ADDR_MCAST_FLAG_TRANSIENT = 0x01, + + /** + * @brief The address is based on a network prefix + * + * @see + * RFC 3306, section 4 + * + */ + NG_IPV6_ADDR_MCAST_FLAG_PREFIX_BASED = 0x02, + + /** + * @brief The address embeds the address on the rendezvous point + * + * @see + * RFC 3956, section 3 + * + */ + NG_IPV6_ADDR_MCAST_FLAG_EMBED_ON_RP = 0x04, +} ng_ipv6_addr_mcast_flag_t; + +/** + * @brief Values for the scope field in multicast addresses. + * + * @see + * RFC 4291, section 2.7 + * + */ +typedef enum { + NG_IPV6_ADDR_MCAST_SCP_IF_LOCAL = 0x1, /**< interface-local scope */ + NG_IPV6_ADDR_MCAST_SCP_LINK_LOCAL = 0x2, /**< link-local scope */ + /** + * @brief realm-local scope + * + * @see + * RFC 7346, section 3 + * and + * + * RFC 7346, section 5 + * and + */ + NG_IPV6_ADDR_MCAST_SCP_REALM_LOCAL = 0x3, + NG_IPV6_ADDR_MCAST_SCP_ADMIN_LOCAL = 0x4, /**< admin-local scope */ + NG_IPV6_ADDR_MCAST_SCP_SITE_LOCAL = 0x5, /**< site-local scope */ + NG_IPV6_ADDR_MCAST_SCP_ORG_LOCAL = 0x8, /**< organization-local scope */ + NG_IPV6_ADDR_MCAST_SCP_GLOBAL = 0xe, /**< global scope */ +} ng_ipv6_addr_mcast_scp_t; + +/** + * @brief Checks if two IPv6 addresses are equal. + * + * @param[in] a An IPv6 address. + * @param[in] b Another IPv6 address. + * + * @return true, if @p a and @p b are equal + * @return false, otherwise. + */ +static inline bool ng_ipv6_addr_equal(const ng_ipv6_addr_t *a, + const ng_ipv6_addr_t *b) +{ + return (a->u64[0].u64 == b->u64[0].u64) && + (a->u64[1].u64 == b->u64[1].u64); +} + +/** + * @brief Checks if @p addr is unspecified (all zero). + * + * @see + * RFC 4291, section 2.5.2 + * + * + * @param[in] addr An IPv6 address. + * + * @return true, if @p addr is unspecified address + * @return false, otherwise. + */ +static inline bool ng_ipv6_addr_is_unspecified(const ng_ipv6_addr_t *addr) +{ + return (addr->u64[0].u64 == 0) && + (addr->u64[1].u64 == 0); +} + +/** + * @brief Check if @p addr is a multicast address. + * + * @see + * RFC 4291, section 2.7 + * + * + * @param[in] addr An IPv6 address. + * + * @return true, if @p addr is multicast address, + * @return false, otherwise. + */ +static inline bool ng_ipv6_addr_is_multicast(const ng_ipv6_addr_t *addr) +{ + return (addr->u8[0] == 0xff); +} + +/** + * @brief Checks if @p addr is a loopback address. + * + * @see + * RFC 4291, section 2.5.3 + * + * + * @param[in] addr An IPv6 address. + * + * @return true, if @p addr is loopback address, + * @return false, otherwise. + */ +static inline bool ng_ipv6_addr_is_loopback(const ng_ipv6_addr_t *addr) +{ + return (addr->u64[0].u64 == 0) && + (byteorder_ntohll(addr->u64[1]) == 1); +} + +/** + * @brief Check if @p addr is a link-local address. + * + * @see + * RFC 4291, section 2.5.6 + * + * @see + * RFC 4291, section 2.7 + * + * + * @param[in] addr An IPv6 address. + * + * @return true, if @p addr is link-local address, + * @return false, otherwise. + */ +static inline bool ng_ipv6_addr_is_link_local(const ng_ipv6_addr_t *addr) +{ + return (byteorder_ntohll(addr->u64[0]) == 0xfe80000000000000) || + (ng_ipv6_addr_is_multicast(addr) && + (addr->u8[1] & 0x0f) == NG_IPV6_ADDR_MCAST_SCP_LINK_LOCAL); +} + +/** + * @brief Check if @p addr is unique local unicast address. + * + * @see + * RFC 4193 + * + * + * @param[in] addr An IPv6 address. + * + * @return true, if @p addr is unique local unicast address, + * @return false, otherwise. + */ +static inline bool ng_ipv6_addr_is_unique_local_unicast(const ng_ipv6_addr_t *addr) +{ + return ((addr->u8[0] == 0xfc) || (addr->u8[0] == 0xfd)); +} + +/** + * @brief Check if @p addr is solicited-node multicast address. + * + * @see + * RFC 4291, section 2.7.1 + * + * + * @param[in] addr An IPv6 address. + * + * @return true, if @p addr is solicited-node multicast address, + * @return false, otherwise. + */ +static inline bool ng_ipv6_addr_is_solicited_node(const ng_ipv6_addr_t *addr) +{ + return (byteorder_ntohll(addr->u64[0]) == 0xff02000000000000) && + (byteorder_ntohl(addr->u32[2]) == 1) && + (addr->u8[12] == 0xff); +} + +/** + * @brief Checks up to which bit-count two IPv6 addresses match in their + * prefix. + * + * @param[in] a An IPv6 address. + * @param[in] b Another IPv6 address. + * + * @return The number of bits @p a and @p b match in there prefix + */ +uint8_t ng_ipv6_addr_match_prefix(const ng_ipv6_addr_t *a, const ng_ipv6_addr_t *b); + +/** + * @brief Sets IPv6 address @p out with the first @p bits bit taken + * from @p prefix and the remaining bits to 0. + * + * @param[out] out Prefix to be set. + * @param[in] prefix Address to take prefix from. + * @param[in] bits Bits to be copied from @p prefix to @p out + * (set to 128 when greater than 128). + */ +void ng_ipv6_addr_init_prefix(ng_ipv6_addr_t *out, const ng_ipv6_addr_t *prefix, + uint8_t bits); + +/** + * @brief Sets @p addr dynamically to the unspecified IPv6 address (::). + * + * @see + * RFC 4291, section 2.5.2 + * + * + * @param[in,out] addr The address to set. + */ +static inline void ng_ipv6_addr_set_unspecified(ng_ipv6_addr_t *addr) +{ + addr->u64[0].u64 = 0; + addr->u64[1].u64 = 0; +} + +/** + * @brief Sets @p addr dynamically to the loopback IPv6 address (::1). + * + * @see + * RFC 4291, section 2.5.3 + * + * + * @param[in,out] addr The address to set. + */ +static inline void ng_ipv6_addr_set_loopback(ng_ipv6_addr_t *addr) +{ + addr->u64[0].u64 = 0; + addr->u64[1] = byteorder_htonll(1); +} + +/** + * @brief Sets the first 64 bit of @p addr to link local prefix (fe08::/64). + * + * @see + * RFC 4291, section 2.5.6 + * + * + * @param[in,out] addr The address to set. + */ +static inline void ng_ipv6_addr_set_link_local_prefix(ng_ipv6_addr_t *addr) +{ + addr->u64[0] = byteorder_htonll(0xfe80000000000000); +} + +/** + * @brief Sets the 64-bit interface ID (as integer) of a unicast or anycast + * IPv6 address. + * + * @see + * RFC 4291, section 2.5.4 + * + * + * @param[in,out] addr The address to set. + * @param[in] iid The interface ID as integer to set. + */ +static inline void ng_ipv6_addr_set_iid(ng_ipv6_addr_t *addr, uint64_t iid) +{ + addr->u64[1] = byteorder_htonll(iid); +} + +/** + * @brief Sets the 64-bit interface ID (as array) of a unicast or anycast + * IPv6 address. + * + * @see + * RFC 4291, section 2.5.4 + * + * + * @param[in,out] addr The address to set. + * @param[in] iid The interface ID as array of at least length 8 to set. + */ +static inline void ng_ipv6_addr_set_aiid(ng_ipv6_addr_t *addr, uint8_t *iid) +{ + addr->u8[8] = iid[0]; + addr->u8[9] = iid[1]; + addr->u8[10] = iid[2]; + addr->u8[11] = iid[3]; + addr->u8[12] = iid[4]; + addr->u8[13] = iid[5]; + addr->u8[14] = iid[6]; + addr->u8[15] = iid[7]; +} + + +/** + * @brief Sets the bits for an address required to be a multicast address. + * + * @see + * RFC 4291, section 2.7 + * + * + * @param[in,out] addr The address to set. + * @param[in] flags The multicast address' flags. + * @param[in] scope The multicast address' scope. + */ +static inline void ng_ipv6_addr_set_multicast(ng_ipv6_addr_t *addr, + ng_ipv6_addr_mcast_flag_t flags, + ng_ipv6_addr_mcast_scp_t scope) +{ + addr->u8[0] = 0xff; + addr->u8[1] = (((uint8_t)flags) << 4) | (((uint8_t) scope) & 0x0f); +} + +/** + * @brief Sets @p addr dynamically to an all nodes multicast IPv6 address (ff0S::1, + * where S is the scope). + * + * @see + * RFC 4291, section 2.7.1 + * + * + * @param[in,out] addr The address to set. + * @param[in] scope The multicast address' scope. + */ +static inline void ng_ipv6_addr_set_all_nodes_multicast(ng_ipv6_addr_t *addr, + ng_ipv6_addr_mcast_scp_t scope) +{ + addr->u64[0] = byteorder_htonll(0xff00000000000000); + addr->u8[1] = (uint8_t)scope; + addr->u64[1] = byteorder_htonll(1); +} + +/** + * @brief Sets @p addr dynamically to an all routers multicast IPv6 address (ff0S::2, + * where S is the scope). + * + * @see + * RFC 4291, section 2.7.1 + * + * + * @param[in,out] addr The address to set. + * @param[in] scope The multicast address' scope. + */ +static inline void ng_ipv6_addr_set_all_routers_multicast(ng_ipv6_addr_t *addr, + ng_ipv6_addr_mcast_scp_t scope) +{ + addr->u64[0] = byteorder_htonll(0xff00000000000000); + addr->u8[1] = (uint8_t)scope; + addr->u64[1] = byteorder_htonll(2); +} + +/** + * @brief Set @p out to the solicited-node multicast address + * computed from @p in. + * + * @see + * RFC 4291 + * + * + * @param[out] out Is set to solicited-node address of this node. + * @param[in] in The IPv6 address the solicited-node address. + */ +static inline void ng_ipv6_addr_set_solicited_nodes(ng_ipv6_addr_t *out, + const ng_ipv6_addr_t *in) +{ + out->u64[0] = byteorder_htonll(0xff02000000000000); + out->u32[2] = byteorder_htonl(1); + out->u8[12] = 0xff; + out->u8[13] = in->u8[13]; + out->u16[7] = in->u16[7]; +} + + +#ifdef __cplusplus +} +#endif + +#endif /* NG_IPV6_ADDR_H_ */ +/** + * @} + */ diff --git a/sys/net/network_layer/ng_ipv6/addr/Makefile b/sys/net/network_layer/ng_ipv6/addr/Makefile new file mode 100644 index 000000000000..90d60e48654c --- /dev/null +++ b/sys/net/network_layer/ng_ipv6/addr/Makefile @@ -0,0 +1,3 @@ +MODULE = ng_ipv6_addr + +include $(RIOTBASE)/Makefile.base diff --git a/sys/net/network_layer/ng_ipv6/addr/ng_ipv6_addr.c b/sys/net/network_layer/ng_ipv6/addr/ng_ipv6_addr.c new file mode 100644 index 000000000000..a329810ee4af --- /dev/null +++ b/sys/net/network_layer/ng_ipv6/addr/ng_ipv6_addr.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2015 Martine Lenders + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for + * more details. + */ + +/** + * @{ + * + * @file + * + * @author Martine Lenders + */ + +#include +#include + +#include "net/ng_ipv6/addr.h" + +uint8_t ng_ipv6_addr_match_prefix(const ng_ipv6_addr_t *a, const ng_ipv6_addr_t *b) +{ + uint8_t prefix_len = 0; + + if ((a == NULL) || (b == NULL)) { + return 0; + } + + if (a == b) { + return 128; + } + + for (int i = 0; i < 16; i++) { + /* if bytes are equal add 8 */ + if (a->u8[i] == b->u8[i]) { + prefix_len += 8; + } + else { + uint8_t xor = (a->u8[i] ^ b->u8[i]); + + /* while bits from byte equal add 1 */ + for (int j = 0; j < 8; j++) { + if ((xor & 0x80) == 0) { + prefix_len++; + xor = xor << 1; + } + else { + break; + } + } + + break; + } + } + + return prefix_len; +} + +void ng_ipv6_addr_init_prefix(ng_ipv6_addr_t *out, const ng_ipv6_addr_t *prefix, + uint8_t bits) +{ + uint8_t bytes; + + ng_ipv6_addr_set_unspecified(out); + + if (bits > 128) { + bits = 128; + } + + bytes = bits / 8; + + memcpy(out, prefix, bytes); + + if (bits % 8) { + uint8_t mask = 0xff << (8 - (bits - (bytes * 8))); + + out->u8[bytes] = prefix->u8[bytes] & mask; + } +} + +/** + * @} + */ diff --git a/tests/unittests/tests-ipv6_addr/Makefile b/tests/unittests/tests-ipv6_addr/Makefile new file mode 100644 index 000000000000..091d51ee5210 --- /dev/null +++ b/tests/unittests/tests-ipv6_addr/Makefile @@ -0,0 +1,3 @@ +MODULE = tests-ipv6_addr + +include $(RIOTBASE)/Makefile.base diff --git a/tests/unittests/tests-ipv6_addr/Makefile.include b/tests/unittests/tests-ipv6_addr/Makefile.include new file mode 100644 index 000000000000..a58da54afeab --- /dev/null +++ b/tests/unittests/tests-ipv6_addr/Makefile.include @@ -0,0 +1 @@ +USEMODULE += ng_ipv6_addr diff --git a/tests/unittests/tests-ipv6_addr/tests-ipv6_addr.c b/tests/unittests/tests-ipv6_addr/tests-ipv6_addr.c new file mode 100644 index 000000000000..03eb6efc80fd --- /dev/null +++ b/tests/unittests/tests-ipv6_addr/tests-ipv6_addr.c @@ -0,0 +1,687 @@ +/* + * Copyright (C) 2015 Martine Lenders + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @{ + * + * @file tests-ipv6_addr.c + */ +#include +#include + +#include "embUnit/embUnit.h" + +#include "byteorder.h" +#include "net/ng_ipv6/addr.h" + +#include "tests-ipv6_addr.h" + +static void test_ipv6_addr_equal_not_equal(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + ng_ipv6_addr_t b = { { + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f + } + }; + TEST_ASSERT_EQUAL_INT(false, ng_ipv6_addr_equal(&a, &b)); +} + +static void test_ipv6_addr_equal_not_equal2(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + ng_ipv6_addr_t b = { { + 0x80, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(false, ng_ipv6_addr_equal(&a, &b)); +} + +static void test_ipv6_addr_equal_not_equal3(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + ng_ipv6_addr_t b = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0e + } + }; + TEST_ASSERT_EQUAL_INT(false, ng_ipv6_addr_equal(&a, &b)); +} + +static void test_ipv6_addr_equal_not_equal4(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + ng_ipv6_addr_t b = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x25, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(false, ng_ipv6_addr_equal(&a, &b)); +} + +static void test_ipv6_addr_equal_equal(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + ng_ipv6_addr_t b = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_equal(&a, &b)); +} + +static void test_ipv6_addr_is_unspecified_not_unspecified(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(false, ng_ipv6_addr_is_unspecified(&a)); +} + +static void test_ipv6_addr_is_unspecified_unspecified(void) +{ + ng_ipv6_addr_t a = NG_IPV6_ADDR_UNSPECIFIED; + + TEST_ASSERT_EQUAL_INT(0, a.u64[0].u64); /* Don't trust the macro ;) */ + TEST_ASSERT_EQUAL_INT(0, a.u64[1].u64); + TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_is_unspecified(&a)); +} + +static void test_ipv6_addr_is_multicast_not_multicast(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x01, 0xff, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(false, ng_ipv6_addr_is_multicast(&a)); +} + +static void test_ipv6_addr_is_multicast_multicast(void) +{ + ng_ipv6_addr_t a = { { + 0xff, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_is_multicast(&a)); +} + +static void test_ipv6_addr_is_loopback_not_loopback(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(false, ng_ipv6_addr_is_loopback(&a)); +} + +static void test_ipv6_addr_is_loopback_loopback(void) +{ + ng_ipv6_addr_t a = NG_IPV6_ADDR_LOOPBACK; + + TEST_ASSERT_EQUAL_INT(0, a.u64[0].u64); /* Don't trust the macro ;) */ + TEST_ASSERT_EQUAL_INT(1, byteorder_ntohll(a.u64[1])); + TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_is_loopback(&a)); +} + +static void test_ipv6_addr_is_link_local_not_link_local(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(false, ng_ipv6_addr_is_link_local(&a)); +} + +static void test_ipv6_addr_is_link_local_nearly_link_local(void) +{ + ng_ipv6_addr_t a = { { + 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(false, ng_ipv6_addr_is_link_local(&a)); +} + +static void test_ipv6_addr_is_link_local_link_local_unicast(void) +{ + ng_ipv6_addr_t a = { { + 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_is_link_local(&a)); +} + +static void test_ipv6_addr_is_link_local_link_local_multicast1(void) +{ + ng_ipv6_addr_t a = { { + 0xff, 0x12, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_is_link_local(&a)); +} + +static void test_ipv6_addr_is_link_local_link_local_multicasta(void) +{ + ng_ipv6_addr_t a = { { + 0xff, 0xa2, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_is_link_local(&a)); +} + +static void test_ipv6_addr_is_unique_local_unicast_not_unique_local_unicast(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(false, ng_ipv6_addr_is_unique_local_unicast(&a)); +} + +static void test_ipv6_addr_is_unique_local_unicast_unique_local_unicast_locally_assigned(void) +{ + ng_ipv6_addr_t a = { { + 0xfd, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_is_unique_local_unicast(&a)); +} + +static void test_ipv6_addr_is_unique_local_unicast_unique_local_unicast_not_locally_assigned(void) +{ + ng_ipv6_addr_t a = { { + 0xfc, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_is_unique_local_unicast(&a)); +} + +static void test_ipv6_addr_is_solicited_node_no_solicited_node_multicast(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(false, ng_ipv6_addr_is_solicited_node(&a)); +} + +static void test_ipv6_addr_is_solicited_node_multicast_but_no_solicited_node(void) +{ + ng_ipv6_addr_t a = { { + 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(false, ng_ipv6_addr_is_solicited_node(&a)); +} + +static void test_ipv6_addr_is_solicited_node_solicited_node_multicast(void) +{ + ng_ipv6_addr_t a = { { + 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0xff, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_is_solicited_node(&a)); +} + +static void test_ipv6_addr_match_prefix_first_NULL(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(0, ng_ipv6_addr_match_prefix(NULL, &a)); +} + +static void test_ipv6_addr_match_prefix_second_NULL(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(0, ng_ipv6_addr_match_prefix(&a, NULL)); +} + +static void test_ipv6_addr_match_prefix_no_match(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + ng_ipv6_addr_t b = { { + 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, + 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0 + } + }; + TEST_ASSERT_EQUAL_INT(0, ng_ipv6_addr_match_prefix(&a, &b)); +} + +static void test_ipv6_addr_match_prefix_match_1(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + ng_ipv6_addr_t b = { { + 0x40, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(1, ng_ipv6_addr_match_prefix(&a, &b)); +} + +static void test_ipv6_addr_match_prefix_match_2(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + ng_ipv6_addr_t b = { { + 0x20, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(2, ng_ipv6_addr_match_prefix(&a, &b)); +} + +static void test_ipv6_addr_match_prefix_match_3(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + ng_ipv6_addr_t b = { { + 0x10, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(3, ng_ipv6_addr_match_prefix(&a, &b)); +} + +static void test_ipv6_addr_match_prefix_match_6(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + ng_ipv6_addr_t b = { { + 0x02, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(6, ng_ipv6_addr_match_prefix(&a, &b)); +} + +static void test_ipv6_addr_match_prefix_match_127(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + ng_ipv6_addr_t b = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0e + } + }; + TEST_ASSERT_EQUAL_INT(127, ng_ipv6_addr_match_prefix(&a, &b)); +} + +static void test_ipv6_addr_match_prefix_match_128(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + ng_ipv6_addr_t b = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + + TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_equal(&a, &b)); + TEST_ASSERT_EQUAL_INT(128, ng_ipv6_addr_match_prefix(&a, &b)); +} + +static void test_ipv6_addr_match_prefix_same_pointer(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + TEST_ASSERT_EQUAL_INT(128, ng_ipv6_addr_match_prefix(&a, &a)); +} + +static void test_ipv6_addr_init_prefix(void) +{ + ng_ipv6_addr_t a, b = { { + 0x00, 0x01, 0x02, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } + }; + + ng_ipv6_addr_init_prefix(&a, &b, 31); + TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_equal(&a, &b)); +} + +static void test_ipv6_addr_set_unspecified(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + + ng_ipv6_addr_set_unspecified(&a); + + TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_is_unspecified(&a)); +} + +static void test_ipv6_addr_set_loopback(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + + ng_ipv6_addr_set_loopback(&a); + + TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_is_loopback(&a)); +} + +static void test_ipv6_addr_set_link_local_prefix(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + + ng_ipv6_addr_t b = { { + 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff + } + }; + + ng_ipv6_addr_set_link_local_prefix(&a); + + TEST_ASSERT_EQUAL_INT(64, ng_ipv6_addr_match_prefix(&a, &b)); +} + +static void test_ipv6_addr_set_iid(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + + ng_ipv6_addr_t b = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff + } + }; + + ng_ipv6_addr_set_iid(&a, byteorder_ntohll(b.u64[1])); + + TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_equal(&a, &b)); +} + +static void test_ipv6_addr_set_aiid(void) +{ + ng_ipv6_addr_t a = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + + ng_ipv6_addr_t b = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff + } + }; + + ng_ipv6_addr_set_aiid(&a, &(b.u8[8])); + + TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_equal(&a, &b)); +} + +static void test_ipv6_addr_set_multicast(void) +{ + ng_ipv6_addr_t a; + ng_ipv6_addr_mcast_flag_t flags = (ng_ipv6_addr_mcast_flag_t)5; + ng_ipv6_addr_mcast_scp_t scope = NG_IPV6_ADDR_MCAST_SCP_REALM_LOCAL; + + ng_ipv6_addr_set_multicast(&a, flags, scope); + + TEST_ASSERT_EQUAL_INT(0xff, a.u8[0]); + TEST_ASSERT_EQUAL_INT((flags << 4) | scope, a.u8[1]); +} + +static void test_ipv6_addr_set_all_nodes_multicast_if_local(void) +{ + ng_ipv6_addr_t a = NG_IPV6_ADDR_UNSPECIFIED; + ng_ipv6_addr_t b = NG_IPV6_ADDR_ALL_NODES_IF_LOCAL; + ng_ipv6_addr_mcast_scp_t scope = NG_IPV6_ADDR_MCAST_SCP_IF_LOCAL; + + TEST_ASSERT_EQUAL_INT(0xff010000, byteorder_ntohl(b.u32[0])); /* Don't trust the macro ;) */ + TEST_ASSERT_EQUAL_INT(0, b.u32[1].u32); + TEST_ASSERT_EQUAL_INT(1, byteorder_ntohll(b.u64[1])); + + ng_ipv6_addr_set_all_nodes_multicast(&a, scope); + + TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_equal(&a, &b)); +} + +static void test_ipv6_addr_set_all_nodes_multicast_link_local(void) +{ + ng_ipv6_addr_t a = NG_IPV6_ADDR_UNSPECIFIED; + ng_ipv6_addr_t b = NG_IPV6_ADDR_ALL_NODES_LINK_LOCAL; + ng_ipv6_addr_mcast_scp_t scope = NG_IPV6_ADDR_MCAST_SCP_LINK_LOCAL; + + TEST_ASSERT_EQUAL_INT(0xff020000, byteorder_ntohl(b.u32[0])); /* Don't trust the macro ;) */ + TEST_ASSERT_EQUAL_INT(0, b.u32[1].u32); + TEST_ASSERT_EQUAL_INT(1, byteorder_ntohll(b.u64[1])); + + ng_ipv6_addr_set_all_nodes_multicast(&a, scope); + + TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_equal(&a, &b)); +} + +static void test_ipv6_addr_set_all_nodes_multicast_unusual(void) +{ + ng_ipv6_addr_t a; + ng_ipv6_addr_mcast_scp_t scope = NG_IPV6_ADDR_MCAST_SCP_REALM_LOCAL; + + ng_ipv6_addr_set_all_nodes_multicast(&a, scope); + + TEST_ASSERT_EQUAL_INT(0xff030000, byteorder_ntohl(a.u32[0])); + TEST_ASSERT_EQUAL_INT(0, a.u32[1].u32); + TEST_ASSERT_EQUAL_INT(1, byteorder_ntohll(a.u64[1])); +} + +static void test_ipv6_addr_set_all_routers_multicast_if_local(void) +{ + ng_ipv6_addr_t a = NG_IPV6_ADDR_UNSPECIFIED; + ng_ipv6_addr_t b = NG_IPV6_ADDR_ALL_ROUTERS_IF_LOCAL; + ng_ipv6_addr_mcast_scp_t scope = NG_IPV6_ADDR_MCAST_SCP_IF_LOCAL; + + TEST_ASSERT_EQUAL_INT(0xff010000, byteorder_ntohl(b.u32[0])); /* Don't trust the macro ;) */ + TEST_ASSERT_EQUAL_INT(0, b.u32[1].u32); + TEST_ASSERT_EQUAL_INT(2, byteorder_ntohll(b.u64[1])); + + ng_ipv6_addr_set_all_routers_multicast(&a, scope); + + TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_equal(&a, &b)); +} + +static void test_ipv6_addr_set_all_routers_multicast_link_local(void) +{ + ng_ipv6_addr_t a = NG_IPV6_ADDR_UNSPECIFIED; + ng_ipv6_addr_t b = NG_IPV6_ADDR_ALL_ROUTERS_LINK_LOCAL; + ng_ipv6_addr_mcast_scp_t scope = NG_IPV6_ADDR_MCAST_SCP_LINK_LOCAL; + + TEST_ASSERT_EQUAL_INT(0xff020000, byteorder_ntohl(b.u32[0])); /* Don't trust the macro ;) */ + TEST_ASSERT_EQUAL_INT(0, b.u32[1].u32); + TEST_ASSERT_EQUAL_INT(2, byteorder_ntohll(b.u64[1])); + + ng_ipv6_addr_set_all_routers_multicast(&a, scope); + + TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_equal(&a, &b)); +} + +static void test_ipv6_addr_set_all_routers_multicast_site_local(void) +{ + ng_ipv6_addr_t a = NG_IPV6_ADDR_UNSPECIFIED; + ng_ipv6_addr_t b = NG_IPV6_ADDR_ALL_ROUTERS_SITE_LOCAL; + ng_ipv6_addr_mcast_scp_t scope = NG_IPV6_ADDR_MCAST_SCP_SITE_LOCAL; + + TEST_ASSERT_EQUAL_INT(0xff050000, byteorder_ntohl(b.u32[0])); /* Don't trust the macro ;) */ + TEST_ASSERT_EQUAL_INT(0, b.u32[1].u32); + TEST_ASSERT_EQUAL_INT(2, byteorder_ntohll(b.u64[1])); + + ng_ipv6_addr_set_all_routers_multicast(&a, scope); + + TEST_ASSERT_EQUAL_INT(true, ng_ipv6_addr_equal(&a, &b)); +} + +static void test_ipv6_addr_set_all_routers_multicast_unusual(void) +{ + ng_ipv6_addr_t a; + ng_ipv6_addr_mcast_scp_t scope = NG_IPV6_ADDR_MCAST_SCP_ORG_LOCAL; + + ng_ipv6_addr_set_all_routers_multicast(&a, scope); + + TEST_ASSERT_EQUAL_INT(0xff080000, byteorder_ntohl(a.u32[0])); + TEST_ASSERT_EQUAL_INT(0, a.u32[1].u32); + TEST_ASSERT_EQUAL_INT(2, byteorder_ntohll(a.u64[1])); +} + +static void test_ipv6_addr_set_solicited_nodes(void) +{ + ng_ipv6_addr_t a = NG_IPV6_ADDR_UNSPECIFIED; + ng_ipv6_addr_t b = { { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + } + }; + + ng_ipv6_addr_set_solicited_nodes(&a, &b); + + TEST_ASSERT_EQUAL_INT(0xff020000, byteorder_ntohl(a.u32[0])); + TEST_ASSERT_EQUAL_INT(0, a.u32[1].u32); + TEST_ASSERT_EQUAL_INT(1, byteorder_ntohl(a.u32[2])); + TEST_ASSERT_EQUAL_INT(0xff0d0e0f, byteorder_ntohl(a.u32[3])); +} + +Test *tests_ipv6_addr_tests(void) +{ + EMB_UNIT_TESTFIXTURES(fixtures) { + new_TestFixture(test_ipv6_addr_equal_not_equal), + new_TestFixture(test_ipv6_addr_equal_not_equal2), + new_TestFixture(test_ipv6_addr_equal_not_equal3), + new_TestFixture(test_ipv6_addr_equal_not_equal4), + new_TestFixture(test_ipv6_addr_equal_equal), + new_TestFixture(test_ipv6_addr_is_unspecified_not_unspecified), + new_TestFixture(test_ipv6_addr_is_unspecified_unspecified), + new_TestFixture(test_ipv6_addr_is_multicast_not_multicast), + new_TestFixture(test_ipv6_addr_is_multicast_multicast), + new_TestFixture(test_ipv6_addr_is_loopback_not_loopback), + new_TestFixture(test_ipv6_addr_is_loopback_loopback), + new_TestFixture(test_ipv6_addr_is_link_local_not_link_local), + new_TestFixture(test_ipv6_addr_is_link_local_nearly_link_local), + new_TestFixture(test_ipv6_addr_is_link_local_link_local_unicast), + new_TestFixture(test_ipv6_addr_is_link_local_link_local_multicast1), + new_TestFixture(test_ipv6_addr_is_link_local_link_local_multicasta), + new_TestFixture(test_ipv6_addr_is_unique_local_unicast_not_unique_local_unicast), + new_TestFixture(test_ipv6_addr_is_unique_local_unicast_unique_local_unicast_locally_assigned), + new_TestFixture(test_ipv6_addr_is_unique_local_unicast_unique_local_unicast_not_locally_assigned), + new_TestFixture(test_ipv6_addr_is_solicited_node_no_solicited_node_multicast), + new_TestFixture(test_ipv6_addr_is_solicited_node_multicast_but_no_solicited_node), + new_TestFixture(test_ipv6_addr_is_solicited_node_solicited_node_multicast), + new_TestFixture(test_ipv6_addr_match_prefix_first_NULL), + new_TestFixture(test_ipv6_addr_match_prefix_second_NULL), + new_TestFixture(test_ipv6_addr_match_prefix_no_match), + new_TestFixture(test_ipv6_addr_match_prefix_match_1), + new_TestFixture(test_ipv6_addr_match_prefix_match_2), + new_TestFixture(test_ipv6_addr_match_prefix_match_3), + new_TestFixture(test_ipv6_addr_match_prefix_match_6), + new_TestFixture(test_ipv6_addr_match_prefix_match_127), + new_TestFixture(test_ipv6_addr_match_prefix_match_128), + new_TestFixture(test_ipv6_addr_match_prefix_same_pointer), + new_TestFixture(test_ipv6_addr_init_prefix), + new_TestFixture(test_ipv6_addr_set_unspecified), + new_TestFixture(test_ipv6_addr_set_loopback), + new_TestFixture(test_ipv6_addr_set_link_local_prefix), + new_TestFixture(test_ipv6_addr_set_iid), + new_TestFixture(test_ipv6_addr_set_aiid), + new_TestFixture(test_ipv6_addr_set_multicast), + new_TestFixture(test_ipv6_addr_set_all_nodes_multicast_if_local), + new_TestFixture(test_ipv6_addr_set_all_nodes_multicast_link_local), + new_TestFixture(test_ipv6_addr_set_all_nodes_multicast_unusual), + new_TestFixture(test_ipv6_addr_set_all_routers_multicast_if_local), + new_TestFixture(test_ipv6_addr_set_all_routers_multicast_link_local), + new_TestFixture(test_ipv6_addr_set_all_routers_multicast_site_local), + new_TestFixture(test_ipv6_addr_set_all_routers_multicast_unusual), + new_TestFixture(test_ipv6_addr_set_solicited_nodes), + }; + + EMB_UNIT_TESTCALLER(ipv6_addr_tests, NULL, NULL, fixtures); + + return (Test *)&ipv6_addr_tests; +} + +void tests_ipv6_addr(void) +{ + TESTS_RUN(tests_ipv6_addr_tests()); +} +/** @} */ diff --git a/tests/unittests/tests-ipv6_addr/tests-ipv6_addr.h b/tests/unittests/tests-ipv6_addr/tests-ipv6_addr.h new file mode 100644 index 000000000000..77e6dace3ddb --- /dev/null +++ b/tests/unittests/tests-ipv6_addr/tests-ipv6_addr.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2015 Martine Lenders + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @addtogroup unittests + * @{ + * + * @file + * @brief Unittests for the ``ng_ipv6_addr`` module + * + * @author Martine Lenders + */ +#ifndef TESTS_IPV6_ADDR_H_ +#define TESTS_IPV6_ADDR_H_ + +#include "embUnit.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief The entry point of this test suite. + */ +void tests_ipv6_addr(void); + +#ifdef __cplusplus +} +#endif + +#endif /* TESTS_IPV6_ADDR_H_ */ +/** @} */