diff --git a/repos/libports/run/nic_router_ipv4_fragm.run b/repos/libports/run/nic_router_ipv4_fragm.run new file mode 100644 index 0000000000..05e2e392cc --- /dev/null +++ b/repos/libports/run/nic_router_ipv4_fragm.run @@ -0,0 +1,161 @@ +# +# To execute this run script on your Linux host you have to do some +# preparation: +# +# 1) Setup a TAP device: +# ! sudo ip tuntap add dev tap0 mode tap user $USER +# ! sudo ip address flush dev tap0 +# ! sudo ip address add 10.0.2.1/24 brd 10.0.2.255 dev tap0 +# ! sudo ip link set dev tap0 addr 02:00:00:ca:fe:01 +# ! sudo ip link set dev tap0 up +# +# 2) Ensure that 'nping' is installed and that it is permitted run +# UDP mode as user (examplary for Ubuntu 18.04): +# ! sudo apt install nmap +# ! sudo setcap cap_net_raw=+ep /usr/bin/nping +# +# 3) Now, start the test: +# ! cd build/x86_64 +# ! make run/nic_router_ipv4_fragm KERNEL=linux BOARD=linux +# +# 4) Clean up your Linux when done testing: +# ! sudo ip tuntap delete tap0 mode tap +# + +if {![have_board linux]} { + puts "Run script is not supported on this platform." + exit 0 +} + +set nping_missing [catch { + spawn nping --version + expect { + {Nping version} { } + eof { return } + timeout { return } + } +}] + +if {$nping_missing} { + puts "\nPlease install 'nping' and try again\n" + exit 1; +} + +create_boot_directory + +import_from_depot [depot_user]/pkg/[drivers_nic_pkg] + +build { core init timer server/nic_router app/ping test/lwip/udp } + +append config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } + +install_config $config +build_boot_image { + core init timer nic_router ping test-lwip-udp-server ld.lib.so libc.lib.so + libm.lib.so vfs.lib.so vfs_lwip.lib.so } + +# wait for server ip stack to come up +run_genode_until {.*lwIP Nic interface up.*\n} 30 +set genode_id [output_spawn_id] + +# ping server without ipv4 fragmentation (should succeed) +spawn nping -c 1 --privileged --udp --data-length 160 --mtu 800 -p 8000 10.0.2.55 +set pattern_string "" +append pattern_string {.*RCVD .* UDP 10\.0\.2\.55:8000 > 10\.0\.2\.1:53 .*\n} +append pattern_string {.*Raw packets sent: 1 (188B) | Rcvd: 1 (188B) | Lost: 0.*\n} +run_genode_until $pattern_string 30 $spawn_id + +# ping server with ipv4 fragmentation (should fail) +spawn nping -c 1 --privileged --udp --data-length 1600 --mtu 800 -p 8000 10.0.2.55 +set pattern_string "" +expect eof + +# check that the nic router dropped the ipv4 fragments of the second ping +set pattern_string "" +append pattern_string {.*drop packet .fragmented IPv4 not supported.*\n} +append pattern_string {.*drop packet .fragmented IPv4 not supported.*\n} +append pattern_string {.*drop packet .fragmented IPv4 not supported.*\n} +run_genode_until $pattern_string 30 $genode_id diff --git a/repos/os/src/server/nic_router/interface.cc b/repos/os/src/server/nic_router/interface.cc index 8a42059ed9..e5c8496f8b 100644 --- a/repos/os/src/server/nic_router/interface.cc +++ b/repos/os/src/server/nic_router/interface.cc @@ -1115,11 +1115,15 @@ void Interface::_handle_ip(Ethernet_frame ð, Packet_descriptor const &pkt, Domain &local_domain) { - /* read packet information */ + /* drop fragmented IPv4 as it isn't supported */ Ipv4_packet &ip = eth.data(size_guard); - Ipv4_address_prefix const &local_intf = local_domain.ip_config().interface; + if (ip.more_fragments() || + ip.fragment_offset() != 0) { + throw Drop_packet("fragmented IPv4 not supported"); + } /* try handling subnet-local IP packets */ + Ipv4_address_prefix const &local_intf = local_domain.ip_config().interface; if (local_intf.prefix_matches(ip.dst()) && ip.dst() != local_intf.address) { diff --git a/tool/autopilot.list b/tool/autopilot.list index 997deb5724..4b4c75cde7 100644 --- a/tool/autopilot.list +++ b/tool/autopilot.list @@ -42,6 +42,7 @@ nic_bridge nic_bridge_stress nic_dump nic_router +nic_router_ipv4_fragm nic_router_disable_arp nic_router_dhcp_managed nic_router_dhcp_unmanaged