A multi-targets ping tool and library, which supports 10,000 packets/second, accurate latency

Overview

mping-rs

License GitHub Action Crate API

a multi-targets ping tool, which supports 10,000 packets/second, accurate latency.

一个高频ping工具,支持多个目标。 正常的ping一般用来做探测工具,mping还可以用来做压测工具。 Go版本: smallnest/mping

And you can use it as a lib to implement your multi-targets and handle the ping results. See the ping.rs example in the examples folder.

Usage - as a tool

compile

cargo build --release

options usage.

> $$ mping  -h
mping 0.3.0
A multi-targets ping tool, which supports 10,000 packets/second.

USAGE:
    mping [OPTIONS] <ip address>...

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

OPTIONS:
    -c, --count <count>        max packet count
    -d, --delay <delay>        delay in seconds [default: 3]
    -r, --rate <rate>          rate in packets/second [default: 100]
    -s, --size <size>          payload size [default: 64]
    -w, --timeout <timeout>    timeout in seconds [default: 1]
    -z, --tos <tos>            type of service
    -t, --ttl <ttl>            time to live [default: 64]

ARGS:
    <ip address>...    one ip address or more, e.g. 127.0.0.1,8.8.8.8/24,bing.com

example

sudo ./mping -r 5 8.8.8.8
sudo ./mping -r 100 8.8.8.8/30,8.8.4.4,github.com
sudo ./mping -r 100 github.com,bing.com

docker:

sudo docker run --rm -it smallnest/mping-rs:latest 8.8.8.8

Usage - as a library

ping a target once

", args[0]); process::exit(1); } let addr = args[1].clone(); match ping_once(addr, Some(Duration::from_secs(2)), Some(1234), Some(64), None, Some(64)) { Ok((bitflip,latency)) => { println!("bitflip: {}, latency: {:.2}ms", bitflip, latency.as_secs_f64()*1000.0); } Err(e) => { println!("error: {:?}", e); } } }">
use std::env;
use std::process;
use std::time::Duration;
use std::net::{IpAddr, ToSocketAddrs};

use mping::ping_once;

/// ping a target as an example of ping_once.
fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() != 2 {
        println!("Usage: {} ", args[0]);
        process::exit(1);
    }
    let addr = args[1].clone();

    match ping_once(addr, Some(Duration::from_secs(2)), Some(1234), Some(64), None, Some(64)) {
        Ok((bitflip,latency)) => {
            println!("bitflip: {}, latency: {:.2}ms", bitflip, latency.as_secs_f64()*1000.0);
        }
        Err(e) => {
            println!("error: {:?}", e);
        }
    }

}

ping many targets forever

", args[0]); process::exit(1); } let pid = process::id() as u16; let target = args[1].clone(); let addr = parse_ip(&target); let addrs = vec![addr.parse().unwrap()]; let popt = PingOption { timeout: Duration::from_secs(1), ttl: 64, tos: None, ident: pid, len: 56, rate: 100, rate_for_all: false, delay: 3, count: None, }; let (tx, rx) = mpsc::channel(); thread::spawn(move || match ping(addrs, popt, false, Some(tx)) { Ok(_) => {} Err(e) => { println!("error: {:?}", e); } }); for tr in rx { let total = tr.received + tr.loss; let loss_rate = if total == 0 { 0.0 } else { (tr.loss as f64) / (total as f64) }; if tr.received == 0 { println!( "{}: sent:{}, recv:{}, loss rate: {:.2}%, latency: {}ms", addr, total, tr.received, loss_rate * 100.0, 0 ) } else { println!( "{}: sent:{}, recv:{}, loss rate: {:.2}%, latency: {:.2}ms", addr, total, tr.received, loss_rate * 100.0, Duration::from_nanos(tr.latency as u64 / (tr.received as u64)).as_secs_f64() * 1000.0 ) } } } fn parse_ip(s: &str) -> String { if let Ok(_) = s.parse::() { return s.to_string(); } else if let Ok(addrs) = (s, 0).to_socket_addrs() { for addr in addrs { if let IpAddr::V4(ipv4) = addr.ip() { return IpAddr::V4(ipv4).to_string(); } } } s.to_string() }">
use std::env;
use std::process;
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
use std::net::{IpAddr, ToSocketAddrs};

