pub struct Ipv4Packet {
Show 15 fields pub version: u8, pub header_length: u8, pub dscp: u8, pub ecn: u8, pub total_length: u16, pub identification: u16, pub flags: u8, pub fragment_offset: u16, pub ttl: u8, pub next_level_protocol: IpNextLevelProtocol, pub checksum: u16, pub source: Ipv4Addr, pub destination: Ipv4Addr, pub options: Vec<Ipv4Option>, pub payload: Vec<u8>,
}
Expand description

Represents an IPv4 packet.

Fields§

§version: u8§header_length: u8§dscp: u8§ecn: u8§total_length: u16§identification: u16§flags: u8§fragment_offset: u16§ttl: u8§next_level_protocol: IpNextLevelProtocol§checksum: u16§source: Ipv4Addr§destination: Ipv4Addr§options: Vec<Ipv4Option>§payload: Vec<u8>

Implementations§

source§

impl Ipv4Packet

source

pub fn from_bytes(packet: &[u8]) -> Ipv4Packet

Examples found in repository?
examples/socket/icmp.rs (line 45)
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
fn main() {
    let dst_ip: IpAddr = IpAddr::V4(Ipv4Addr::new(1, 1, 1, 1));
    let interface: Interface = cross_socket::interface::get_default_interface().unwrap();
    let socket_option = SocketOption {
        ip_version: IpVersion::V4,
        socket_type: SocketType::Raw,
        protocol: Some(IpNextLevelProtocol::Icmp),
        timeout: None,
        ttl: None,
        non_blocking: false,
    };
    let socket: Socket = Socket::new(socket_option).unwrap();
    // Create packet info
    let mut packet_info = PacketInfo::new();
    packet_info.src_ip = IpAddr::V4(interface.ipv4[0].addr);
    packet_info.dst_ip = dst_ip;
    packet_info.ip_protocol = Some(IpNextLevelProtocol::Icmp);
    packet_info.payload = vec![0; 0];

    // Build ICMP Echo Request packet
    let icmp_packet = cross_socket::packet::builder::build_icmp_packet();

    // Send ICMP Echo Request packets to 1.1.1.1
    let socket_addr = SocketAddr::new(dst_ip, 0);
    match socket.send_to(&icmp_packet, socket_addr) {
        Ok(packet_len) => {
            println!("Sent {} bytes", packet_len);
        }
        Err(e) => {
            println!("Error: {}", e);
        }
    }

    // Receive ICMP Echo Reply packets from 1.1.1.1
    println!("Waiting for ICMP Echo Reply... ");
    let mut buf = vec![0; 512];
    let (packet_len, _) = socket.receive_from(&mut buf).unwrap();
    let ip_packet = cross_socket::packet::ipv4::Ipv4Packet::from_bytes(&buf[..packet_len]);
    println!("Received {} bytes from {}", packet_len, ip_packet.source);
    let icmp_packet = cross_socket::packet::icmp::IcmpPacket::from_bytes(&ip_packet.payload);
    println!("Packet: {:?}", icmp_packet);
}
More examples
Hide additional examples
examples/datalink_socket/tcp_ping.rs (line 44)
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
fn main() {
    let interface: Interface = cross_socket::interface::get_default_interface().unwrap();
    // Create new socket
    let mut socket: DataLinkSocket = DataLinkSocket::new(interface, false).unwrap();
    // Create packet info
    let mut packet_info = PacketInfo::new();
    packet_info.src_mac = socket.interface.mac_addr.clone().unwrap();
    packet_info.dst_mac = socket.interface.gateway.clone().unwrap().mac_addr;
    packet_info.ether_type = EtherType::Ipv4;
    packet_info.src_ip = IpAddr::V4(socket.interface.ipv4[0].addr);
    packet_info.dst_ip = IpAddr::V4(std::net::Ipv4Addr::new(1, 1, 1, 1));
    packet_info.src_port = Some(53443);
    packet_info.dst_port = Some(80);
    packet_info.ip_protocol = Some(IpNextLevelProtocol::Tcp);
    packet_info.payload = vec![0; 0];

    // Send TCP SYN packets to 1.1.1.1:80
    match socket.send(packet_info) {
        Ok(packet_len) => {
            println!("Sent {} bytes", packet_len);
        }
        Err(e) => {
            println!("Error: {}", e);
        }
    }

    // Receive packets
    println!("Waiting for TCP SYN+ACK... ");
    loop {
        match socket.receive() {
            Ok(packet) => {
                let ethernet_packet = cross_socket::packet::ethernet::EthernetPacket::from_bytes(&packet);
                if ethernet_packet.ethertype != EtherType::Ipv4 {
                    continue;
                }
                let ip_packet = cross_socket::packet::ipv4::Ipv4Packet::from_bytes(&ethernet_packet.payload);
                if ip_packet.next_level_protocol != IpNextLevelProtocol::Tcp || ip_packet.source != std::net::Ipv4Addr::new(1, 1, 1, 1) {
                    continue;
                }
                println!("Received {} bytes from {}", packet.len(), ip_packet.source);
                let tcp_packet = cross_socket::packet::tcp::TcpPacket::from_bytes(&ip_packet.payload);
                println!("Packet: {:?}", tcp_packet);
                break;
            }
            Err(e) => {
                println!("Error: {}", e);
            }
        }
    }
    
}
examples/datalink_socket/icmp_ping.rs (line 44)
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
fn main() {
    let interface: Interface = cross_socket::interface::get_default_interface().unwrap();
    // Create new socket
    let mut socket: DataLinkSocket = DataLinkSocket::new(interface, false).unwrap();
    // Create packet info
    let mut packet_info = PacketInfo::new();
    packet_info.src_mac = socket.interface.mac_addr.clone().unwrap();
    packet_info.dst_mac = socket.interface.gateway.clone().unwrap().mac_addr;
    packet_info.ether_type = EtherType::Ipv4;
    packet_info.src_ip = IpAddr::V4(socket.interface.ipv4[0].addr);
    packet_info.dst_ip = IpAddr::V4(std::net::Ipv4Addr::new(1, 1, 1, 1));
    packet_info.src_port = None;
    packet_info.dst_port = None;
    packet_info.ip_protocol = Some(IpNextLevelProtocol::Icmp);
    packet_info.payload = vec![0; 0];

    // Send ICMP Echo Request packets to 1.1.1.1
    match socket.send(packet_info) {
        Ok(packet_len) => {
            println!("Sent {} bytes", packet_len);
        }
        Err(e) => {
            println!("Error: {}", e);
        }
    }

    // Receive packets
    println!("Waiting for ICMP Echo Reply... ");
    loop {
        match socket.receive() {
            Ok(packet) => {
                let ethernet_packet = cross_socket::packet::ethernet::EthernetPacket::from_bytes(&packet);
                if ethernet_packet.ethertype != EtherType::Ipv4 {
                    continue;
                }
                let ip_packet = cross_socket::packet::ipv4::Ipv4Packet::from_bytes(&ethernet_packet.payload);
                if ip_packet.next_level_protocol != IpNextLevelProtocol::Icmp || ip_packet.source != std::net::Ipv4Addr::new(1, 1, 1, 1) {
                    continue;
                }
                println!("Received {} bytes from {}", packet.len(), ip_packet.source);
                let icmp_packet = cross_socket::packet::icmp::IcmpPacket::from_bytes(&ip_packet.payload);
                println!("Packet: {:?}", icmp_packet);
                break;
            }
            Err(e) => {
                println!("Error: {}", e);
            }
        }
    }
    
}
examples/datalink_socket/udp_ping.rs (line 44)
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
fn main() {
    let interface: Interface = cross_socket::interface::get_default_interface().unwrap();
    // Create new socket
    let mut socket: DataLinkSocket = DataLinkSocket::new(interface, false).unwrap();
    // Create packet info
    let mut packet_info = PacketInfo::new();
    packet_info.src_mac = socket.interface.mac_addr.clone().unwrap();
    packet_info.dst_mac = socket.interface.gateway.clone().unwrap().mac_addr;
    packet_info.ether_type = EtherType::Ipv4;
    packet_info.src_ip = IpAddr::V4(socket.interface.ipv4[0].addr);
    packet_info.dst_ip = IpAddr::V4(std::net::Ipv4Addr::new(1, 1, 1, 1));
    packet_info.src_port = Some(53443);
    packet_info.dst_port = Some(33435);
    packet_info.ip_protocol = Some(IpNextLevelProtocol::Udp);
    packet_info.payload = vec![0; 0];

    // Send UDP packets to 1.1.1.1:33435
    match socket.send(packet_info) {
        Ok(packet_len) => {
            println!("Sent {} bytes", packet_len);
        }
        Err(e) => {
            println!("Error: {}", e);
        }
    }

    // Receive packets
    println!("Waiting for ICMP Destination (Port) Unreachable...");
    loop {
        match socket.receive() {
            Ok(packet) => {
                let ethernet_packet = cross_socket::packet::ethernet::EthernetPacket::from_bytes(&packet);
                if ethernet_packet.ethertype != EtherType::Ipv4 {
                    continue;
                }
                let ip_packet = cross_socket::packet::ipv4::Ipv4Packet::from_bytes(&ethernet_packet.payload);
                if ip_packet.next_level_protocol != IpNextLevelProtocol::Icmp || ip_packet.source != std::net::Ipv4Addr::new(1, 1, 1, 1) {
                    continue;
                }
                println!("Received {} bytes from {}", packet.len(), ip_packet.source);
                let icmp_packet = cross_socket::packet::icmp::IcmpPacket::from_bytes(&ip_packet.payload);
                println!("Packet: {:?}", icmp_packet);
                break;
            }
            Err(e) => {
                println!("Error: {}", e);
            }
        }
    }
    
}
examples/socket/udp.rs (line 57)
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
fn main() {
    let interface: Interface = cross_socket::interface::get_default_interface().unwrap();
    let src_ip: IpAddr = IpAddr::V4(interface.ipv4[0].addr);
    let src_socket_addr: SocketAddr = SocketAddr::new(src_ip, 0);
    let dst_ip: IpAddr = IpAddr::V4(Ipv4Addr::new(1, 1, 1, 1));
    let dst_socket_addr: SocketAddr = SocketAddr::new(dst_ip, 33435);
    let socket_option = SocketOption {
        ip_version: IpVersion::V4,
        socket_type: SocketType::Dgram,
        protocol: Some(IpNextLevelProtocol::Udp),
        timeout: None,
        ttl: None,
        non_blocking: false,
    };
    // Sender socket
    let socket: Socket = Socket::new(socket_option).unwrap();

    // Receiver socket
    let listener_socket: ListenerSocket = ListenerSocket::new(src_socket_addr, IpVersion::V4, None, Some(Duration::from_millis(1000))).unwrap();

    // Create packet info
    let mut packet_info = PacketInfo::new();
    packet_info.src_ip = src_ip;
    packet_info.dst_ip = dst_socket_addr.ip();
    packet_info.src_port = Some(53443);
    packet_info.dst_port = Some(dst_socket_addr.port());
    packet_info.ip_protocol = Some(IpNextLevelProtocol::Udp);
    packet_info.payload = vec![0; 0];

    // Build UDP packet
    let udp_packet = cross_socket::packet::builder::build_udp_packet(packet_info);

    // Send UDP packets to 1.1.1.1:33435
    match socket.send_to(&udp_packet, dst_socket_addr) {
        Ok(packet_len) => {
            println!("Sent {} bytes", packet_len);
        }
        Err(e) => {
            println!("Error: {}", e);
        }
    }

    // Receive ICMP Port Unreachable packets
    println!("Waiting for ICMP Destination (Port) Unreachable...");
    let mut buf = vec![0; 512];
    loop {
        match listener_socket.receive_from(&mut buf){
            Ok((packet_len, _)) => {
                let ip_packet = cross_socket::packet::ipv4::Ipv4Packet::from_bytes(&buf[..packet_len]);
                if ip_packet.next_level_protocol != IpNextLevelProtocol::Icmp || ip_packet.source != std::net::Ipv4Addr::new(1, 1, 1, 1) {
                    continue;
                }
                println!("Received {} bytes from {}", packet_len, ip_packet.source);
                let icmp_packet = cross_socket::packet::icmp::IcmpPacket::from_bytes(&ip_packet.payload);
                println!("Packet: {:?}", icmp_packet);
                break;
            }
            Err(e) => {
                println!("Error: {}", e);
            }
        }
    }
}
examples/socket/tcp.rs (line 64)
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
fn main() {
    let interface: Interface = cross_socket::interface::get_default_interface().unwrap();
    let src_ip: IpAddr = IpAddr::V4(interface.ipv4[0].addr);
    let src_socket_addr: SocketAddr = SocketAddr::new(src_ip, 53443);
    let dst_ip: IpAddr = IpAddr::V4(Ipv4Addr::new(1, 1, 1, 1));
    let dst_socket_addr: SocketAddr = SocketAddr::new(dst_ip, 80);
    let socket_option = SocketOption {
        ip_version: IpVersion::V4,
        socket_type: SocketType::Raw,
        protocol: Some(IpNextLevelProtocol::Tcp),
        timeout: None,
        ttl: None,
        non_blocking: false,
    };
    // Sender socket
    let socket: Socket = Socket::new(socket_option).unwrap();

    // Receiver socket
    // RAW SOCKET recvfrom not working for TCP. So we use DataLinkSocket instead.
    let mut listener_socket: DataLinkSocket = DataLinkSocket::new(interface, false).unwrap();

    // Create packet info
    let mut packet_info = PacketInfo::new();
    packet_info.src_ip = src_socket_addr.ip();
    packet_info.dst_ip = dst_socket_addr.ip();
    packet_info.src_port = Some(src_socket_addr.port());
    packet_info.dst_port = Some(dst_socket_addr.port());
    packet_info.ip_protocol = Some(IpNextLevelProtocol::Tcp);
    packet_info.payload = vec![0; 0];

    // Build TCP SYN packet
    let tcp_packet = cross_socket::packet::builder::build_tcp_syn_packet(packet_info);

    // Send TCP SYN packet to 1.1.1.1
    match socket.send_to(&tcp_packet, dst_socket_addr) {
        Ok(packet_len) => {
            println!("Sent {} bytes", packet_len);
        }
        Err(e) => {
            println!("Error: {}", e);
        }
    }

    // Receive packets
    println!("Waiting for TCP SYN+ACK... ");
    loop {
        match listener_socket.receive() {
            Ok(packet) => {
                let ethernet_packet = cross_socket::packet::ethernet::EthernetPacket::from_bytes(&packet);
                if ethernet_packet.ethertype != EtherType::Ipv4 {
                    continue;
                }
                let ip_packet = cross_socket::packet::ipv4::Ipv4Packet::from_bytes(&ethernet_packet.payload);
                if ip_packet.next_level_protocol != IpNextLevelProtocol::Tcp || ip_packet.source != std::net::Ipv4Addr::new(1, 1, 1, 1) {
                    continue;
                }
                println!("Received {} bytes from {}", packet.len(), ip_packet.source);
                let tcp_packet = cross_socket::packet::tcp::TcpPacket::from_bytes(&ip_packet.payload);
                println!("Packet: {:?}", tcp_packet);
                break;
            }
            Err(e) => {
                println!("Error: {}", e);
            }
        }
    }
}

Trait Implementations§

source§

impl Clone for Ipv4Packet

source§

fn clone(&self) -> Ipv4Packet

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl Debug for Ipv4Packet

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl PartialEq<Ipv4Packet> for Ipv4Packet

source§

fn eq(&self, other: &Ipv4Packet) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl StructuralPartialEq for Ipv4Packet

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere 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 Twhere 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 Twhere T: Clone,

§

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 Twhere U: Into<T>,

§

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 Twhere U: TryFrom<T>,

§

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

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

§

fn vzip(self) -> V