diff --git a/repos/os/include/net/icmp.h b/repos/os/include/net/icmp.h index f1da401979..288a56bb6f 100644 --- a/repos/os/include/net/icmp.h +++ b/repos/os/include/net/icmp.h @@ -114,6 +114,8 @@ class Net::Icmp_packet void update_checksum(Genode::size_t data_sz); + void update_checksum(Internet_checksum_diff const &icd); + bool checksum_error(Genode::size_t data_sz) const; @@ -157,6 +159,9 @@ class Net::Icmp_packet void query_id(Genode::uint16_t v) { _rest_of_header_u16[0] = host_to_big_endian(v); } void query_seq(Genode::uint16_t v) { _rest_of_header_u16[1] = host_to_big_endian(v); } + void type_and_code(Type t, Code c, Internet_checksum_diff &icd); + void query_id(Genode::uint16_t v, Internet_checksum_diff &icd); + /********* ** log ** diff --git a/repos/os/include/net/internet_checksum.h b/repos/os/include/net/internet_checksum.h index 8ff8ccd566..b0bfe27385 100644 --- a/repos/os/include/net/internet_checksum.h +++ b/repos/os/include/net/internet_checksum.h @@ -76,6 +76,11 @@ namespace Net { Packed_uint16 const *old_data_ptr, Genode::size_t data_sz); + /** + * Update this modifier by adding up another modifier + */ + void add_up_diff(Internet_checksum_diff const &icd); + /** * Return the given checksum with this modifier applied */ diff --git a/repos/os/include/net/ipv4.h b/repos/os/include/net/ipv4.h index ad01ceea83..41380a4e1d 100644 --- a/repos/os/include/net/ipv4.h +++ b/repos/os/include/net/ipv4.h @@ -98,6 +98,9 @@ class Net::Ipv4_packet void update_checksum(Internet_checksum_diff const &icd); + void update_checksum(Internet_checksum_diff const &icd, + Internet_checksum_diff &caused_icd); + bool checksum_error() const; private: diff --git a/repos/os/include/net/tcp.h b/repos/os/include/net/tcp.h index a4f38a66dd..8d0cec9a56 100644 --- a/repos/os/include/net/tcp.h +++ b/repos/os/include/net/tcp.h @@ -72,6 +72,8 @@ class Net::Tcp_packet Ipv4_address ip_dst, size_t tcp_size); + void update_checksum(Internet_checksum_diff const &icd); + /*************** ** Accessors ** @@ -99,6 +101,9 @@ class Net::Tcp_packet 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); } + void src_port(Port p, Internet_checksum_diff &icd); + void dst_port(Port p, Internet_checksum_diff &icd); + /********* ** log ** diff --git a/repos/os/include/net/udp.h b/repos/os/include/net/udp.h index fc1e50310f..f275aa14f2 100644 --- a/repos/os/include/net/udp.h +++ b/repos/os/include/net/udp.h @@ -84,6 +84,8 @@ class Net::Udp_packet void update_checksum(Ipv4_address ip_src, Ipv4_address ip_dst); + void update_checksum(Internet_checksum_diff const &icd); + bool checksum_error(Ipv4_address ip_src, Ipv4_address ip_dst) const; @@ -103,6 +105,9 @@ class Net::Udp_packet void src_port_big_endian(Genode::uint16_t v) { _src_port = v; } void dst_port_big_endian(Genode::uint16_t v) { _dst_port = v; } + void src_port(Port p, Internet_checksum_diff &icd); + void dst_port(Port p, Internet_checksum_diff &icd); + /********* ** log ** diff --git a/repos/os/src/lib/net/icmp.cc b/repos/os/src/lib/net/icmp.cc index 50d673a906..772d6ef634 100644 --- a/repos/os/src/lib/net/icmp.cc +++ b/repos/os/src/lib/net/icmp.cc @@ -34,7 +34,33 @@ void Icmp_packet::update_checksum(size_t data_sz) } +void Icmp_packet::update_checksum(Internet_checksum_diff const &icd) +{ + _checksum = icd.apply_to(_checksum); +} + + bool Icmp_packet::checksum_error(size_t data_sz) const { return internet_checksum((Packed_uint16 *)this, sizeof(Icmp_packet) + data_sz); } + + +void Icmp_packet::query_id(uint16_t v, Internet_checksum_diff &icd) +{ + uint16_t const v_be { host_to_big_endian(v) }; + icd.add_up_diff(( + Packed_uint16 *)&v_be, (Packed_uint16 *)&_rest_of_header_u16[0], 2); + + _rest_of_header_u16[0] = v_be; +} + + +void Icmp_packet::type_and_code(Type t, Code c, Internet_checksum_diff &icd) +{ + uint16_t const old_type_and_code { *(uint16_t*)this }; + type(t); + code(c); + icd.add_up_diff( + (Packed_uint16 *)&_type, (Packed_uint16 *)&old_type_and_code, 2); +} diff --git a/repos/os/src/lib/net/internet_checksum.cc b/repos/os/src/lib/net/internet_checksum.cc index 0580337e90..77ee15b70b 100644 --- a/repos/os/src/lib/net/internet_checksum.cc +++ b/repos/os/src/lib/net/internet_checksum.cc @@ -96,6 +96,12 @@ uint16_t Net::internet_checksum_pseudo_ip(Packed_uint16 const *data_ptr, ** Internet_checksum_diff ** ****************************/ +void Internet_checksum_diff::add_up_diff(Internet_checksum_diff const &icd) +{ + _value += icd._value; +} + + void Internet_checksum_diff::add_up_diff(Packed_uint16 const *new_data_ptr, Packed_uint16 const *old_data_ptr, size_t data_sz) diff --git a/repos/os/src/lib/net/ipv4.cc b/repos/os/src/lib/net/ipv4.cc index e2a4e5646a..cc33996343 100644 --- a/repos/os/src/lib/net/ipv4.cc +++ b/repos/os/src/lib/net/ipv4.cc @@ -176,3 +176,15 @@ void Ipv4_packet::update_checksum(Internet_checksum_diff const &icd) { _checksum = icd.apply_to(_checksum); } + + +void +Ipv4_packet::update_checksum(Internet_checksum_diff const &icd, + Internet_checksum_diff &caused_icd) +{ + uint16_t const new_checksum { icd.apply_to(_checksum) }; + caused_icd.add_up_diff( + (Packed_uint16 *)&new_checksum, (Packed_uint16 *)&_checksum, 2); + + _checksum = new_checksum; +} diff --git a/repos/os/src/lib/net/tcp.cc b/repos/os/src/lib/net/tcp.cc index d25d1ee277..f600454457 100644 --- a/repos/os/src/lib/net/tcp.cc +++ b/repos/os/src/lib/net/tcp.cc @@ -47,3 +47,25 @@ void Net::Tcp_packet::update_checksum(Ipv4_address ip_src, host_to_big_endian((uint16_t)tcp_size), Ipv4_packet::Protocol::TCP, ip_src, ip_dst); } + + +void Net::Tcp_packet::update_checksum(Internet_checksum_diff const &icd) +{ + _checksum = icd.apply_to(_checksum); +} + + +void Net::Tcp_packet::src_port(Port p, Internet_checksum_diff &icd) +{ + uint16_t const p_be { host_to_big_endian(p.value) }; + icd.add_up_diff((Packed_uint16 *)&p_be, (Packed_uint16 *)&_src_port, 2); + _src_port = p_be; +} + + +void Net::Tcp_packet::dst_port(Port p, Internet_checksum_diff &icd) +{ + uint16_t const p_be { host_to_big_endian(p.value) }; + icd.add_up_diff((Packed_uint16 *)&p_be, (Packed_uint16 *)&_dst_port, 2); + _dst_port = p_be; +} diff --git a/repos/os/src/lib/net/udp.cc b/repos/os/src/lib/net/udp.cc index 0c99cff1bb..766399dc6d 100644 --- a/repos/os/src/lib/net/udp.cc +++ b/repos/os/src/lib/net/udp.cc @@ -41,9 +41,31 @@ void Net::Udp_packet::update_checksum(Ipv4_address ip_src, } +void Net::Udp_packet::update_checksum(Internet_checksum_diff const &icd) +{ + _checksum = icd.apply_to(_checksum); +} + + bool Net::Udp_packet::checksum_error(Ipv4_address ip_src, Ipv4_address ip_dst) const { return internet_checksum_pseudo_ip((Packed_uint16 *)this, length(), _length, Ipv4_packet::Protocol::UDP, ip_src, ip_dst); } + + +void Net::Udp_packet::src_port(Port p, Internet_checksum_diff &icd) +{ + uint16_t const p_be { host_to_big_endian(p.value) }; + icd.add_up_diff((Packed_uint16 *)&p_be, (Packed_uint16 *)&_src_port, 2); + _src_port = p_be; +} + + +void Net::Udp_packet::dst_port(Port p, Internet_checksum_diff &icd) +{ + uint16_t const p_be { host_to_big_endian(p.value) }; + icd.add_up_diff((Packed_uint16 *)&p_be, (Packed_uint16 *)&_dst_port, 2); + _dst_port = p_be; +} diff --git a/repos/os/src/server/nic_router/interface.cc b/repos/os/src/server/nic_router/interface.cc index 114587a032..83c869ad19 100644 --- a/repos/os/src/server/nic_router/interface.cc +++ b/repos/os/src/server/nic_router/interface.cc @@ -155,25 +155,21 @@ static void _link_packet(L3_protocol const prot, } -static void _update_checksum(L3_protocol const prot, - void *const prot_base, - size_t const prot_size, - Ipv4_address const src, - Ipv4_address const dst, - size_t const ip_size) +static void _l4_update_checksum(L3_protocol const prot, + void *const prot_base, + Internet_checksum_diff const &prot_icd) { switch (prot) { case L3_protocol::TCP: - ((Tcp_packet *)prot_base)->update_checksum(src, dst, prot_size); + ((Tcp_packet *)prot_base)->update_checksum(prot_icd); return; case L3_protocol::UDP: - ((Udp_packet *)prot_base)->update_checksum(src, dst); + ((Udp_packet *)prot_base)->update_checksum(prot_icd); return; case L3_protocol::ICMP: { Icmp_packet &icmp = *(Icmp_packet *)prot_base; - icmp.update_checksum(ip_size - sizeof(Ipv4_packet) - - sizeof(Icmp_packet)); + icmp.update_checksum(prot_icd); return; } default: throw Interface::Bad_transport_protocol(); } @@ -190,14 +186,15 @@ static Port _dst_port(L3_protocol const prot, void *const prot_base) } -static void _dst_port(L3_protocol const prot, - void *const prot_base, - Port const port) +static void _dst_port(L3_protocol const prot, + void *const prot_base, + Internet_checksum_diff &prot_icd, + Port const port) { switch (prot) { - case L3_protocol::TCP: (*(Tcp_packet *)prot_base).dst_port(port); return; - case L3_protocol::UDP: (*(Udp_packet *)prot_base).dst_port(port); return; - case L3_protocol::ICMP: (*(Icmp_packet *)prot_base).query_id(port.value); return; + case L3_protocol::TCP: (*(Tcp_packet *)prot_base).dst_port(port, prot_icd); return; + case L3_protocol::UDP: (*(Udp_packet *)prot_base).dst_port(port, prot_icd); return; + case L3_protocol::ICMP: (*(Icmp_packet *)prot_base).query_id(port.value, prot_icd); return; default: throw Interface::Bad_transport_protocol(); } } @@ -212,14 +209,15 @@ static Port _src_port(L3_protocol const prot, void *const prot_base) } -static void _src_port(L3_protocol const prot, - void *const prot_base, - Port const port) +static void _src_port(L3_protocol const prot, + void *const prot_base, + Internet_checksum_diff &prot_icd, + Port const port) { switch (prot) { - case L3_protocol::TCP: ((Tcp_packet *)prot_base)->src_port(port); return; - case L3_protocol::UDP: ((Udp_packet *)prot_base)->src_port(port); return; - case L3_protocol::ICMP: ((Icmp_packet *)prot_base)->query_id(port.value); return; + case L3_protocol::TCP: ((Tcp_packet *)prot_base)->src_port(port, prot_icd); return; + case L3_protocol::UDP: ((Udp_packet *)prot_base)->src_port(port, prot_icd); return; + case L3_protocol::ICMP: ((Icmp_packet *)prot_base)->query_id(port.value, prot_icd); return; default: throw Interface::Bad_transport_protocol(); } } @@ -301,11 +299,9 @@ void Interface::_pass_prot_to_domain(Domain &domain, Internet_checksum_diff const &ip_icd, L3_protocol const prot, void *const prot_base, - size_t const prot_size) + Internet_checksum_diff const &prot_icd) { - _update_checksum( - prot, prot_base, prot_size, ip.src(), ip.dst(), ip.total_length()); - + _l4_update_checksum(prot, prot_base, prot_icd); ip.update_checksum(ip_icd); domain.interfaces().for_each([&] (Interface &interface) { @@ -584,7 +580,7 @@ void Interface::_nat_link_and_pass(Ethernet_frame ð, Internet_checksum_diff &ip_icd, L3_protocol const prot, void *const prot_base, - size_t const prot_size, + Internet_checksum_diff &prot_icd, Link_side_id const &local_id, Domain &local_domain, Domain &remote_domain) @@ -598,8 +594,13 @@ void Interface::_nat_link_and_pass(Ethernet_frame ð, if(_config().verbose()) { log("[", local_domain, "] using NAT rule: ", nat); } - _src_port(prot, prot_base, nat.port_alloc(prot).alloc()); - ip.src(remote_domain.ip_config().interface().address, ip_icd); + _src_port(prot, prot_base, prot_icd, nat.port_alloc(prot).alloc()); + Internet_checksum_diff icd { }; + ip.src(remote_domain.ip_config().interface().address, icd); + ip_icd.add_up_diff(icd); + if (prot == L3_protocol::TCP || prot == L3_protocol::UDP) { + prot_icd.add_up_diff(icd); + } remote_port_alloc = nat.port_alloc(prot); }, [&] /* no_match */ () { } @@ -609,7 +610,7 @@ void Interface::_nat_link_and_pass(Ethernet_frame ð, _new_link(prot, local_id, remote_port_alloc, remote_domain, remote_id); _pass_prot_to_domain( remote_domain, eth, size_guard, ip, ip_icd, prot, prot_base, - prot_size); + prot_icd); } catch (Port_allocator_guard::Out_of_indices) { switch (prot) { @@ -945,11 +946,11 @@ void Interface::handle_interface_link_state() } -void Interface::_send_icmp_echo_reply(Ethernet_frame ð, - Ipv4_packet &ip, - Icmp_packet &icmp, - size_t icmp_sz, - Size_guard &size_guard) +void Interface::_send_icmp_echo_reply(Ethernet_frame ð, + Ipv4_packet &ip, + Icmp_packet &icmp, + Internet_checksum_diff &icmp_icd, + Size_guard &size_guard) { /* adapt Ethernet header */ Mac_address const eth_src = eth.src(); @@ -962,8 +963,9 @@ void Interface::_send_icmp_echo_reply(Ethernet_frame ð, ip.dst(ip_src); /* adapt ICMP header */ - icmp.type(Icmp_packet::Type::ECHO_REPLY); - icmp.code(Icmp_packet::Code::ECHO_REPLY); + icmp.type_and_code(Icmp_packet::Type::ECHO_REPLY, + Icmp_packet::Code::ECHO_REPLY, + icmp_icd); /* * Update checksums and send @@ -971,7 +973,7 @@ void Interface::_send_icmp_echo_reply(Ethernet_frame ð, * Skip updating the IPv4 checksum because we have only swapped SRC and * DST and these changes cancel each other out in checksum calculation. */ - icmp.update_checksum(icmp_sz - sizeof(Icmp_packet)); + icmp.update_checksum(icmp_icd); send(eth, size_guard); } @@ -983,7 +985,7 @@ void Interface::_handle_icmp_query(Ethernet_frame ð, Packet_descriptor const &pkt, L3_protocol prot, void *prot_base, - size_t prot_size, + Internet_checksum_diff &prot_icd, Domain &local_domain) { Link_side_id const local_id = { ip.src(), _src_port(prot, prot_base), @@ -1004,13 +1006,18 @@ void Interface::_handle_icmp_query(Ethernet_frame ð, " link: ", link); } _adapt_eth(eth, remote_side.src_ip(), pkt, remote_domain); - ip.src(remote_side.dst_ip(), ip_icd); - ip.dst(remote_side.src_ip(), ip_icd); - _src_port(prot, prot_base, remote_side.dst_port()); - _dst_port(prot, prot_base, remote_side.src_port()); + Internet_checksum_diff icd { }; + ip.src(remote_side.dst_ip(), icd); + ip.dst(remote_side.src_ip(), icd); + ip_icd.add_up_diff(icd); + if (prot == L3_protocol::TCP || prot == L3_protocol::UDP) { + prot_icd.add_up_diff(icd); + } + _src_port(prot, prot_base, prot_icd, remote_side.dst_port()); + _dst_port(prot, prot_base, prot_icd, remote_side.src_port()); _pass_prot_to_domain( remote_domain, eth, size_guard, ip, ip_icd, prot, - prot_base, prot_size); + prot_base, prot_icd); _link_packet(prot, prot_base, link, client); done = true; @@ -1032,7 +1039,7 @@ void Interface::_handle_icmp_query(Ethernet_frame ð, Domain &remote_domain = rule.domain(); _adapt_eth(eth, local_id.dst_ip, pkt, remote_domain); _nat_link_and_pass(eth, size_guard, ip, ip_icd, prot, prot_base, - prot_size, local_id, local_domain, + prot_icd, local_id, local_domain, remote_domain); done = true; @@ -1054,7 +1061,7 @@ void Interface::_handle_icmp_error(Ethernet_frame ð, Packet_descriptor const &pkt, Domain &local_domain, Icmp_packet &icmp, - size_t icmp_sz) + Internet_checksum_diff &icmp_icd) { Ipv4_packet &embed_ip { icmp.data(size_guard) }; Internet_checksum_diff embed_ip_icd { }; @@ -1092,14 +1099,18 @@ void Interface::_handle_icmp_error(Ethernet_frame ð, ip.dst(remote_side.src_ip(), ip_icd); /* adapt source and destination of embedded IP and transport packet */ - embed_ip.src(remote_side.src_ip(), embed_ip_icd); - embed_ip.dst(remote_side.dst_ip(), embed_ip_icd); - _src_port(embed_prot, embed_prot_base, remote_side.src_port()); - _dst_port(embed_prot, embed_prot_base, remote_side.dst_port()); + Internet_checksum_diff icd { }; + embed_ip.src(remote_side.src_ip(), icd); + embed_ip.dst(remote_side.dst_ip(), icd); + embed_ip_icd.add_up_diff(icd); + + _src_port(embed_prot, embed_prot_base, icd, remote_side.src_port()); + _dst_port(embed_prot, embed_prot_base, icd, remote_side.dst_port()); /* update checksum of both IP headers and the ICMP header */ - embed_ip.update_checksum(embed_ip_icd); - icmp.update_checksum(icmp_sz - sizeof(Icmp_packet)); + embed_ip.update_checksum(embed_ip_icd, icd); + icmp_icd.add_up_diff(icd); + icmp.update_checksum(icmp_icd); ip.update_checksum(ip_icd); /* send adapted packet to all interfaces of remote domain */ @@ -1126,7 +1137,7 @@ void Interface::_handle_icmp(Ethernet_frame ð, Packet_descriptor const &pkt, L3_protocol prot, void *prot_base, - size_t prot_size, + Internet_checksum_diff &prot_icd, Domain &local_domain, Ipv4_address_prefix const &local_intf) { @@ -1143,14 +1154,14 @@ void Interface::_handle_icmp(Ethernet_frame ð, if(_config().verbose()) { log("[", local_domain, "] act as ICMP Echo server"); } - _send_icmp_echo_reply(eth, ip, icmp, prot_size, size_guard); + _send_icmp_echo_reply(eth, ip, icmp, prot_icd, size_guard); return; } /* try to act as ICMP router */ switch (icmp.type()) { case Icmp_packet::Type::ECHO_REPLY: - case Icmp_packet::Type::ECHO_REQUEST: _handle_icmp_query(eth, size_guard, ip, ip_icd, pkt, prot, prot_base, prot_size, local_domain); break; - case Icmp_packet::Type::DST_UNREACHABLE: _handle_icmp_error(eth, size_guard, ip, ip_icd, pkt, local_domain, icmp, prot_size); break; + case Icmp_packet::Type::ECHO_REQUEST: _handle_icmp_query(eth, size_guard, ip, ip_icd, pkt, prot, prot_base, prot_icd, local_domain); break; + case Icmp_packet::Type::DST_UNREACHABLE: _handle_icmp_error(eth, size_guard, ip, ip_icd, pkt, local_domain, icmp, prot_icd); break; default: Drop_packet("unhandled type in ICMP"); } } @@ -1190,9 +1201,9 @@ void Interface::_handle_ip(Ethernet_frame ð, /* try to route via transport layer rules */ bool done { false }; try { - L3_protocol const prot = ip.protocol(); - size_t const prot_size = size_guard.unconsumed(); - void *const prot_base = _prot_base(prot, size_guard, ip); + L3_protocol const prot { ip.protocol() }; + void *const prot_base { _prot_base(prot, size_guard, ip) }; + Internet_checksum_diff prot_icd { }; /* try handling DHCP requests before trying any routing */ if (prot == L3_protocol::UDP) { @@ -1235,7 +1246,7 @@ void Interface::_handle_ip(Ethernet_frame ð, } else if (prot == L3_protocol::ICMP) { _handle_icmp(eth, size_guard, ip, ip_icd, pkt, prot, prot_base, - prot_size, local_domain, local_intf); + prot_icd, local_domain, local_intf); return; } @@ -1258,13 +1269,20 @@ void Interface::_handle_ip(Ethernet_frame ð, " link: ", link); } _adapt_eth(eth, remote_side.src_ip(), pkt, remote_domain); - ip.src(remote_side.dst_ip(), ip_icd); - ip.dst(remote_side.src_ip(), ip_icd); - _src_port(prot, prot_base, remote_side.dst_port()); - _dst_port(prot, prot_base, remote_side.src_port()); + + Internet_checksum_diff icd { }; + ip.src(remote_side.dst_ip(), icd); + ip.dst(remote_side.src_ip(), icd); + ip_icd.add_up_diff(icd); + if (prot == L3_protocol::TCP || prot == L3_protocol::UDP) { + prot_icd.add_up_diff(icd); + } + _src_port(prot, prot_base, prot_icd, remote_side.dst_port()); + _dst_port(prot, prot_base, prot_icd, remote_side.src_port()); + _pass_prot_to_domain( remote_domain, eth, size_guard, ip, ip_icd, prot, - prot_base, prot_size); + prot_base, prot_icd); _link_packet(prot, prot_base, link, client); done = true; @@ -1288,13 +1306,19 @@ void Interface::_handle_ip(Ethernet_frame ð, } Domain &remote_domain = rule.domain(); _adapt_eth(eth, rule.to_ip(), pkt, remote_domain); - ip.dst(rule.to_ip(), ip_icd); + + Internet_checksum_diff icd { }; + ip.dst(rule.to_ip(), icd); + ip_icd.add_up_diff(icd); + if (prot == L3_protocol::TCP || prot == L3_protocol::UDP) { + prot_icd.add_up_diff(icd); + } if (!(rule.to_port() == Port(0))) { - _dst_port(prot, prot_base, rule.to_port()); + _dst_port(prot, prot_base, prot_icd, rule.to_port()); } _nat_link_and_pass( eth, size_guard, ip, ip_icd, prot, prot_base, - prot_size, local_id, local_domain, remote_domain); + prot_icd, local_id, local_domain, remote_domain); done = true; }, @@ -1319,7 +1343,7 @@ void Interface::_handle_ip(Ethernet_frame ð, Domain &remote_domain = permit_rule.domain(); _adapt_eth(eth, local_id.dst_ip, pkt, remote_domain); _nat_link_and_pass( - eth, size_guard, ip, ip_icd, prot, prot_base, prot_size, + eth, size_guard, ip, ip_icd, prot, prot_base, prot_icd, local_id, local_domain, remote_domain); done = true; diff --git a/repos/os/src/server/nic_router/interface.h b/repos/os/src/server/nic_router/interface.h index b7e798c4a9..117e1e2a73 100644 --- a/repos/os/src/server/nic_router/interface.h +++ b/repos/os/src/server/nic_router/interface.h @@ -189,11 +189,11 @@ class Net::Interface : private Interface_list::Element Genode::uint32_t xid, Ipv4_address_prefix const &local_intf); - void _send_icmp_echo_reply(Ethernet_frame ð, - Ipv4_packet &ip, - Icmp_packet &icmp, - Genode::size_t icmp_sz, - Size_guard &size_guard); + void _send_icmp_echo_reply(Ethernet_frame ð, + Ipv4_packet &ip, + Icmp_packet &icmp, + Internet_checksum_diff &icmp_icd, + Size_guard &size_guard); Forward_rule_tree &_forward_rules(Domain &local_domain, L3_protocol const prot) const; @@ -234,7 +234,7 @@ class Net::Interface : private Interface_list::Element Packet_descriptor const &pkt, L3_protocol prot, void *prot_base, - Genode::size_t prot_size, + Internet_checksum_diff &prot_icd, Domain &local_domain); void _handle_icmp_error(Ethernet_frame ð, @@ -244,7 +244,7 @@ class Net::Interface : private Interface_list::Element Packet_descriptor const &pkt, Domain &local_domain, Icmp_packet &icmp, - Genode::size_t icmp_sz); + Internet_checksum_diff &icmp_icd); void _handle_icmp(Ethernet_frame ð, Size_guard &size_guard, @@ -253,7 +253,7 @@ class Net::Interface : private Interface_list::Element Packet_descriptor const &pkt, L3_protocol prot, void *prot_base, - Genode::size_t prot_size, + Internet_checksum_diff &prot_icd, Domain &local_domain, Ipv4_address_prefix const &local_intf); @@ -268,7 +268,7 @@ class Net::Interface : private Interface_list::Element Internet_checksum_diff &ip_icd, L3_protocol const prot, void *const prot_base, - Genode::size_t const prot_size, + Internet_checksum_diff &prot_icd, Link_side_id const &local_id, Domain &local_domain, Domain &remote_domain); @@ -287,7 +287,7 @@ class Net::Interface : private Interface_list::Element Internet_checksum_diff const &ip_icd, L3_protocol const prot, void *const prot_base, - Genode::size_t const prot_size); + Internet_checksum_diff const &prot_icd); void _handle_pkt();