Skip to content

Commit df32e8c

Browse files
committed
Suppress ICMP error replies for packets that are accepted by raw sockets.
1 parent acbe139 commit df32e8c

File tree

1 file changed

+70
-18
lines changed

1 file changed

+70
-18
lines changed

src/iface/ethernet.rs

Lines changed: 70 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -876,20 +876,21 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> {
876876
let ip_payload = ipv6_packet.payload();
877877

878878
#[cfg(feature = "socket-raw")]
879-
let handled_by_raw_socket = self.raw_socket_filter(sockets, &ipv6_repr.into(), ip_payload);
880-
#[cfg(not(feature = "socket-raw"))]
881-
let handled_by_raw_socket = false;
879+
{
880+
if self.raw_socket_filter(sockets, &ipv6_repr.into(), ip_payload) {
881+
return Ok(Packet::None);
882+
}
883+
}
882884

883-
self.process_nxt_hdr(sockets, timestamp, ipv6_repr, ipv6_repr.next_header,
884-
handled_by_raw_socket, ip_payload)
885+
self.process_nxt_hdr(sockets, timestamp, ipv6_repr, ipv6_repr.next_header, ip_payload)
885886
}
886887

887888
/// Given the next header value forward the payload onto the correct process
888889
/// function.
889890
#[cfg(feature = "proto-ipv6")]
890891
fn process_nxt_hdr<'frame>
891892
(&mut self, sockets: &mut SocketSet, timestamp: Instant, ipv6_repr: Ipv6Repr,
892-
nxt_hdr: IpProtocol, handled_by_raw_socket: bool, ip_payload: &'frame [u8])
893+
nxt_hdr: IpProtocol, ip_payload: &'frame [u8])
893894
-> Result<Packet<'frame>>
894895
{
895896
match nxt_hdr {
@@ -905,11 +906,7 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> {
905906
self.process_tcp(sockets, timestamp, ipv6_repr.into(), ip_payload),
906907

907908
IpProtocol::HopByHop =>
908-
self.process_hopbyhop(sockets, timestamp, ipv6_repr, handled_by_raw_socket, ip_payload),
909-
910-
#[cfg(feature = "socket-raw")]
911-
_ if handled_by_raw_socket =>
912-
Ok(Packet::None),
909+
self.process_hopbyhop(sockets, timestamp, ipv6_repr, ip_payload),
913910

914911
_ => {
915912
// Send back as much of the original payload as we can.
@@ -973,6 +970,10 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> {
973970
}
974971

975972
match ipv4_repr.protocol {
973+
#[cfg(feature = "socket-raw")]
974+
_ if handled_by_raw_socket =>
975+
Ok(Packet::None),
976+
976977
IpProtocol::Icmp =>
977978
self.process_icmpv4(sockets, ip_repr, ip_payload),
978979

@@ -988,10 +989,6 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> {
988989
IpProtocol::Tcp =>
989990
self.process_tcp(sockets, timestamp, ip_repr, ip_payload),
990991

991-
#[cfg(feature = "socket-raw")]
992-
_ if handled_by_raw_socket =>
993-
Ok(Packet::None),
994-
995992
_ => {
996993
// Send back as much of the original payload as we can.
997994
let payload_len = icmp_reply_payload_len(ip_payload.len(), IPV4_MIN_MTU,
@@ -1173,8 +1170,7 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> {
11731170

11741171
#[cfg(feature = "proto-ipv6")]
11751172
fn process_hopbyhop<'frame>(&mut self, sockets: &mut SocketSet, timestamp: Instant,
1176-
ipv6_repr: Ipv6Repr, handled_by_raw_socket: bool,
1177-
ip_payload: &'frame [u8]) -> Result<Packet<'frame>>
1173+
ipv6_repr: Ipv6Repr, ip_payload: &'frame [u8]) -> Result<Packet<'frame>>
11781174
{
11791175
let hbh_pkt = Ipv6HopByHopHeader::new_checked(ip_payload)?;
11801176
let hbh_repr = Ipv6HopByHopRepr::parse(&hbh_pkt)?;
@@ -1199,7 +1195,7 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> {
11991195
}
12001196
}
12011197
self.process_nxt_hdr(sockets, timestamp, ipv6_repr, hbh_repr.next_header,
1202-
handled_by_raw_socket, &ip_payload[hbh_repr.buffer_len()..])
1198+
&ip_payload[hbh_repr.buffer_len()..])
12031199
}
12041200

12051201
#[cfg(feature = "proto-ipv4")]
@@ -2593,4 +2589,60 @@ mod test {
25932589
assert_eq!(leaves[i].1, IgmpRepr::LeaveGroup { group_addr });
25942590
}
25952591
}
2592+
2593+
#[test]
2594+
#[cfg(all(feature = "proto-ipv4", feature = "socket-raw"))]
2595+
fn test_raw_socket_no_reply() {
2596+
use socket::{RawSocket, RawSocketBuffer, RawPacketMetadata};
2597+
use wire::IpVersion;
2598+
2599+
let (mut iface, mut socket_set) = create_loopback();
2600+
2601+
let packets = 1;
2602+
let rx_buffer = RawSocketBuffer::new(vec![RawPacketMetadata::EMPTY; packets], vec![0; 48 * 1]);
2603+
let tx_buffer = RawSocketBuffer::new(vec![RawPacketMetadata::EMPTY; packets], vec![0; 48 * packets]);
2604+
let raw_socket = RawSocket::new(IpVersion::Ipv4, IpProtocol::Udp, rx_buffer, tx_buffer);
2605+
socket_set.add(raw_socket);
2606+
2607+
let src_addr = Ipv4Address([127, 0, 0, 2]);
2608+
let dst_addr = Ipv4Address([127, 0, 0, 1]);
2609+
2610+
let udp_repr = UdpRepr {
2611+
src_port: 67,
2612+
dst_port: 68,
2613+
payload: &[0x2a; 10]
2614+
};
2615+
let mut bytes = vec![0xff; udp_repr.buffer_len()];
2616+
let mut packet = UdpPacket::new_unchecked(&mut bytes[..]);
2617+
udp_repr.emit(&mut packet, &src_addr.into(), &dst_addr.into(), &ChecksumCapabilities::default());
2618+
let ipv4_repr = Ipv4Repr {
2619+
src_addr: src_addr,
2620+
dst_addr: dst_addr,
2621+
protocol: IpProtocol::Udp,
2622+
hop_limit: 64,
2623+
payload_len: udp_repr.buffer_len()
2624+
};
2625+
2626+
// Emit to ethernet frame
2627+
let mut eth_bytes = vec![0u8;
2628+
EthernetFrame::<&[u8]>::header_len() +
2629+
ipv4_repr.buffer_len() + udp_repr.buffer_len()
2630+
];
2631+
let frame = {
2632+
let mut frame = EthernetFrame::new_unchecked(&mut eth_bytes);
2633+
ipv4_repr.emit(
2634+
&mut Ipv4Packet::new_unchecked(frame.payload_mut()),
2635+
&ChecksumCapabilities::default());
2636+
udp_repr.emit(
2637+
&mut UdpPacket::new_unchecked(
2638+
&mut frame.payload_mut()[ipv4_repr.buffer_len()..]),
2639+
&src_addr.into(),
2640+
&dst_addr.into(),
2641+
&ChecksumCapabilities::default());
2642+
EthernetFrame::new_unchecked(&*frame.into_inner())
2643+
};
2644+
2645+
assert_eq!(iface.inner.process_ipv4(&mut socket_set, Instant::from_millis(0), &frame),
2646+
Ok(Packet::None));
2647+
}
25962648
}

0 commit comments

Comments
 (0)