Commit 6c41d375 authored by Dominik Charousset's avatar Dominik Charousset

Properly compute net address for subnets

parent 556cffa4
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright (C) 2011 - 2017 *
* Dominik Charousset <dominik.charousset (at) haw-hamburg.de> *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
#include <array>
#include <cstdint>
namespace caf {
namespace detail {
/// Sets all bits after bits_to_keep to 0.
template <size_t NumBytes>
void mask_bits(std::array<uint8_t, NumBytes>& bytes, size_t bits_to_keep) {
// Calculate how many bytes we keep.
auto bytes_to_keep = bits_to_keep / 8;
if (bytes_to_keep >= NumBytes)
return;
// See whether we have an unclean cut, e.g. keeping 7 bits of a byte.
auto byte_cutoff = bits_to_keep % 8;
auto i = bytes.begin() + bytes_to_keep;
if (byte_cutoff != 0) {
static constexpr uint8_t mask[] = {0x00, 0x80, 0xC0, 0xE0,
0xF0, 0xF8, 0xFC, 0xFE};
*i = *i & mask[byte_cutoff];
++i;
}
// Zero remaining bytes.
for (; i != bytes.end(); ++i)
*i = 0;
}
} // namespace detail
} // namespace caf
......@@ -18,6 +18,8 @@
#include "caf/ipv4_subnet.hpp"
#include "caf/detail/mask_bits.hpp"
namespace caf {
// -- constructors, destructors, and assignment operators --------------------
......@@ -29,7 +31,7 @@ ipv4_subnet::ipv4_subnet() : prefix_length_(0) {
ipv4_subnet::ipv4_subnet(ipv4_address network_address, uint8_t prefix_length)
: address_(network_address),
prefix_length_(prefix_length) {
// nop
detail::mask_bits(address_.bytes(), prefix_length_);
}
// -- properties ---------------------------------------------------------------
......
......@@ -18,6 +18,8 @@
#include "caf/ipv6_subnet.hpp"
#include "caf/detail/mask_bits.hpp"
namespace caf {
// -- constructors, destructors, and assignment operators --------------------
......@@ -29,19 +31,19 @@ ipv6_subnet::ipv6_subnet() : prefix_length_(0) {
ipv6_subnet::ipv6_subnet(ipv4_subnet subnet)
: address_(ipv6_address{subnet.network_address()}),
prefix_length_(v4_offset + subnet.prefix_length()){
// nop
detail::mask_bits(address_.bytes(), prefix_length_);
}
ipv6_subnet::ipv6_subnet(ipv4_address network_address, uint8_t prefix_length)
: address_(network_address),
prefix_length_(prefix_length + v4_offset) {
// nop
detail::mask_bits(address_.bytes(), prefix_length_);
}
ipv6_subnet::ipv6_subnet(ipv6_address network_address, uint8_t prefix_length)
: address_(network_address),
prefix_length_(prefix_length) {
// nop
detail::mask_bits(address_.bytes(), prefix_length_);
}
// -- properties ---------------------------------------------------------------
......
......@@ -44,6 +44,16 @@ CAF_TEST(constructing) {
CAF_CHECK_EQUAL(local.prefix_length(), 8u);
}
CAF_TEST(equality) {
auto a = addr(0xff, 0xff, 0xff, 0xff) / 19;
auto b = addr(0xff, 0xff, 0xff, 0xab) / 19;
auto net = addr(0xff, 0xff, 0xe0, 0x00);
CAF_CHECK_EQUAL(a.network_address(), net);
CAF_CHECK_EQUAL(a.network_address(), b.network_address());
CAF_CHECK_EQUAL(a.prefix_length(), b.prefix_length());
CAF_CHECK_EQUAL(a, b);
}
CAF_TEST(constains) {
ipv4_subnet local{addr(127, 0, 0, 0), 8};
CAF_CHECK(local.contains(addr(127, 0, 0, 1)));
......
......@@ -39,6 +39,16 @@ CAF_TEST(constructing) {
CAF_CHECK_EQUAL(zero.prefix_length(), 128u);
}
CAF_TEST(equality) {
auto a = ipv6_address{{0xffff, 0xffff, 0xffff}, {}} / 27;
auto b = ipv6_address{{0xffff, 0xffff, 0xabab}, {}} / 27;
auto net = ipv6_address{{0xffff, 0xffe0}, {}};
CAF_CHECK_EQUAL(a.network_address(), net);
CAF_CHECK_EQUAL(a.network_address(), b.network_address());
CAF_CHECK_EQUAL(a.prefix_length(), b.prefix_length());
CAF_CHECK_EQUAL(a, b);
}
CAF_TEST(constains) {
auto local = ipv6_address{{0xbebe, 0xbebe}, {}} / 32;
CAF_CHECK(local.contains(ipv6_address({0xbebe, 0xbebe, 0xbebe}, {})));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment