net: introduce and apply Net::Port type

Thereby fix bug in the NIC router that previously used uint8_t values for ports in
some places.

Ref #2193
This commit is contained in:
Martin Stein 2016-12-06 14:12:18 +01:00 committed by Norman Feske
parent 27cc0a402a
commit eef18e1ecd
14 changed files with 137 additions and 71 deletions

View File

@ -257,10 +257,10 @@ class Net::Dhcp_packet
static bool is_dhcp(Udp_packet const *udp)
{
return ((udp->src_port() == Dhcp_packet::BOOTPC ||
udp->src_port() == Dhcp_packet::BOOTPS) &&
(udp->dst_port() == Dhcp_packet::BOOTPC ||
udp->dst_port() == Dhcp_packet::BOOTPS));
return ((udp->src_port() == Port(Dhcp_packet::BOOTPC) ||
udp->src_port() == Port(Dhcp_packet::BOOTPS)) &&
(udp->dst_port() == Port(Dhcp_packet::BOOTPC) ||
udp->dst_port() == Port(Dhcp_packet::BOOTPS)));
}

View File

@ -0,0 +1,56 @@
/*
* \brief Network port
* \author Martin Stein
* \date 2016-08-19
*/
/*
* Copyright (C) 2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _NET__PORT_H_
#define _NET__PORT_H_
/* Genode includes */
#include <base/stdint.h>
#include <base/output.h>
#include <util/string.h>
namespace Net { class Port; }
/**
* This class makes it clear what the port integer-value means at an interface
*/
struct Net::Port
{
Genode::uint16_t value;
explicit Port(Genode::uint16_t const value) : value(value) { }
bool operator == (Port const &other) const { return value == other.value; }
void print(Genode::Output &out) const { Genode::print(out, value); }
}
__attribute__((packed));
namespace Genode {
/**
* Read port value from string
*
* \return number of consumed characters
*/
inline size_t ascii_to(const char *s, Net::Port &result)
{
unsigned value = 0;
size_t const consumed = ascii_to_unsigned(s, value, 0);
result = Net::Port(value);
return consumed;
}
}
#endif /* _NET__PORT_H_ */

View File

