Struct IcmpEchoRequestor

Source
pub struct IcmpEchoRequestor { /* private fields */ }
Expand description

Requestor for sending ICMP Echo Requests (ping) and receiving replies on Unix systems.

This implementation uses ICMP sockets with Tokio for async operations. It requires unprivileged ICMP socket support, which is available on macOS by default and on Linux when the net.ipv4.ping_group_range sysctl parameter is properly configured.

The requestor spawns a background task to handle incoming replies and is safe to clone and use across multiple threads and async tasks.

§Platform Requirements

  • macOS: Works with unprivileged sockets out of the box
  • Linux: Requires net.ipv4.ping_group_range sysctl to allow unprivileged ICMP sockets

§Examples

use ping_async::IcmpEchoRequestor;
use std::net::IpAddr;

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let target = "8.8.8.8".parse::<IpAddr>().unwrap();
    let pinger = IcmpEchoRequestor::new(target, None, None, None)?;
     
    let reply = pinger.send().await?;
    println!("Reply: {:?}", reply);
     
    Ok(())
}

Implementations§

Source§

impl IcmpEchoRequestor

Source

pub fn new( target_addr: IpAddr, source_addr: Option<IpAddr>, ttl: Option<u8>, timeout: Option<Duration>, ) -> Result<Self>

Creates a new ICMP echo requestor for the specified target address.

§Arguments
  • target_addr - The IP address to ping (IPv4 or IPv6)
  • source_addr - Optional source IP address to bind to. Must match the IP version of target_addr
  • ttl - Optional Time-To-Live value. Defaults to PING_DEFAULT_TTL
  • timeout - Optional timeout duration. Defaults to PING_DEFAULT_TIMEOUT
§Errors

Returns an error if:

  • The source address type doesn’t match the target address type (IPv4 vs IPv6)
  • ICMP socket creation fails (typically due to insufficient permissions)
  • Socket configuration fails
§Platform Requirements
  • Linux: Requires net.ipv4.ping_group_range sysctl parameter to allow unprivileged ICMP sockets. Check with: sysctl net.ipv4.ping_group_range
  • macOS: Works with unprivileged sockets by default
§Examples
use ping_async::IcmpEchoRequestor;
use std::net::IpAddr;
use std::time::Duration;

// Basic usage with defaults
let pinger = IcmpEchoRequestor::new(
    "8.8.8.8".parse().unwrap(),
    None,
    None,
    None
)?;

// With custom source address and timeout
let pinger = IcmpEchoRequestor::new(
    "2001:4860:4860::8888".parse().unwrap(),
    Some("::1".parse().unwrap()),
    Some(64),
    Some(Duration::from_millis(500))
)?;
Source

pub async fn send(&self) -> Result<IcmpEchoReply>

Sends an ICMP echo request and waits for a reply.

This method is async and will complete when either:

  • An echo reply is received
  • The configured timeout expires
  • An error occurs

The requestor uses lazy initialization - the background reply router task is only spawned on the first call to send(). The requestor can be used multiple times and is safe to use concurrently from multiple async tasks.

§Returns

Returns an IcmpEchoReply containing:

  • The destination IP address
  • The status of the ping operation
  • The measured round-trip time
§Errors

Returns an error if:

  • The socket send operation fails immediately
  • The background router task has failed (typically due to permission loss)
  • Internal communication channels fail unexpectedly

Note that timeout and unreachable conditions are returned as successful IcmpEchoReply with appropriate status values, not as errors.

§Examples
use ping_async::{IcmpEchoRequestor, IcmpEchoStatus};

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let pinger = IcmpEchoRequestor::new(
        "8.8.8.8".parse().unwrap(),
        None, None, None
    )?;
     
    // Send multiple pings using the same requestor
    for i in 0..3 {
        let reply = pinger.send().await?;
         
        match reply.status() {
            IcmpEchoStatus::Success => {
                println!("Ping {}: {:?}", i, reply.round_trip_time());
            }
            IcmpEchoStatus::TimedOut => {
                println!("Ping {} timed out", i);
            }
            _ => {
                println!("Ping {} failed: {:?}", i, reply.status());
            }
        }
    }
     
    Ok(())
}

Trait Implementations§

Source§

impl Clone for IcmpEchoRequestor

Source§

fn clone(&self) -> IcmpEchoRequestor

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V