diff --git a/Cargo.toml b/Cargo.toml index 39406fa..08d5906 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,13 +9,13 @@ description = " ICMP ping library for quickly sending and measuring batches of I readme = "README.md" [dependencies] -pnet = "0.28" -pnet_macros_support = "0.28" +pnet = "0.34" +pnet_macros_support = "0.34" log = "0.4" rand = "0.8" [dev-dependencies] -pretty_env_logger = "0.4" +pretty_env_logger = "0.5" [[example]] name = "ping" diff --git a/src/lib.rs b/src/lib.rs index c3a16a8..889ec33 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,7 +7,8 @@ extern crate rand; mod ping; use ping::{send_pings, Ping, ReceivedPing}; -use pnet::packet::icmp::echo_reply::EchoReplyPacket; +use pnet::packet::icmp::echo_reply::EchoReplyPacket as IcmpEchoReplyPacket; +use pnet::packet::icmpv6::echo_reply::EchoReplyPacket as Icmpv6EchoReplyPacket; use pnet::packet::ip::IpNextHeaderProtocols; use pnet::packet::Packet; use pnet::packet::{icmp, icmpv6}; @@ -227,9 +228,9 @@ impl Pinger { let mut iter = icmp_packet_iter(&mut receiver); loop { match iter.next() { - Ok((packet, addr)) => match EchoReplyPacket::new(packet.packet()) { + Ok((packet, addr)) => match IcmpEchoReplyPacket::new(packet.packet()) { Some(echo_reply) => { - if packet.get_icmp_type() == icmp::IcmpType::new(0) { + if packet.get_icmp_type() == icmp::IcmpTypes::EchoReply { let start_time = timer.read().unwrap(); match thread_tx.send(ReceivedPing { addr, @@ -274,32 +275,35 @@ impl Pinger { let mut iter = icmpv6_packet_iter(&mut receiver); loop { match iter.next() { - Ok((packet, addr)) => { - if packet.get_icmpv6_type() == icmpv6::Icmpv6Type::new(129) { - let start_time = timerv6.read().unwrap(); - match thread_txv6.send(ReceivedPing { - addr, - identifier: 0, - sequence_number: 0, - rtt: Instant::now().duration_since(*start_time), - }) { - Ok(_) => {} - Err(e) => { - if !*stopv6.lock().unwrap() { - error!("Error sending ping result on channel: {}", e) - } else { - return; + Ok((packet, addr)) => match Icmpv6EchoReplyPacket::new(packet.packet()) { + Some(echo_reply) => { + if packet.get_icmpv6_type() == icmpv6::Icmpv6Types::EchoReply { + let start_time = timerv6.read().unwrap(); + match thread_txv6.send(ReceivedPing { + addr, + identifier: echo_reply.get_identifier(), + sequence_number: echo_reply.get_sequence_number(), + rtt: Instant::now().duration_since(*start_time), + }) { + Ok(_) => {} + Err(e) => { + if !*stopv6.lock().unwrap() { + error!("Error sending ping result on channel: {}", e) + } else { + return; + } } } + } else { + debug!( + "ICMPv6 type other than reply (129) received from {:?}: {:?}", + addr, + packet.get_icmpv6_type() + ); } - } else { - debug!( - "ICMP type other than reply (129) received from {:?}: {:?}", - addr, - packet.get_icmpv6_type() - ); } - } + None => {} + }, Err(e) => { error!("An error occurred while reading: {}", e); } diff --git a/src/ping.rs b/src/ping.rs index 2ba03f8..d132b14 100644 --- a/src/ping.rs +++ b/src/ping.rs @@ -1,10 +1,7 @@ -use pnet::packet::icmp::echo_request; -use pnet::packet::icmp::IcmpTypes; -use pnet::packet::icmpv6::{Icmpv6Types, MutableIcmpv6Packet}; use pnet::packet::Packet; +use pnet::packet::{icmp, icmpv6}; use pnet::transport::TransportSender; use pnet::util; -use pnet_macros_support::types::*; use rand::random; use std::collections::BTreeMap; use std::net::IpAddr; @@ -29,13 +26,9 @@ pub struct ReceivedPing { impl Ping { pub fn new(addr: IpAddr) -> Ping { - let mut identifier = 0; - if addr.is_ipv4() { - identifier = random::(); - } Ping { addr, - identifier, + identifier: random::(), sequence_number: 0, seen: false, } @@ -67,13 +60,12 @@ fn send_echo( // Allocate enough space for a new packet let mut vec: Vec = vec![0; size]; - // Use echo_request so we can set the identifier and sequence number - let mut echo_packet = echo_request::MutableEchoRequestPacket::new(&mut vec[..]).unwrap(); + let mut echo_packet = icmp::echo_request::MutableEchoRequestPacket::new(&mut vec[..]).unwrap(); echo_packet.set_sequence_number(ping.increment_sequence_number()); echo_packet.set_identifier(ping.get_identifier()); - echo_packet.set_icmp_type(IcmpTypes::EchoRequest); + echo_packet.set_icmp_type(icmp::IcmpTypes::EchoRequest); - let csum = icmp_checksum(&echo_packet); + let csum = util::checksum(echo_packet.packet(), 1); echo_packet.set_checksum(csum); tx.send_to(echo_packet, ping.get_addr()) @@ -81,19 +73,22 @@ fn send_echo( fn send_echov6( tx: &mut TransportSender, - addr: IpAddr, + ping: &mut Ping, size: usize, ) -> Result { // Allocate enough space for a new packet let mut vec: Vec = vec![0; size]; - let mut echo_packet = MutableIcmpv6Packet::new(&mut vec[..]).unwrap(); - echo_packet.set_icmpv6_type(Icmpv6Types::EchoRequest); + let mut echo_packet = + icmpv6::echo_request::MutableEchoRequestPacket::new(&mut vec[..]).unwrap(); + echo_packet.set_sequence_number(ping.increment_sequence_number()); + echo_packet.set_identifier(ping.get_identifier()); + echo_packet.set_icmpv6_type(icmpv6::Icmpv6Types::EchoRequest); - let csum = icmpv6_checksum(&echo_packet); + let csum = util::checksum(echo_packet.packet(), 1); echo_packet.set_checksum(csum); - tx.send_to(echo_packet, addr) + tx.send_to(echo_packet, ping.get_addr()) } pub fn send_pings( @@ -112,7 +107,7 @@ pub fn send_pings( match if addr.is_ipv4() { send_echo(&mut tx.lock().unwrap(), ping, size) } else if addr.is_ipv6() { - send_echov6(&mut txv6.lock().unwrap(), *addr, size) + send_echov6(&mut txv6.lock().unwrap(), ping, size) } else { Ok(0) } { @@ -194,14 +189,6 @@ pub fn send_pings( } } -fn icmp_checksum(packet: &echo_request::MutableEchoRequestPacket) -> u16be { - util::checksum(packet.packet(), 1) -} - -fn icmpv6_checksum(packet: &MutableIcmpv6Packet) -> u16be { - util::checksum(packet.packet(), 1) -} - #[cfg(test)] mod tests { use super::*;