net_flood: fix CRC error, make more precise

Issue #2953
This commit is contained in:
Martin Stein 2018-07-12 15:26:30 +02:00 committed by Christian Helmuth
parent 304cb290d9
commit 7b47c8f0c6
2 changed files with 108 additions and 95 deletions

View File

@ -39,8 +39,9 @@ class Main : public Nic_handler,
using Periodic_timeout = Timer::Periodic_timeout<Main>; using Periodic_timeout = Timer::Periodic_timeout<Main>;
struct Bad_protocol : Exception { };
enum { IPV4_TIME_TO_LIVE = 64 }; enum { IPV4_TIME_TO_LIVE = 64 };
enum { ICMP_DATA_SIZE = 56 };
enum { ICMP_SEQ = 1 }; enum { ICMP_SEQ = 1 };
enum { SRC_PORT = 50000 }; enum { SRC_PORT = 50000 };
enum { FIRST_DST_PORT = 49152 }; enum { FIRST_DST_PORT = 49152 };
@ -50,7 +51,7 @@ class Main : public Nic_handler,
Attached_rom_dataspace _config_rom { _env, "config" }; Attached_rom_dataspace _config_rom { _env, "config" };
Xml_node _config { _config_rom.xml() }; Xml_node _config { _config_rom.xml() };
Timer::Connection _timer { _env }; Timer::Connection _timer { _env };
Microseconds _period_us { 100 }; Microseconds _period_us { 1 };
Constructible<Periodic_timeout> _period { }; Constructible<Periodic_timeout> _period { };
Heap _heap { &_env.ram(), &_env.rm() }; Heap _heap { &_env.ram(), &_env.rm() };
bool const _verbose { _config.attribute_value("verbose", false) }; bool const _verbose { _config.attribute_value("verbose", false) };
@ -63,6 +64,9 @@ class Main : public Nic_handler,
Ipv4_address() }; Ipv4_address() };
Protocol const _protocol { _config.attribute_value("protocol", Protocol::ICMP) }; Protocol const _protocol { _config.attribute_value("protocol", Protocol::ICMP) };
Port _dst_port { FIRST_DST_PORT }; Port _dst_port { FIRST_DST_PORT };
size_t _ping_sz { _init_ping_sz() };
size_t _init_ping_sz() const;
void _handle_arp(Ethernet_frame &eth, void _handle_arp(Ethernet_frame &eth,
Size_guard &size_guard); Size_guard &size_guard);
@ -195,6 +199,18 @@ void Main::_handle_arp(Ethernet_frame &eth,
} }
size_t Main::_init_ping_sz() const
{
enum { IP_SZ = sizeof(Ethernet_frame) + sizeof(Ipv4_packet) };
switch (_protocol) {
case Protocol::ICMP: return IP_SZ + sizeof(Icmp_packet);
case Protocol::UDP: return IP_SZ + sizeof(Udp_packet);
case Protocol::TCP: return IP_SZ + sizeof(Tcp_packet);
default: throw Bad_protocol();
}
}
void Main::_send_arp_reply(Ethernet_frame &req_eth, void Main::_send_arp_reply(Ethernet_frame &req_eth,
Arp_packet &req_arp) Arp_packet &req_arp)
{ {
@ -258,9 +274,9 @@ void Main::_send_ping(Duration)
_broadcast_arp_request(ip_config().gateway); } _broadcast_arp_request(ip_config().gateway); }
return; return;
} }
_nic.send(sizeof(Ethernet_frame) + sizeof(Ipv4_packet) + try {
sizeof(Icmp_packet) + ICMP_DATA_SIZE, while (true) {
[&] (void *pkt_base, Size_guard &size_guard) _nic.send(_ping_sz, [&] (void *pkt_base, Size_guard &size_guard)
{ {
/* create ETH header */ /* create ETH header */
Ethernet_frame &eth = Ethernet_frame::construct_at(pkt_base, size_guard); Ethernet_frame &eth = Ethernet_frame::construct_at(pkt_base, size_guard);
@ -290,9 +306,7 @@ void Main::_send_ping(Duration)
icmp.code(Icmp_packet::Code::ECHO_REQUEST); icmp.code(Icmp_packet::Code::ECHO_REQUEST);
icmp.query_id(_dst_port.value); icmp.query_id(_dst_port.value);
icmp.query_seq(ICMP_SEQ); icmp.query_seq(ICMP_SEQ);
icmp.update_checksum(0);
/* finish ICMP header */
icmp.update_checksum(ICMP_DATA_SIZE);
/* prepare next ICMP ping */ /* prepare next ICMP ping */
if (_dst_port.value == LAST_DST_PORT) { if (_dst_port.value == LAST_DST_PORT) {
@ -349,6 +363,9 @@ void Main::_send_ping(Duration)
ip.total_length(size_guard.head_size() - ip_off); ip.total_length(size_guard.head_size() - ip_off);
ip.update_checksum(); ip.update_checksum();
}); });
}
}
catch (Net::Packet_stream_source::Packet_alloc_failed) { }
} }

View File

@ -51,7 +51,7 @@ class Net::Nic
using Signal_handler = Genode::Signal_handler<Nic>; using Signal_handler = Genode::Signal_handler<Nic>;
enum { PKT_SIZE = ::Nic::Packet_allocator::DEFAULT_PACKET_SIZE }; enum { PKT_SIZE = ::Nic::Packet_allocator::DEFAULT_PACKET_SIZE };
enum { BUF_SIZE = 90 * PKT_SIZE }; enum { BUF_SIZE = 1000 * PKT_SIZE };
Genode::Env &_env; Genode::Env &_env;
Genode::Allocator &_alloc; Genode::Allocator &_alloc;
@ -101,7 +101,6 @@ class Net::Nic
void send(Genode::size_t pkt_size, void send(Genode::size_t pkt_size,
FUNC && write_to_pkt) FUNC && write_to_pkt)
{ {
try {
Packet_descriptor pkt = _source().alloc_packet(pkt_size); Packet_descriptor pkt = _source().alloc_packet(pkt_size);
void *pkt_base = _source().packet_content(pkt); void *pkt_base = _source().packet_content(pkt);
Size_guard size_guard(pkt_size); Size_guard size_guard(pkt_size);
@ -113,9 +112,6 @@ class Net::Nic
catch (Size_guard::Exceeded) { Genode::log("snd ?"); } catch (Size_guard::Exceeded) { Genode::log("snd ?"); }
} }
} }
catch (Net::Packet_stream_source::Packet_alloc_failed) {
Genode::warning("failed to allocate packet"); }
}
/*************** /***************