diff --git a/src/pinger.rs b/src/pinger.rs index 6b58792..85909aa 100644 --- a/src/pinger.rs +++ b/src/pinger.rs @@ -56,8 +56,9 @@ pub fn run(args: Args, hosts_in: Vec<(String, IpAddr)>) { let fd4 = owned_fd4.as_ref().map(|o| o.as_raw_fd()); let fd6 = owned_fd6.as_ref().map(|o| o.as_raw_fd()); - let pid_id = (std::process::id() & 0xFFFF) as u16; - let my_id = dgram_id4.or(dgram_id6).unwrap_or(pid_id); + let pid_id = (std::process::id() & 0xFFFF) as u16; + let my_id4 = dgram_id4.unwrap_or(pid_id); + let my_id6 = dgram_id6.unwrap_or(pid_id); let interval = Duration::from_millis(args.interval); let period = Duration::from_millis(args.period); @@ -103,7 +104,8 @@ pub fn run(args: Args, hosts_in: Vec<(String, IpAddr)>) { let is_ipv6 = hosts[idx].is_ipv6; let kind = if is_ipv6 { kind6 } else { kind4 }; - let pkt = build_icmp_packet(my_id, seq, args.size, is_ipv6, kind); + let pkt_id = if is_ipv6 { my_id6 } else { my_id4 }; + let pkt = build_icmp_packet(pkt_id, seq, args.size, is_ipv6, kind); let sent = match hosts[idx].addr { IpAddr::V4(ref a) => fd4.map(|fd| send_ping_v4(fd, a, &pkt)).unwrap_or(false), @@ -136,16 +138,14 @@ pub fn run(args: Args, hosts_in: Vec<(String, IpAddr)>) { } } - for (fd_opt, is_v6, kind) in &[(fd4, false, kind4), (fd6, true, kind6)] { + for (fd_opt, is_v6, kind, expected_id) in &[(fd4, false, kind4, my_id4), (fd6, true, kind6, my_id6),] { let fd = match fd_opt { Some(f) => *f, None => continue }; loop { - let received = match recv_ping(fd, &mut recv_buf, *is_v6, *kind) { + let received = match recv_ping(fd, &mut recv_buf, *is_v6, *kind, Some(*expected_id)) { Some(r) => r, None => break, }; - if received.id != my_id { continue; } - if let Some(pending) = seqmap.get(&received.seq) { if Instant::now().duration_since(pending.sent_at) > timeout { seqmap.remove(&received.seq); diff --git a/src/socket.rs b/src/socket.rs index 5ae23ea..b8641e7 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -166,12 +166,11 @@ pub fn send_ping_v6(fd: RawFd, addr: &Ipv6Addr, pkt: &[u8]) -> bool { } pub struct ReceivedPing { - pub id: u16, pub seq: u16, pub raw_len: usize, } -pub fn recv_ping(fd: RawFd, buf: &mut [u8], is_ipv6: bool, kind: SocketKind) -> Option { +pub fn recv_ping(fd: RawFd, buf: &mut [u8], is_ipv6: bool, kind: SocketKind, expected_id: Option) -> Option { let mut src: libc::sockaddr_storage = unsafe { std::mem::zeroed() }; let mut src_len = std::mem::size_of::() as socklen_t; @@ -211,8 +210,11 @@ pub fn recv_ping(fd: RawFd, buf: &mut [u8], is_ipv6: bool, kind: SocketKind) -> let id = u16::from_be_bytes([icmp[4], icmp[5]]); + if let Some(eid) = expected_id { + if id != eid { return None; } + } + Some(ReceivedPing { - id, seq: u16::from_be_bytes([icmp[6], icmp[7]]), raw_len, })