From 888b098dca4ee8d0d1e6501c9386bfab2a393457 Mon Sep 17 00:00:00 2001 From: Dan Robertson Date: Thu, 7 Dec 2017 03:52:40 +0000 Subject: [PATCH] Process the Icmpv4Repr in IcmpSocket::process - Use the Icmpv4Repr in IcmpSocket::process instead of the raw payload. - Update the IcmpSocket tests. --- src/iface/ethernet.rs | 2 +- src/socket/icmp.rs | 27 ++++++++++++++++++--------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/iface/ethernet.rs b/src/iface/ethernet.rs index 80d3827..f05b989 100644 --- a/src/iface/ethernet.rs +++ b/src/iface/ethernet.rs @@ -460,7 +460,7 @@ impl<'b, 'c> InterfaceInner<'b, 'c> { 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) { + match icmp_socket.process(&ip_repr, &icmp_repr, &checksum_caps) { // The packet is valid and handled by socket. Ok(()) => handled_by_icmp_socket = true, // The socket buffer is full. diff --git a/src/socket/icmp.rs b/src/socket/icmp.rs index a17e953..d9acf40 100644 --- a/src/socket/icmp.rs +++ b/src/socket/icmp.rs @@ -313,12 +313,14 @@ impl<'a, 'b> IcmpSocket<'a, 'b> { } } - pub(crate) fn process(&mut self, ip_repr: &IpRepr, ip_payload: &[u8]) -> Result<()> { - let packet_buf = self.rx_buffer.enqueue_one_with(|buf| buf.resize(ip_payload.len()))?; - packet_buf.as_mut().copy_from_slice(ip_payload); + pub(crate) fn process(&mut self, ip_repr: &IpRepr, icmp_repr: &Icmpv4Repr, + cksum: &ChecksumCapabilities) -> Result<()> { + let packet_buf = self.rx_buffer.enqueue_one_with(|buf| buf.resize(icmp_repr.buffer_len()))?; packet_buf.endpoint = ip_repr.src_addr(); net_trace!("{}:{}: receiving {} octets", self.meta.handle, packet_buf.endpoint, packet_buf.size); + let mut packet = Icmpv4Packet::new(packet_buf.as_mut()); + icmp_repr.emit(&mut packet, cksum); Ok(()) } @@ -367,7 +369,7 @@ mod test { fn buffer(packets: usize) -> SocketBuffer<'static, 'static> { let mut storage = vec![]; for _ in 0..packets { - storage.push(PacketBuffer::new(vec![0; 24])) + storage.push(PacketBuffer::new(vec![0; 46])) } SocketBuffer::new(storage) } @@ -432,7 +434,7 @@ mod test { Err(Error::Exhausted)); // This buffer is too long - assert_eq!(socket.send_slice(&[0xff; 25], REMOTE_IP), Err(Error::Truncated)); + assert_eq!(socket.send_slice(&[0xff; 47], REMOTE_IP), Err(Error::Truncated)); assert!(socket.can_send()); let mut bytes = [0xff; 24]; @@ -494,19 +496,20 @@ mod test { let caps = DeviceCapabilities::default(); - let mut bytes = [0xff; 20]; + let mut bytes = [0xff; 24]; let mut packet = Icmpv4Packet::new(&mut bytes); ECHO_REPR.emit(&mut packet, &caps.checksum); let data = &packet.into_inner()[..]; assert!(socket.accepts(&REMOTE_IP_REPR, &ECHO_REPR, &caps.checksum)); - assert_eq!(socket.process(&REMOTE_IP_REPR, &data[..]), + assert_eq!(socket.process(&REMOTE_IP_REPR, &ECHO_REPR, &caps.checksum), Ok(())); assert!(socket.can_recv()); assert!(socket.accepts(&REMOTE_IP_REPR, &ECHO_REPR, &caps.checksum)); - assert_eq!(socket.process(&REMOTE_IP_REPR, &data[..]), + assert_eq!(socket.process(&REMOTE_IP_REPR, &ECHO_REPR, &caps.checksum), Err(Error::Exhausted)); + assert_eq!(socket.recv(), Ok((&data[..], REMOTE_IP))); assert!(!socket.can_recv()); } @@ -568,8 +571,14 @@ mod test { // Ensure we can accept ICMP error response to the bound // UDP port assert!(socket.accepts(&ip_repr, &icmp_repr, &caps.checksum)); - assert_eq!(socket.process(&ip_repr, &data[..]), + assert_eq!(socket.process(&ip_repr, &icmp_repr, &caps.checksum), Ok(())); assert!(socket.can_recv()); + + let mut bytes = [0x00; 46]; + let mut packet = Icmpv4Packet::new(&mut bytes[..]); + icmp_repr.emit(&mut packet, &caps.checksum); + assert_eq!(socket.recv(), Ok((&packet.into_inner()[..], REMOTE_IP))); + assert!(!socket.can_recv()); } }