diff --git a/repos/os/include/net/ipv4.h b/repos/os/include/net/ipv4.h index 48f04b42e..cef5b11c2 100644 --- a/repos/os/include/net/ipv4.h +++ b/repos/os/include/net/ipv4.h @@ -30,8 +30,6 @@ namespace Net class Ipv4_address; - class Ipv4_address_prefix; - class Ipv4_packet; } @@ -222,61 +220,9 @@ class Net::Ipv4_packet } __attribute__((packed)); -struct Net::Ipv4_address_prefix -{ - Ipv4_address address; - Genode::uint8_t prefix = 32; - - bool valid() const { return address.valid() || !prefix; } - - void print(Genode::Output &output) const; - - bool prefix_matches(Ipv4_address const &ip) const; - - Ipv4_address subnet_mask() const - { - Ipv4_address result; - if (prefix >= 8) { - - result.addr[0] = 0xff; - - if (prefix >= 16) { - - result.addr[1] = 0xff; - - if (prefix >= 24) { - - result.addr[2] = 0xff; - result.addr[3] = 0xff << (32 - prefix); - } else { - result.addr[2] = 0xff << (24 - prefix); - } - } else { - result.addr[1] = 0xff << (16 - prefix); - } - } else { - result.addr[0] = 0xff << (8 - prefix); - } - return result; - } - - Ipv4_address broadcast_address() const - { - Ipv4_address result = address; - Ipv4_address const mask = subnet_mask(); - for (unsigned i = 0; i < 4; i++) { - result.addr[i] |= ~mask.addr[i]; - } - return result; - } -}; - - namespace Genode { inline size_t ascii_to(char const *s, Net::Ipv4_address &result); - - inline size_t ascii_to(char const *s, Net::Ipv4_address_prefix &result); } @@ -310,30 +256,4 @@ Genode::size_t Genode::ascii_to(char const *s, Net::Ipv4_address &result) } } - -Genode::size_t Genode::ascii_to(char const *s, Net::Ipv4_address_prefix &result) -{ - /* read the leading IPv4 address, fail if there's no address */ - Net::Ipv4_address_prefix buf; - size_t read_len = ascii_to(s, buf.address); - if (!read_len) { - return 0; } - - /* check for the following slash */ - s += read_len; - if (*s != '/') { - return 0; } - read_len++; - s++; - - /* read the prefix, fail if there's no prefix */ - size_t prefix_len = ascii_to_unsigned(s, buf.prefix, 10); - if (!prefix_len) { - return 0; } - - /* fill result and return read length */ - result = buf; - return read_len + prefix_len; -} - #endif /* _IPV4_H_ */ diff --git a/repos/os/src/lib/net/ipv4.cc b/repos/os/src/lib/net/ipv4.cc index 7a2cb3076..2c2b2da30 100644 --- a/repos/os/src/lib/net/ipv4.cc +++ b/repos/os/src/lib/net/ipv4.cc @@ -149,24 +149,3 @@ Genode::uint16_t Ipv4_packet::calculate_checksum(Ipv4_packet const &packet) const Ipv4_address Ipv4_packet::CURRENT((Genode::uint8_t)0x00); const Ipv4_address Ipv4_packet::BROADCAST((Genode::uint8_t)0xFF); - - -void Ipv4_address_prefix::print(Genode::Output &output) const -{ - Genode::print(output, address, "/", prefix); -} - -bool Ipv4_address_prefix::prefix_matches(Ipv4_address const &ip) const -{ - uint8_t prefix_left = prefix; - uint8_t byte = 0; - for (; prefix_left >= 8; prefix_left -= 8, byte++) { - if (ip.addr[byte] != address.addr[byte]) { - return false; } - } - if (prefix_left == 0) { - return true; } - - uint8_t const mask = ~(0xff >> prefix_left); - return !((ip.addr[byte] ^ address.addr[byte]) & mask); -} diff --git a/repos/os/src/server/nic_router/direct_rule.h b/repos/os/src/server/nic_router/direct_rule.h index 9f4b30090..44e2439a9 100644 --- a/repos/os/src/server/nic_router/direct_rule.h +++ b/repos/os/src/server/nic_router/direct_rule.h @@ -14,14 +14,14 @@ #ifndef _DIRECT_RULE_H_ #define _DIRECT_RULE_H_ +/* local includes */ +#include +#include + /* Genode includes */ -#include #include #include -/* local includes */ -#include - namespace Genode { class Xml_node; } namespace Net { diff --git a/repos/os/src/server/nic_router/ipv4_address_prefix.cc b/repos/os/src/server/nic_router/ipv4_address_prefix.cc new file mode 100644 index 000000000..d22d1295a --- /dev/null +++ b/repos/os/src/server/nic_router/ipv4_address_prefix.cc @@ -0,0 +1,79 @@ +/* + * \brief Ipv4 address combined with a subnet prefix length + * \author Martin Stein + * \date 2017-10-12 + */ + +/* + * Copyright (C) 2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* local includes */ +#include + +using namespace Genode; +using namespace Net; + + +Ipv4_address Ipv4_address_prefix::subnet_mask() const +{ + Ipv4_address result; + if (prefix >= 8) { + + result.addr[0] = 0xff; + + if (prefix >= 16) { + + result.addr[1] = 0xff; + + if (prefix >= 24) { + + result.addr[2] = 0xff; + result.addr[3] = 0xff << (32 - prefix); + } else { + result.addr[2] = 0xff << (24 - prefix); + } + } else { + result.addr[1] = 0xff << (16 - prefix); + } + } else { + result.addr[0] = 0xff << (8 - prefix); + } + return result; +} + + +void Ipv4_address_prefix::print(Genode::Output &output) const +{ + Genode::print(output, address, "/", prefix); +} + + +bool Ipv4_address_prefix::prefix_matches(Ipv4_address const &ip) const +{ + uint8_t prefix_left = prefix; + uint8_t byte = 0; + for (; prefix_left >= 8; prefix_left -= 8, byte++) { + if (ip.addr[byte] != address.addr[byte]) { + return false; } + } + if (prefix_left == 0) { + return true; } + + uint8_t const mask = ~(0xff >> prefix_left); + return !((ip.addr[byte] ^ address.addr[byte]) & mask); +} + + +Ipv4_address Ipv4_address_prefix::broadcast_address() const +{ + Ipv4_address result = address; + Ipv4_address const mask = subnet_mask(); + for (unsigned i = 0; i < 4; i++) { + result.addr[i] |= ~mask.addr[i]; + } + return result; +} diff --git a/repos/os/src/server/nic_router/ipv4_address_prefix.h b/repos/os/src/server/nic_router/ipv4_address_prefix.h new file mode 100644 index 000000000..396da637e --- /dev/null +++ b/repos/os/src/server/nic_router/ipv4_address_prefix.h @@ -0,0 +1,71 @@ +/* + * \brief Ipv4 address combined with a subnet prefix length + * \author Martin Stein + * \date 2017-10-12 + */ + +/* + * Copyright (C) 2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _IPV4_ADDRESS_PREFIX_H_ +#define _IPV4_ADDRESS_PREFIX_H_ + +/* Genode includes */ +#include + +namespace Net { class Ipv4_address_prefix; } + + +struct Net::Ipv4_address_prefix +{ + Ipv4_address address; + Genode::uint8_t prefix { 32 }; + + bool valid() const { return address.valid() || prefix == 0; } + + void print(Genode::Output &output) const; + + bool prefix_matches(Ipv4_address const &ip) const; + + Ipv4_address subnet_mask() const; + + Ipv4_address broadcast_address() const; +}; + + +namespace Genode { + + inline size_t ascii_to(char const *s, Net::Ipv4_address_prefix &result); +} + + +Genode::size_t Genode::ascii_to(char const *s, Net::Ipv4_address_prefix &result) +{ + /* read the leading IPv4 address, fail if there's no address */ + Net::Ipv4_address_prefix buf; + size_t read_len = ascii_to(s, buf.address); + if (!read_len) { + return 0; } + + /* check for the following slash */ + s += read_len; + if (*s != '/') { + return 0; } + read_len++; + s++; + + /* read the prefix, fail if there's no prefix */ + size_t prefix_len = ascii_to_unsigned(s, buf.prefix, 10); + if (!prefix_len) { + return 0; } + + /* fill result and return read length */ + result = buf; + return read_len + prefix_len; +} + +#endif /* _IPV4_ADDRESS_PREFIX_H_ */ diff --git a/repos/os/src/server/nic_router/target.mk b/repos/os/src/server/nic_router/target.mk index 9fb66be04..29e250bd3 100644 --- a/repos/os/src/server/nic_router/target.mk +++ b/repos/os/src/server/nic_router/target.mk @@ -2,7 +2,7 @@ TARGET = nic_router LIBS += base net -SRC_CC += arp_waiter.cc ip_rule.cc +SRC_CC += arp_waiter.cc ip_rule.cc ipv4_address_prefix.cc SRC_CC += component.cc port_allocator.cc forward_rule.cc SRC_CC += nat_rule.cc mac_allocator.cc main.cc SRC_CC += uplink.cc interface.cc arp_cache.cc configuration.cc diff --git a/repos/os/src/server/nic_router/uplink.h b/repos/os/src/server/nic_router/uplink.h index 0d6165fdc..b162fa98f 100644 --- a/repos/os/src/server/nic_router/uplink.h +++ b/repos/os/src/server/nic_router/uplink.h @@ -20,6 +20,7 @@ /* local includes */ #include +#include namespace Net { class Uplink; }