From c5acf0227d7ed546b3051789034002fde96e848d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cenk=20G=C3=BCndo=C4=9Fan?= Date: Mon, 26 Oct 2015 11:36:02 +0100 Subject: [PATCH] ipv6/addr: initialize iid part of an ipv6 address --- sys/include/net/ipv6/addr.h | 11 ++++++++++ sys/net/network_layer/ipv6/addr/ipv6_addr.c | 23 +++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/sys/include/net/ipv6/addr.h b/sys/include/net/ipv6/addr.h index bc311fc9c6..bbb66aa094 100644 --- a/sys/include/net/ipv6/addr.h +++ b/sys/include/net/ipv6/addr.h @@ -470,6 +470,17 @@ uint8_t ipv6_addr_match_prefix(const ipv6_addr_t *a, const ipv6_addr_t *b); */ void ipv6_addr_init_prefix(ipv6_addr_t *out, const ipv6_addr_t *prefix, uint8_t bits); +/** + * @brief Sets the last @p bits of IPv6 address @p out to @p iid. + * Leading bits of @p out stay untouched. + * + * @param[out] out IPv6 address to be set. + * @param[in] iid buffer representing the iid. + * @param[in] bits Bits to be copied from @p iid to @p out + * (set to 128 when greater than 128). + */ +void ipv6_addr_init_iid(ipv6_addr_t *out, const uint8_t *iid, uint8_t bits); + /** * @brief Sets @p addr dynamically to the unspecified IPv6 address (::). * diff --git a/sys/net/network_layer/ipv6/addr/ipv6_addr.c b/sys/net/network_layer/ipv6/addr/ipv6_addr.c index 1e2d2dbbb6..9f4f9ab0bc 100644 --- a/sys/net/network_layer/ipv6/addr/ipv6_addr.c +++ b/sys/net/network_layer/ipv6/addr/ipv6_addr.c @@ -77,6 +77,29 @@ void ipv6_addr_init_prefix(ipv6_addr_t *out, const ipv6_addr_t *prefix, out->u8[bytes] |= (prefix->u8[bytes] & mask); } } + +void ipv6_addr_init_iid(ipv6_addr_t *out, const uint8_t *iid, uint8_t bits) +{ + uint8_t unaligned_bits, bytes, pos; + + if (bits > 128) { + bits = 128; + } + + unaligned_bits = bits % 8; + bytes = bits / 8; + pos = (IPV6_ADDR_BIT_LEN / 8) - bytes; + + if (unaligned_bits) { + uint8_t mask = 0xff << unaligned_bits; + out->u8[pos - 1] &= mask; + out->u8[pos - 1] |= (*iid & ~mask); + iid++; + } + + memcpy(&(out->u8[pos]), iid, bytes); +} + /** * @} */