use ::mping::{ping, PingOption};

/// A multi-targets ping example, which use mping crate.
fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() != 2 {
        println!("Usage: {} ", args[0]);
        process::exit(1);
    }

    let pid = process::id() as u16;
    let target = args[1].clone();
    let addr = parse_ip(&target);

    let addrs = vec![addr.parse().unwrap()];
    let popt = PingOption {
        timeout: Duration::from_secs(1),
        ttl: 64,
        tos: None,
        ident: pid,
        len: 56,
        rate: 100,
        rate_for_all: false,
        delay: 3,
        count: None,
    };
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || match ping(addrs, popt, false, Some(tx)) {
        Ok(_) => {}
        Err(e) => {
            println!("error: {:?}", e);
        }
    });

    for tr in rx {
        let total = tr.received + tr.loss;
        let loss_rate = if total == 0 {
            0.0
        } else {
            (tr.loss as f64) / (total as f64)
        };

        if tr.received == 0 {
            println!(
                "{}: sent:{}, recv:{}, loss rate: {:.2}%, latency: {}ms",
                addr,
                total,
                tr.received,
                loss_rate * 100.0,
                0
            )
        } else {
            println!(
                "{}: sent:{}, recv:{},  loss rate: {:.2}%, latency: {:.2}ms",
                addr,
                total,
                tr.received,
                loss_rate * 100.0,
                Duration::from_nanos(tr.latency as u64 / (tr.received as u64)).as_secs_f64()
                    * 1000.0
            )
        }
    }
}

fn parse_ip(s: &str) -> String {
    if let Ok(_) = s.parse::<IpAddr>() {
        return s.to_string();
    } else if let Ok(addrs) = (s, 0).to_socket_addrs() {
        for addr in addrs {
            if let IpAddr::V4(ipv4) = addr.ip() {
                return IpAddr::V4(ipv4).to_string();
            }
        }
    }
    
    s.to_string()
}
You might also like...
An HTTP server wrapper for omnisette. Supports both V1 (Provision) and V3 of anisette servers.

omnisette-server An HTTP server wrapper for omnisette. Supports both V1 (Provision) and V3 of anisette servers. Setup First, download the Apple Music

Bevy asset loader that transparently supports loading over http(s)

Bevy Web Asset This is a tiny crate that that wraps the standard bevy asset loader, and adds the ability to load assets from http and https urls. Supp

🔍 Fully-featured metrics collection agent for First Tech Challenge competitions. Supports Prometheus.

Scout Scout is a fully-featured free and open source metrics collector for FTC competitions. The project is licensed under the GNU LGPLv3 license. Fea

An end-to-end encrypted, anonymous IP-hiding, decentralized, audio/video/file sharing/offline messaging multi-device platform built for both communications and application security and performance.

An end-to-end encrypted, anonymous IP-hiding, decentralized, audio/video/file sharing/offline messaging multi-device platform built for both communications and application security and performance.

A multi-connection TCP reverse proxy server and client.

tprox A multi-connection TCP reverse proxy. The tprox server is able to proxy multiple incoming connections to the tprox client over a single TCP conn

A multi-protocol network relay

A multi-protocol network relay

A set of cryptographic primitives for building a multi-hop Proxy Re-encryption scheme, known as Transform Encryption.

recrypt A pure-Rust library that implements a set of cryptographic primitives for building a multi-hop Proxy Re-encryption scheme, known as Transform

A multi-functional lightweight BitTorrent Tracker

Torrust-Axum Tracker Project Description Torrust-Axum Tracker is a lightweight but incredibly powerful and feature-rich BitTorrent Tracker made using

