simple_ping/
simple_ping.rs1#[cfg(target_os = "linux")]
10fn main() -> Result<(), Box<dyn std::error::Error>> {
11 use std::net::Ipv4Addr;
12 use std::time::{Duration, Instant};
13 use wireforge_core::icmp::{IcmpPacket, IcmpPacketBuilder};
14 use wireforge_core::ipv4::{Ipv4Packet, Ipv4PacketBuilder};
15 use wireforge_core::types::IpProtocol;
16 use wireforge_io::{L3Receiver, L3Sender};
17
18 let target: Ipv4Addr = std::env::args()
19 .nth(1)
20 .unwrap_or_else(|| "8.8.8.8".into())
21 .parse()?;
22 let src = Ipv4Addr::new(0, 0, 0, 0); let mut rx = L3Receiver::new(IpProtocol::Icmp)?;
25 rx.set_timeout(Some(Duration::from_secs(2)))?;
26
27 let tx = L3Sender::new()?;
28
29 let icmp = IcmpPacketBuilder::echo_request()
30 .identifier(0x0001)
31 .sequence_number(1)
32 .payload(b"wireforge-ping!")
33 .build();
34
35 let ip = Ipv4PacketBuilder::new()
36 .source(src)
37 .destination(target)
38 .protocol(IpProtocol::Icmp)
39 .ttl(64)
40 .payload(&icmp)
41 .unwrap()
42 .build();
43
44 let start = Instant::now();
45 tx.send_to(&ip, std::net::SocketAddrV4::new(target, 0))?;
46 println!("PING {} ...", target);
47
48 loop {
49 let reply = rx.recv()?;
50 if reply.protocol() == IpProtocol::Icmp && reply.destination() == src {
51 if let Some(icmp_reply) = IcmpPacket::new(reply.payload()) {
52 if icmp_reply.type_() == 0 {
53 let rtt = start.elapsed();
55 println!(
56 "Reply from {}: seq={} ttl={} rtt={:.2}ms",
57 reply.source(),
58 1,
59 reply.ttl(),
60 rtt.as_secs_f64() * 1000.0,
61 );
62 break;
63 }
64 }
65 }
66 }
67 Ok(())
68}
69
70#[cfg(not(target_os = "linux"))]
71fn main() {
72 eprintln!("simple_ping requires Linux (raw sockets).");
73}