Browse Source

Unbreak parsing of ICMP unreachable messages.

Fixes #16.
whitequark 7 years ago
parent
commit
818fa7dda4
2 changed files with 12 additions and 11 deletions
  1. 1 4
      src/iface/ethernet.rs
  2. 11 7
      src/wire/icmpv4.rs

+ 1 - 4
src/iface/ethernet.rs

@@ -280,13 +280,10 @@ impl<'a, 'b, 'c, DeviceT: Device + 'a> Interface<'a, 'b, 'c, DeviceT> {
                                 reason = Icmpv4DstUnreachable::ProtoUnreachable
                             }
 
-                            let mut data = [0; 8];
-                            data.copy_from_slice(&ipv4_packet.payload()[0..8]);
-
                             let icmp_reply_repr = Icmpv4Repr::DstUnreachable {
                                 reason: reason,
                                 header: ipv4_repr,
-                                data:   data
+                                data:   &ipv4_packet.payload()[0..8]
                             };
                             let ipv4_reply_repr = Ipv4Repr {
                                 src_addr:    dst_addr,

+ 11 - 7
src/wire/icmpv4.rs

@@ -352,7 +352,7 @@ pub enum Repr<'a> {
     DstUnreachable {
         reason: DstUnreachable,
         header: Ipv4Repr,
-        data:   [u8; 8]
+        data:   &'a [u8]
     },
     #[doc(hidden)]
     __Nonexhaustive
@@ -381,17 +381,21 @@ impl<'a> Repr<'a> {
 
             (Message::DstUnreachable, code) => {
                 let ip_packet = try!(Ipv4Packet::new(packet.data()));
-                let ip_repr = try!(Ipv4Repr::parse(&ip_packet));
 
-                let mut data = [0; 8];
                 let payload = &packet.data()[ip_packet.header_len() as usize..];
-                if payload.len() < data.len() { return Err(Error::Truncated) }
-                data.copy_from_slice(&payload[0..8]);
+                // RFC 792 requires exactly eight bytes to be returned.
+                // We allow more, since there isn't a reason not to, but require at least eight.
+                if payload.len() < 8 { return Err(Error::Truncated) }
 
                 Ok(Repr::DstUnreachable {
                     reason: DstUnreachable::from(code),
-                    header: ip_repr,
-                    data:   data
+                    header: Ipv4Repr {
+                        src_addr: ip_packet.src_addr(),
+                        dst_addr: ip_packet.dst_addr(),
+                        protocol: ip_packet.protocol(),
+                        payload_len: payload.len(),
+                    },
+                    data: payload
                 })
             }
             _ => Err(Error::Unrecognized)