surge_ping/
lib.rs

1mod client;
2mod config;
3mod error;
4mod icmp;
5mod ping;
6
7use std::{net::IpAddr, time::Duration};
8
9pub use client::{AsyncSocket, Client};
10pub use config::{Config, ConfigBuilder};
11pub use error::SurgeError;
12pub use icmp::{
13    icmpv4::Icmpv4Packet, icmpv6::Icmpv6Packet, IcmpPacket, PingIdentifier, PingSequence,
14};
15pub use ping::Pinger;
16use rand::random;
17
18#[derive(Debug, Clone, Copy)]
19pub enum ICMP {
20    V4,
21    V6,
22}
23
24impl Default for ICMP {
25    fn default() -> Self {
26        ICMP::V4
27    }
28}
29
30/// Shortcut method to ping address.
31/// **NOTE**: This function creates a new internal `Client` on each call,
32/// and so should not be used if making many target. Create a
33/// [`Client`](./struct.Client.html) instead.
34///
35/// # Examples
36///
37/// ```rust ignore
38/// match surge_ping::ping("127.0.0.1".parse()?, &[1,2,3,4,5,6,7,8]).await {
39///     Ok((_packet, duration)) => println!("duration: {:.2?}", duration),
40///     Err(e) => println!("{:?}", e),
41/// };
42/// ```
43///
44/// # Errors
45///
46/// This function fails if:
47///
48/// - socket create failed
49///
50pub async fn ping(host: IpAddr, payload: &[u8]) -> Result<(IcmpPacket, Duration), SurgeError> {
51    let config = match host {
52        IpAddr::V4(_) => Config::default(),
53        IpAddr::V6(_) => Config::builder().kind(ICMP::V6).build(),
54    };
55    let client = Client::new(&config)?;
56    let mut pinger = client.pinger(host, PingIdentifier(random())).await;
57    pinger.ping(PingSequence(0), payload).await
58}