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) static bool is_dhcp(Udp_packet const *udp)
{ {
return ((udp->src_port() == Dhcp_packet::BOOTPC || return ((udp->src_port() == Port(Dhcp_packet::BOOTPC) ||
udp->src_port() == Dhcp_packet::BOOTPS) && udp->src_port() == Port(Dhcp_packet::BOOTPS)) &&
(udp->dst_port() == Dhcp_packet::BOOTPC || (udp->dst_port() == Port(Dhcp_packet::BOOTPC) ||
udp->dst_port() == Dhcp_packet::BOOTPS)); 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/ethernet.h>
#include <net/ipv4.h> #include <net/ipv4.h>
#include <util/register.h> #include <util/register.h>
#include <net/port.h>
namespace Net namespace Net
{ {
@ -75,11 +76,11 @@ class Net::Tcp_packet
class No_tcp_packet : Exception {}; class No_tcp_packet : Exception {};
void src_port(Genode::uint16_t p) { _src_port = host_to_big_endian(p); } void src_port(Port p) { _src_port = host_to_big_endian(p.value); }
void dst_port(Genode::uint16_t p) { _dst_port = host_to_big_endian(p); } 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); } Port src_port() const { return Port(host_to_big_endian(_src_port)); }
uint16_t dst_port() const { return host_to_big_endian(_dst_port); } Port dst_port() const { return Port(host_to_big_endian(_dst_port)); }
uint16_t flags() const { return host_to_big_endian(_flags); } uint16_t flags() const { return host_to_big_endian(_flags); }
Tcp_packet(size_t size) { Tcp_packet(size_t size) {

View File

@ -17,7 +17,7 @@
/* Genode */ /* Genode */
#include <base/exception.h> #include <base/exception.h>
#include <base/stdint.h> #include <base/stdint.h>
#include <net/port.h>
#include <util/endian.h> #include <util/endian.h>
#include <net/ethernet.h> #include <net/ethernet.h>
#include <net/ipv4.h> #include <net/ipv4.h>
@ -75,13 +75,13 @@ class Net::Udp_packet
** UDP field read-accessors ** ** UDP field read-accessors **
******************************/ ******************************/
Genode::uint16_t src_port() const { return host_to_big_endian(_src_port); } Port src_port() const { return Port(host_to_big_endian(_src_port)); }
Genode::uint16_t dst_port() const { return host_to_big_endian(_dst_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 length() const { return host_to_big_endian(_length); }
Genode::uint16_t checksum() const { return host_to_big_endian(_checksum); } 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 src_port(Port p) { _src_port = host_to_big_endian(p.value); }
void dst_port(Genode::uint16_t p) { _dst_port = host_to_big_endian(p); } 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 * data() { return (T *)(_data); }
template <typename T> T const * data() const { return (T const *)(_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) Forward_rule::Forward_rule(Domain_tree &domains, Xml_node const &node)
: :
Leaf_rule(domains, 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())) _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(); } 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) { if (port == _port) {
return *this; } 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) { if (!rule) {
throw Forward_rule_tree::No_match(); } 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_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()) { if (!first()) {
throw No_match(); } throw No_match(); }

View File

@ -20,6 +20,7 @@
/* Genode includes */ /* Genode includes */
#include <util/avl_tree.h> #include <util/avl_tree.h>
#include <net/ipv4.h> #include <net/ipv4.h>
#include <net/port.h>
namespace Net { namespace Net {
@ -35,14 +36,14 @@ class Net::Forward_rule : public Leaf_rule,
{ {
private: private:
Genode::uint8_t const _port; Port const _port;
Ipv4_address const _to; Ipv4_address const _to;
public: public:
Forward_rule(Domain_tree &domains, Genode::Xml_node const &node); 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 ** ** 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 { }; 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_ */ #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, static Port _dst_port(uint8_t const prot, void *const prot_base)
void *const prot_base)
{ {
switch (prot) { switch (prot) {
case Tcp_packet::IP_ID: return (*(Tcp_packet *)prot_base).dst_port(); case Tcp_packet::IP_ID: return (*(Tcp_packet *)prot_base).dst_port();
@ -104,7 +103,7 @@ static uint16_t _dst_port(uint8_t const prot,
static void _dst_port(uint8_t const prot, static void _dst_port(uint8_t const prot,
void *const prot_base, void *const prot_base,
uint16_t const port) Port const port)
{ {
switch (prot) { switch (prot) {
case Tcp_packet::IP_ID: (*(Tcp_packet *)prot_base).dst_port(port); return; 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, static Port _src_port(uint8_t const prot, void *const prot_base)
void *const prot_base)
{ {
switch (prot) { switch (prot) {
case Tcp_packet::IP_ID: return (*(Tcp_packet *)prot_base).src_port(); case Tcp_packet::IP_ID: return (*(Tcp_packet *)prot_base).src_port();
@ -125,7 +123,7 @@ static uint16_t _src_port(uint8_t const prot,
static void _src_port(uint8_t const prot, static void _src_port(uint8_t const prot,
void *const prot_base, void *const prot_base,
uint16_t const port) Port const port)
{ {
switch (prot) { switch (prot) {
case Tcp_packet::IP_ID: ((Tcp_packet *)prot_base)->src_port(port); return; 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/avl_tree.h>
#include <util/list.h> #include <util/list.h>
#include <net/ipv4.h> #include <net/ipv4.h>
#include <net/port.h>
/* local includes */ /* local includes */
#include <pointer.h> #include <pointer.h>
@ -43,9 +44,9 @@ struct Net::Link_side_id
{ {
int const data[]; int const data[];
Ipv4_address const src_ip; Ipv4_address const src_ip;
Genode::uint16_t const src_port; Port const src_port;
Ipv4_address const dst_ip; Ipv4_address const dst_ip;
Genode::uint16_t const dst_port; Port const dst_port;
static constexpr Genode::size_t data_size(); 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; } Link &link() const { return _link; }
Ipv4_address const &src_ip() const { return _id.src_ip; } Ipv4_address const &src_ip() const { return _id.src_ip; }
Ipv4_address const &dst_ip() const { return _id.dst_ip; } Ipv4_address const &dst_ip() const { return _id.dst_ip; }
Genode::uint16_t src_port() const { return _id.src_port; } Port src_port() const { return _id.src_port; }
Genode::uint16_t dst_port() const { return _id.dst_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) 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) Xml_node const &node)
: :
Permit_rule(domains, 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(); } throw Invalid(); }
} }
Permit_single_rule const & 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) { if (port == _port) {
return *this; } 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); Permit_single_rule *const rule = Avl_node<Permit_single_rule>::child(side);
if (!rule) { if (!rule) {
throw Permit_single_rule_tree::No_match(); } 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 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(); Permit_single_rule *const rule = first();
if (!rule) { if (!rule) {

View File

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

View File

@ -18,33 +18,38 @@ using namespace Net;
using namespace Genode; 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) { if (_used == _max) {
throw Out_of_indices(); } throw Out_of_indices(); }
uint16_t const port = _port_alloc.alloc(); Port const port = _port_alloc.alloc();
_used++; _used++;
return port; return port;
} }
void Port_allocator_guard::free(Genode::uint16_t port) void Port_allocator_guard::free(Port const port)
{ {
_port_alloc.free(port); _port_alloc.free(port);
_used = _used ? _used - 1 : 0; _used = _used ? _used - 1 : 0;
} }
Port_allocator_guard::Port_allocator_guard(Port_allocator & port_alloc, Port_allocator_guard::Port_allocator_guard(Port_allocator &port_alloc,
unsigned const max) unsigned const max)
: :
_port_alloc(port_alloc), _max(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 */ /* Genode includes */
#include <util/bit_allocator.h> #include <util/bit_allocator.h>
#include <net/port.h>
namespace Net { namespace Net {
class Port_allocator; class Port_allocator;
class Port_allocator_guard; 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: 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 {}; 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); 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; } if (_permit_any) { return *_permit_any; }
return _permit_single_rules.find_by_port(port); 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, Genode::Cstring const &protocol,
Configuration &config); 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_ */ #endif /* _TRANSPORT_RULE_H_ */