@ -21,6 +21,7 @@
#include <net/ethernet.h>
#include <net/ipv4.h>
#include <util/register.h>
#include <net/port.h>
namespace Net
{
@ -75,12 +76,12 @@ class Net::Tcp_packet
class No_tcp_packet : Exception {};
void src_port(Genode::uint16_t p) { _src_port = host_to_big_endian(p); }
void dst_port(Genode::uint16_t p) { _dst_port = host_to_big_endian(p); }
void src_port(Port p) { _src_port = host_to_big_endian(p.value); }
void dst_port(Port p) { _dst_port = host_to_big_endian(p.value); }
uint16_t src_port() const { return host_to_big_endian(_src_port); }
uint16_t dst_port() const { return host_to_big_endian(_dst_port); }
uint16_t flags() const { return host_to_big_endian(_flags); }
Port src_port() const { return Port(host_to_big_endian(_src_port)); }
Port dst_port() const { return Port(host_to_big_endian(_dst_port)); }
uint16_t flags() const { return host_to_big_endian(_flags); }
Tcp_packet(size_t size) {
if (size < sizeof(Tcp_packet)) { throw No_tcp_packet(); } }

View File

@ -17,7 +17,7 @@
/* Genode */
#include <base/exception.h>
#include <base/stdint.h>
#include <net/port.h>
#include <util/endian.h>
#include <net/ethernet.h>
#include <net/ipv4.h>
@ -75,13 +75,13 @@ class Net::Udp_packet
** UDP field read-accessors **
******************************/
Genode::uint16_t src_port() const { return host_to_big_endian(_src_port); }
Genode::uint16_t dst_port() const { return host_to_big_endian(_dst_port); }
Port src_port() const { return Port(host_to_big_endian(_src_port)); }
Port dst_port() const { return Port(host_to_big_endian(_dst_port)); }
Genode::uint16_t length() const { return host_to_big_endian(_length); }
Genode::uint16_t checksum() const { return host_to_big_endian(_checksum); }
void src_port(Genode::uint16_t p) { _src_port = host_to_big_endian(p); }
void dst_port(Genode::uint16_t p) { _dst_port = host_to_big_endian(p); }
void src_port(Port p) { _src_port = host_to_big_endian(p.value); }
void dst_port(Port p) { _dst_port = host_to_big_endian(p.value); }
template <typename T> T * data() { return (T *)(_data); }
template <typename T> T const * data() const { return (T const *)(_data); }

View File

@ -36,20 +36,22 @@ void Forward_rule::print(Output &output) const
Forward_rule::Forward_rule(Domain_tree &domains, Xml_node const &node)
:
Leaf_rule(domains, node),
_port(node.attribute_value("port", 0UL)),
_port(node.attribute_value("port", Port(0))),
_to(node.attribute_value("to", Ipv4_address()))
{
if (!_port || !_to.valid() || dynamic_port(_port)) {
if (_port == Port(0) || !_to.valid() || dynamic_port(_port)) {
throw Invalid(); }
}
Forward_rule const &Forward_rule::find_by_port(uint8_t const port) const
Forward_rule const &Forward_rule::find_by_port(Port const port) const
{
if (port == _port) {
return *this; }
Forward_rule *const rule = Avl_node<Forward_rule>::child(port > _port);
Forward_rule *const rule =
Avl_node<Forward_rule>::child(port.value > _port.value);
if (!rule) {
throw Forward_rule_tree::No_match(); }
@ -61,7 +63,7 @@ Forward_rule const &Forward_rule::find_by_port(uint8_t const port) const
** Forward_rule_tree **
***********************/
Forward_rule const &Forward_rule_tree::find_by_port(uint8_t const port) const
Forward_rule const &Forward_rule_tree::find_by_port(Port const port) const
{
if (!first()) {
throw No_match(); }

View File

@ -20,6 +20,7 @@
/* Genode includes */
#include <util/avl_tree.h>
#include <net/ipv4.h>
#include <net/port.h>
namespace Net {
@ -35,14 +36,14 @@ class Net::Forward_rule : public Leaf_rule,
{
private:
Genode::uint8_t const _port;
Ipv4_address const _to;
Port const _port;
Ipv4_address const _to;
public:
Forward_rule(Domain_tree &domains, Genode::Xml_node const &node);
Forward_rule const &find_by_port(Genode::uint8_t const port) const;
Forward_rule const &find_by_port(Port const port) const;
/*********
@ -56,7 +57,8 @@ class Net::Forward_rule : public Leaf_rule,
** Avl_node **
**************/
bool higher(Forward_rule *rule) { return rule->_port > _port; }
bool higher(Forward_rule *rule) {
return rule->_port.value > _port.value; }
/***************
@ -71,7 +73,7 @@ struct Net::Forward_rule_tree : Genode::Avl_tree<Forward_rule>
{
struct No_match : Genode::Exception { };
Forward_rule const &find_by_port(Genode::uint8_t const port) const;
Forward_rule const &find_by_port(Port const port) const;
};
#endif /* _FORWARD_RULE_H_ */

View File

@ -92,8 +92,7 @@ static void _update_checksum(uint8_t const prot,
}
static uint16_t _dst_port(uint8_t const prot,
void *const prot_base)
static Port _dst_port(uint8_t const prot, void *const prot_base)
{
switch (prot) {
case Tcp_packet::IP_ID: return (*(Tcp_packet *)prot_base).dst_port();
@ -102,9 +101,9 @@ static uint16_t _dst_port(uint8_t const prot,
}
static void _dst_port(uint8_t const prot,
void *const prot_base,
uint16_t const port)
static void _dst_port(uint8_t const prot,
void *const prot_base,
Port const port)
{
switch (prot) {
case Tcp_packet::IP_ID: (*(Tcp_packet *)prot_base).dst_port(port); return;
@ -113,8 +112,7 @@ static void _dst_port(uint8_t const prot,
}
static uint16_t _src_port(uint8_t const prot,
void *const prot_base)
static Port _src_port(uint8_t const prot, void *const prot_base)
{
switch (prot) {
case Tcp_packet::IP_ID: return (*(Tcp_packet *)prot_base).src_port();
@ -123,9 +121,9 @@ static uint16_t _src_port(uint8_t const prot,
}
static void _src_port(uint8_t const prot,
void *const prot_base,
uint16_t const port)
static void _src_port(uint8_t const prot,
void *const prot_base,
Port const port)
{
switch (prot) {
case Tcp_packet::IP_ID: ((Tcp_packet *)prot_base)->src_port(port); return;

View File

@ -19,6 +19,7 @@
#include <util/avl_tree.h>
#include <util/list.h>
#include <net/ipv4.h>
#include <net/port.h>
/* local includes */
#include <pointer.h>
@ -41,11 +42,11 @@ namespace Net {
struct Net::Link_side_id
{
int const data[];
Ipv4_address const src_ip;
Genode::uint16_t const src_port;
Ipv4_address const dst_ip;
Genode::uint16_t const dst_port;
int const data[];
Ipv4_address const src_ip;
Port const src_port;
Ipv4_address const dst_ip;
Port const dst_port;
static constexpr Genode::size_t data_size();
@ -104,8 +105,8 @@ class Net::Link_side : public Genode::Avl_node<Link_side>
Link &link() const { return _link; }
Ipv4_address const &src_ip() const { return _id.src_ip; }
Ipv4_address const &dst_ip() const { return _id.dst_ip; }
Genode::uint16_t src_port() const { return _id.src_port; }
Genode::uint16_t dst_port() const { return _id.dst_port; }
Port src_port() const { return _id.src_port; }
Port dst_port() const { return _id.dst_port; }
};

View File

@ -54,7 +54,7 @@ Permit_any_rule::Permit_any_rule(Domain_tree &domains, Xml_node const &node)
bool Permit_single_rule::higher(Permit_single_rule *rule)
{
return rule->_port > _port;
return rule->_port.value > _port.value;
}
@ -68,20 +68,20 @@ Permit_single_rule::Permit_single_rule(Domain_tree &domains,
Xml_node const &node)
:
Permit_rule(domains, node),
_port(node.attribute_value("port", 0UL))
_port(node.attribute_value("port", Port(0)))
{
if (!_port || dynamic_port(_port)) {
if (_port == Port(0) || dynamic_port(_port)) {
throw Invalid(); }
}
Permit_single_rule const &
Permit_single_rule::find_by_port(uint16_t const port) const
Permit_single_rule::find_by_port(Port const port) const
{
if (port == _port) {
return *this; }
bool const side = port > _port;
bool const side = port.value > _port.value;
Permit_single_rule *const rule = Avl_node<Permit_single_rule>::child(side);
if (!rule) {
throw Permit_single_rule_tree::No_match(); }
@ -96,7 +96,7 @@ Permit_single_rule::find_by_port(uint16_t const port) const
*****************************/
Permit_single_rule const &
Permit_single_rule_tree::find_by_port(uint16_t const port) const
Permit_single_rule_tree::find_by_port(Port const port) const
{
Permit_single_rule *const rule = first();
if (!rule) {

View File

@ -19,6 +19,7 @@
/* Genode includes */
#include <util/avl_tree.h>
#include <net/port.h>
namespace Genode { class Output; }
@ -62,15 +63,14 @@ class Net::Permit_single_rule : public Permit_rule,
{
private:
Genode::uint16_t const _port;
Port const _port;
public:
Permit_single_rule(Domain_tree &domains,
Genode::Xml_node const &node);
Permit_single_rule const &
find_by_port(Genode::uint16_t const port) const;
Permit_single_rule const &find_by_port(Port const port) const;
/*********
@ -91,7 +91,7 @@ class Net::Permit_single_rule : public Permit_rule,
** Accessors **
***************/
Genode::uint16_t port() const { return _port; }
Port port() const { return _port; }
};
@ -99,7 +99,7 @@ struct Net::Permit_single_rule_tree : Genode::Avl_tree<Permit_single_rule>
{
struct No_match : Genode::Exception { };
Permit_single_rule const &find_by_port(Genode::uint16_t const port) const;
Permit_single_rule const &find_by_port(Port const port) const;
};
#endif /* _PERMIT_RULE_H_ */

View File

@ -18,33 +18,38 @@ using namespace Net;
using namespace Genode;
Genode::uint16_t Port_allocator_guard::alloc()
bool Net::dynamic_port(Port const port)
{
return port.value >= (unsigned)Port_allocator::FIRST &&
port.value < (unsigned)Port_allocator::FIRST +
Port_allocator::COUNT;
}
/**************************
** Port_allocator_guard **
**************************/
Port Port_allocator_guard::alloc()
{
if (_used == _max) {
throw Out_of_indices(); }
uint16_t const port = _port_alloc.alloc();
Port const port = _port_alloc.alloc();
_used++;
return port;
}
void Port_allocator_guard::free(Genode::uint16_t port)
void Port_allocator_guard::free(Port const port)
{
_port_alloc.free(port);
_used = _used ? _used - 1 : 0;
}
Port_allocator_guard::Port_allocator_guard(Port_allocator & port_alloc,
unsigned const max)
Port_allocator_guard::Port_allocator_guard(Port_allocator &port_alloc,
unsigned const max)
:
_port_alloc(port_alloc), _max(max)
{ }
bool Net::dynamic_port(uint16_t const port)
{
return port >= Port_allocator::FIRST &&
port < (uint32_t)Port_allocator::FIRST + Port_allocator::COUNT;
}

View File

@ -17,13 +17,14 @@
/* Genode includes */
#include <util/bit_allocator.h>
#include <net/port.h>
namespace Net {
class Port_allocator;
class Port_allocator_guard;
bool dynamic_port(Genode::uint16_t const port);
bool dynamic_port(Port const port);
}
@ -39,9 +40,9 @@ class Net::Port_allocator
public:
Genode::uint16_t alloc() { return _alloc.alloc() + FIRST; }
Port alloc() { return Port(_alloc.alloc() + FIRST); }
void free(Genode::uint16_t port) { _alloc.free(port - FIRST); }
void free(Port const port) { _alloc.free(port.value - FIRST); }
};
@ -57,9 +58,9 @@ class Net::Port_allocator_guard
class Out_of_indices : Genode::Exception {};
Genode::uint16_t alloc();
Port alloc();
void free(Genode::uint16_t port);
void free(Port const port);
Port_allocator_guard(Port_allocator & port_alloc, unsigned const max);

View File

@ -72,7 +72,7 @@ Transport_rule::Transport_rule(Domain_tree &domains,
}
Permit_rule const &Transport_rule::permit_rule(uint16_t const port) const
Permit_rule const &Transport_rule::permit_rule(Port const port) const
{
if (_permit_any) { return *_permit_any; }
return _permit_single_rules.find_by_port(port);

View File

@ -48,7 +48,7 @@ class Net::Transport_rule : public Direct_rule<Transport_rule>
Genode::Cstring const &protocol,
Configuration &config);
Permit_rule const &permit_rule(Genode::uint16_t const port) const;
Permit_rule const &permit_rule(Port const port) const;
};
#endif /* _TRANSPORT_RULE_H_ */