diff --git a/src/packet/icmp.rs b/src/packet/icmp.rs index 1f5a7b3..9ccc7bd 100644 --- a/src/packet/icmp.rs +++ b/src/packet/icmp.rs @@ -80,8 +80,7 @@ impl<'a> EchoReply<'a> { let ident = (u16::from(buffer[4]) << 8) + u16::from(buffer[5]); let seq_cnt = (u16::from(buffer[6]) << 8) + u16::from(buffer[7]); - - let payload = &buffer[HEADER_SIZE..]; + let payload = &buffer[HEADER_SIZE..(HEADER_SIZE + 24)]; Ok(EchoReply { ident, diff --git a/src/packet/ipv4.rs b/src/packet/ipv4.rs index 078f76c..2424c10 100644 --- a/src/packet/ipv4.rs +++ b/src/packet/ipv4.rs @@ -29,6 +29,7 @@ impl IpV4Protocol { } pub struct IpV4Packet<'a> { + #[allow(unused)] pub protocol: IpV4Protocol, pub data: &'a [u8], } diff --git a/src/ping.rs b/src/ping.rs index a89d2ad..30dc670 100644 --- a/src/ping.rs +++ b/src/ping.rs @@ -74,6 +74,7 @@ fn ping_with_socktype( socket.set_unicast_hops_v6(ttl.unwrap_or(64))?; } + #[allow(unused)] if let Some(device) = bind_device { #[cfg(any(target_os = "linux", target_os = "android"))] { @@ -95,16 +96,24 @@ fn ping_with_socktype( socket.set_read_timeout(Some(timeout - elapsed_time))?; let mut buffer: [u8; 2048] = [0; 2048]; - socket.read(&mut buffer)?; + let n = socket.read(&mut buffer)?; let reply = if dest.is_ipv4() { - let ipv4_packet = match IpV4Packet::decode(&buffer) { - Ok(packet) => packet, - Err(_) => return Err(Error::DecodeV4Error.into()), - }; - match EchoReply::decode::(ipv4_packet.data) { - Ok(reply) => reply, - Err(_) => continue, + // DGRAM socket on Linux may return pure ICMP packet without IP header. + if n == ECHO_REQUEST_BUFFER_SIZE { + match EchoReply::decode::(&buffer) { + Ok(reply) => reply, + Err(_) => continue, + } + } else { + let ipv4_packet = match IpV4Packet::decode(&buffer) { + Ok(packet) => packet, + Err(_) => return Err(Error::DecodeV4Error.into()), + }; + match EchoReply::decode::(ipv4_packet.data) { + Ok(reply) => reply, + Err(_) => continue, + } } } else { match EchoReply::decode::(&buffer) { @@ -119,7 +128,7 @@ fn ping_with_socktype( Err(_) => return Err(Error::InternalError.into()), }; - if reply.ident == request.ident { + if reply.payload == request.payload { // received correct ident return Ok(PingResult { rtt: elapsed_time,