From f1ec7113b8a5e81d89cdc94e1988671b5d6b4936 Mon Sep 17 00:00:00 2001 From: shellrow Date: Sat, 19 Jul 2025 22:09:27 +0900 Subject: [PATCH 1/3] Fix IPv4 total_length check --- nex-packet/src/ipv4.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/nex-packet/src/ipv4.rs b/nex-packet/src/ipv4.rs index e1f21b6..a55fad4 100644 --- a/nex-packet/src/ipv4.rs +++ b/nex-packet/src/ipv4.rs @@ -213,8 +213,14 @@ impl Packet for Ipv4Packet { let version = (bytes[0] & 0xF0) >> 4; let header_length = (bytes[0] & 0x0F) as usize; let total_length = u16::from_be_bytes([bytes[2], bytes[3]]) as usize; + let total_length = if total_length > bytes.len() { + // fallback + bytes.len() + } else { + total_length + }; - if bytes.len() < total_length || header_length < 5 { + if header_length < 5 { return None; } From 7b295d19be8019491133ade14a00859d25eade00 Mon Sep 17 00:00:00 2001 From: shellrow Date: Sat, 19 Jul 2025 22:09:33 +0900 Subject: [PATCH 2/3] Update async_icmp_socket.rs --- examples/async_icmp_socket.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/examples/async_icmp_socket.rs b/examples/async_icmp_socket.rs index 27cd226..bb01cb1 100644 --- a/examples/async_icmp_socket.rs +++ b/examples/async_icmp_socket.rs @@ -6,8 +6,11 @@ use bytes::Bytes; use nex::net::interface::{get_interfaces, Interface}; use nex_packet::builder::icmp::IcmpPacketBuilder; -use nex_packet::icmp::{self, IcmpType}; +use nex_packet::icmp::echo_reply::EchoReplyPacket; +use nex_packet::icmp::{self, IcmpPacket, IcmpType}; use nex_socket::icmp::{AsyncIcmpSocket, IcmpConfig, IcmpKind}; +use nex_packet::ipv4::Ipv4Packet; +use nex_packet::packet::Packet; use rand::{thread_rng, Rng}; use std::collections::HashMap; use std::env; @@ -51,6 +54,21 @@ async fn main() -> std::io::Result<()> { loop { if let Ok((n, from)) = socket_clone.recv_from(&mut buf).await { println!("Received {} bytes from {}", n, from.ip()); + if let Some(ipv4_packet) = Ipv4Packet::from_buf(&buf[..n]) { + if ipv4_packet.header.next_level_protocol == nex_packet::ip::IpNextProtocol::Icmp { + if let Some(icmp_packet) = IcmpPacket::from_bytes(ipv4_packet.payload()) { + println!("\t{:?} from: {:?} to {:?}, TTL: {}", icmp_packet.header.icmp_type, ipv4_packet.header.source, ipv4_packet.header.destination, ipv4_packet.header.ttl); + match EchoReplyPacket::try_from(icmp_packet) { + Ok(reply) => { + println!("\tID: {}, Seq: {}", reply.identifier, reply.sequence_number); + } + Err(_) => { + println!("\tReceived non-echo-reply ICMP packet"); + } + } + } + } + } } } }); From e5b05731b121b7634812790fb03f03e633d2e47f Mon Sep 17 00:00:00 2001 From: shellrow Date: Sat, 19 Jul 2025 22:49:42 +0900 Subject: [PATCH 3/3] Update icmp_socket.rs --- examples/icmp_socket.rs | 44 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/examples/icmp_socket.rs b/examples/icmp_socket.rs index d1521d3..cdea933 100644 --- a/examples/icmp_socket.rs +++ b/examples/icmp_socket.rs @@ -6,6 +6,10 @@ use bytes::Bytes; use nex::net::interface::{get_interfaces, Interface}; use nex_packet::builder::icmp::IcmpPacketBuilder; use nex_packet::builder::icmpv6::Icmpv6PacketBuilder; +use nex_packet::icmp::IcmpPacket; +use nex_packet::icmpv6::Icmpv6Packet; +use nex_packet::ipv4::Ipv4Packet; +use nex_packet::packet::Packet; use nex_packet::{icmp, icmpv6}; use nex_socket::icmp::{IcmpConfig, IcmpKind, IcmpSocket}; use std::env; @@ -68,7 +72,43 @@ fn main() -> std::io::Result<()> { println!("Sent echo request to {}", target_ip); let mut buf = [0u8; 1500]; - let (_n, from) = socket.recv_from(&mut buf)?; - println!("Received reply from {}", from.ip()); + let (n, from) = socket.recv_from(&mut buf)?; + println!("Received {} bytes from {}", n, from.ip()); + let packet: &[u8] = &buf[..n]; + match kind { + IcmpKind::V4 => { + // Parse IPv4 + ICMP + if let Some(ipv4_packet) = Ipv4Packet::from_buf(packet) { + if ipv4_packet.header.next_level_protocol == nex_packet::ip::IpNextProtocol::Icmp { + if let Some(icmp_packet) = IcmpPacket::from_bytes(ipv4_packet.payload()) { + println!("\t{:?} from: {:?} to {:?}, TTL: {}", icmp_packet.header.icmp_type, ipv4_packet.header.source, ipv4_packet.header.destination, ipv4_packet.header.ttl); + match icmp::echo_reply::EchoReplyPacket::try_from(icmp_packet) { + Ok(reply) => { + println!("\tID: {}, Seq: {}", reply.identifier, reply.sequence_number); + } + Err(_) => { + println!("\tReceived non-echo-reply ICMP packet"); + } + } + } + } + } + }, + IcmpKind::V6 => { + // Parse ICMPv6 + // The IPv6 header is automatically cropped off when recvfrom() is used. + if let Some(icmpv6_packet) = Icmpv6Packet::from_buf(packet) { + println!("\t{:?} from: {:?}", icmpv6_packet.header.icmpv6_type, from.ip()); + match icmpv6::echo_reply::EchoReplyPacket::from_buf(packet) { + Some(reply) => { + println!("\tID: {}, Seq: {}", reply.identifier, reply.sequence_number); + } + None => { + println!("\tReceived non-echo-reply ICMPv6 packet"); + } + } + } + } + } Ok(()) }