IDP2P is a peer-to-peer identity protocol which enables a controller to create, manage and share its own proofs as well as did documents
IDP2P is a peer-to-peer identity protocol which enables a controller to create, manage and share its own proofs as well as did documents

IDP2P Experimental, inspired by ipfs, did:peer and keri Background See also (related topics): Decentralized Identifiers (DIDs) Verifiable Credentials

Comments
  • Fix mping doesn't work in MACOSX

    Fix mping doesn't work in MACOSX

    Currently, we hardcode the EAGAIN(11) errno check when reading the socket which is NOT always the same in different platforms(for example, MACOS is 35). So it'd be better to use ErrorKind::WouldBlock instead of the hardcode number.

    Before applying this patch:

    ❯ sudo ./target/debug/mping -r 5 8.8.8.8
    10:40:37 [INFO] 8.8.8.8: sent:5, recv:5,  loss rate: 0.00%, latency: 12.05ms
    10:40:37 [ERROR] Error in read: Os { code: 35, kind: WouldBlock, message: "Resource temporarily unavailable" }
    
    opened by git-hulk 0
Releases(v0.2.0)
Owner
smallnest
Author of 《Scala Collections Cookbook》
smallnest
A minimalistic encryption protocol for rust async streams/packets, based on noise protocol and snow.

Snowstorm A minimalistic encryption protocol for rust async streams / packets, based on noise protocol and snow. Quickstart Snowstorm allows you to se

Black Binary 19 Nov 22, 2022
Dropping GFW DNS contaminated packets based on Rust + eBPF

Dropping GFW DNS contaminated packets based on Rust + eBPF

ihc童鞋@提不起劲 1k Jan 3, 2023
Replay packets from pcap -file to network interface

pktreplay can be used to read packets from pcap file or interface and write them into interface. By default packets are written with the same rate they have been saved into the pcap file, or, when reading from interface, as fast as they are received.

Jukka Taimisto 3 Nov 23, 2022
A performant but not-so-accurate time and capacity based cache for Rust.

fastcache A performant but not-so-accurate time and capacity based cache for Rust. This crate provides an implementation of a time-to-live (TTL) and c

Pure White 3 Aug 17, 2023
A prettier lightweight colored ping utility written in Rust

rustyping A prettier lightweight colored ping utility written in Rust. Installation There are three installation options: From the releases page From

K4YT3X 29 Dec 31, 2022
Simple utility to ping a TCP port.

TcpPing Simple utility to ping a TCP port. Example > tcpping 1.1.1.1 53 -b en0 -i 1 -t 4 Connected to 1.1.1.1:53 in 21 ms Connected to 1.1.1.1:53 in 3

null 11 Nov 24, 2022
A fast, stable, efficient, and lightweight intranet penetration, port forwarding tool supports multiple connections, cascading proxy, and transmission encryption

A fast, stable, efficient, and lightweight intranet penetration, port forwarding tool supports multiple connections, cascading proxy, and transmission encryption

editso 1.3k Dec 30, 2022
A tool for defining and running multi-container Docker applications

Ikki Ikki is a tool for defining and running multi-container Docker applications. It is similar to Docker Compose but comes with some differences. Goa

Kirill Vasiltsov 39 Dec 21, 2022
Network Block Storage server, written in Rust. Supports pluggable and chainable underlying storage

nbd-rs Disclaimer DO NEVER USE THIS FOR PRODUCTION Do not use this for any data that you cannot afford to lose any moment. Expect data loss, corruptio

Rainlab Inc 10 Sep 30, 2022
An experimental HTTP server in Rust that supports HTTP/1.1, HTTP/2, and HTTP/3 over QUIC.

?? H123 An experimental HTTP server in Rust that supports HTTP/1.1, HTTP/2, and HTTP/3 over QUIC. Warning This is an experimental project and not inte

Naoki Ikeguchi 7 Dec 15, 2022