Skip to main content

L3Receiver

Struct L3Receiver 

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

Receiver for raw IPv4 packets via SOCK_RAW socket.

Implementations§

Source§

impl L3Receiver

Source

pub fn new(protocol: IpProtocol) -> Result<Self, IoError>

Open a SOCK_RAW socket for the given IP protocol.

Examples found in repository?
examples/simple_ping.rs (line 24)
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); // kernel fills source
23
24    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                    // Echo Reply
54                    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}
Source

pub fn recv(&mut self) -> Result<Ipv4Packet<'_>, IoError>

Receive a single IPv4 packet and parse it.

Examples found in repository?
examples/simple_ping.rs (line 49)
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); // kernel fills source
23
24    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                    // Echo Reply
54                    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}
Source

pub fn set_header_included(&mut self, on: bool) -> Result<(), IoError>

Enable or disable IP_HDRINCL (header included in send).

Source

pub fn set_timeout(&mut self, dur: Option<Duration>) -> Result<(), IoError>

Set receive timeout.

Examples found in repository?
examples/simple_ping.rs (line 25)
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); // kernel fills source
23
24    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                    // Echo Reply
54                    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}

Trait Implementations§

Source§

impl L3Reader for L3Receiver

Source§

fn recv(&mut self) -> Result<Ipv4Packet<'_>, IoError>

Receive a single IPv4 packet and parse it.
Source§

fn set_timeout(&mut self, dur: Option<Duration>) -> Result<(), IoError>

Set the receive timeout. None means blocking (no timeout).
Source§

fn set_header_included(&mut self, on: bool) -> Result<(), IoError>

Enable or disable IP_HDRINCL (header included in send).

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> 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, 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.