Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: smoltcp-rs/smoltcp
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 86ac32539f92
Choose a base ref
...
head repository: smoltcp-rs/smoltcp
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 907f3659a43a
Choose a head ref
  • 2 commits
  • 1 file changed
  • 1 contributor

Commits on Nov 13, 2017

  1. Copy the full SHA
    752ae03 View commit details
  2. Copy the full SHA
    907f365 View commit details
Showing with 40 additions and 18 deletions.
  1. +40 −18 src/iface/ethernet.rs
58 changes: 40 additions & 18 deletions src/iface/ethernet.rs
Original file line number Diff line number Diff line change
@@ -227,11 +227,13 @@ impl<'b, 'c, DeviceT> Interface<'b, 'c, DeviceT>
Socket::Icmp(ref mut socket) =>
socket.dispatch(&caps, |response| {
let tx_token = device.transmit().ok_or(Error::Exhausted)?;
match response {
(IpRepr::Ipv4(repr), icmp_repr) =>
inner.dispatch(tx_token, timestamp, Packet::Icmpv4((repr, icmp_repr))),
device_result = match response {
(IpRepr::Ipv4(ipv4_repr), icmpv4_repr) =>
inner.dispatch(tx_token, timestamp,
Packet::Icmpv4((ipv4_repr, icmpv4_repr))),
_ => Err(Error::Unaddressable),
}
};
device_result
}),
#[cfg(feature = "socket-udp")]
Socket::Udp(ref mut socket) =>
@@ -431,15 +433,20 @@ impl<'b, 'c> InterfaceInner<'b, 'c> {
let checksum_caps = self.device_capabilities.checksum.clone();
let icmp_repr = Icmpv4Repr::parse(&icmp_packet, &checksum_caps)?;

#[cfg(feature = "socket-icmp")]
let mut handled_by_icmp_socket = false;

#[cfg(feature = "socket-icmp")]
for mut icmp_socket in _sockets.iter_mut().filter_map(IcmpSocket::downcast) {
if !icmp_socket.accepts(&ip_repr, &icmp_repr, &checksum_caps) { continue }

match icmp_socket.process(&ip_repr, ip_payload) {
// The packet is valid and handled by socket.
Ok(()) => return Ok(Packet::None),
// The packet is malformed, or the socket buffer is full.
Err(e) => return Err(e)
Ok(()) => handled_by_icmp_socket = true,
// The socket buffer is full.
Err(Error::Exhausted) => (),
// ICMP sockets don't validate the packets in any way.
Err(_) => unreachable!(),
}
}

@@ -460,6 +467,11 @@ impl<'b, 'c> InterfaceInner<'b, 'c> {
// Ignore any echo replies.
Icmpv4Repr::EchoReply { .. } => Ok(Packet::None),

// Don't report an error if a packet with unknown type
// has been handled by an ICMP socket
#[cfg(feature = "socket-icmp")]
_ if handled_by_icmp_socket => Ok(Packet::None),

// FIXME: do something correct here?
_ => Err(Error::Unrecognized),
}
@@ -1040,6 +1052,9 @@ mod test {
let socket_handle = socket_set.add(icmpv4_socket);

let ident = 0x1234;
let seq_no = 0x5432;
let echo_data = &[0xff; 16];

{
let mut socket = socket_set.get::<IcmpSocket>(socket_handle);
// Bind to the ID 0x1234
@@ -1049,34 +1064,41 @@ mod test {
// Ensure the ident we bound to and the ident of the packet are the same.
let mut bytes = [0xff; 24];
let mut packet = Icmpv4Packet::new(&mut bytes);
let echo_repr = Icmpv4Repr::EchoReply {
ident: ident,
seq_no: 0x5432,
data: &[0xff; 16],
};
let echo_repr = Icmpv4Repr::EchoRequest{ ident, seq_no, data: echo_data };
echo_repr.emit(&mut packet, &ChecksumCapabilities::default());
let data = &packet.into_inner()[..];
let icmp_data = &packet.into_inner()[..];

let ip_repr = IpRepr::Ipv4(Ipv4Repr {
let ipv4_repr = Ipv4Repr {
src_addr: Ipv4Address::new(0x7f, 0x00, 0x00, 0x02),
dst_addr: Ipv4Address::new(0x7f, 0x00, 0x00, 0x01),
protocol: IpProtocol::Icmp,
payload_len: 24,
ttl: 64
});
};
let ip_repr = IpRepr::Ipv4(ipv4_repr);

// Open a socket and ensure the packet is handled due to the listening
// socket.
{
assert!(!socket_set.get::<IcmpSocket>(socket_handle).can_recv());
}
assert_eq!(iface.inner.process_icmpv4(&mut socket_set, ip_repr, data),
Ok(Packet::None));

// Confirm we still get EchoReply from `smoltcp` even with the ICMP socket listening
let echo_reply = Icmpv4Repr::EchoReply{ ident, seq_no, data: echo_data };
let ipv4_reply = Ipv4Repr {
src_addr: ipv4_repr.dst_addr,
dst_addr: ipv4_repr.src_addr,
..ipv4_repr
};
assert_eq!(iface.inner.process_icmpv4(&mut socket_set, ip_repr, icmp_data),
Ok(Packet::Icmpv4((ipv4_reply, echo_reply))));

{
let mut socket = socket_set.get::<IcmpSocket>(socket_handle);
assert!(socket.can_recv());
assert_eq!(socket.recv(),
Ok((&data[..], IpAddress::Ipv4(Ipv4Address::new(0x7f, 0x00, 0x00, 0x02)))));
Ok((&icmp_data[..],
IpAddress::Ipv4(Ipv4Address::new(0x7f, 0x00, 0x00, 0x02)))));
}
}
}