ip_spoofing/
packet.rs

1use super::Result;
2
3use etherparse::*;
4use rand::Rng;
5
6/// Wrapper around `Vec<u8>` that is pre-allocates memory for writing packet bytes
7#[derive(Debug)]
8pub struct ReusablePacketWriter {
9    inner: Vec<u8>,
10}
11
12impl ReusablePacketWriter {
13    /// Creates wrapper around `Vec<u8>` with pre-allocated `u16::MAX` (max possible MTU size)
14    #[inline]
15    pub fn new() -> Self {
16        Self {
17            inner: Vec::with_capacity(u16::MAX as _),
18        }
19    }
20
21    /// Takes slice of memory from this wrapper
22    #[inline]
23    pub fn as_slice(&self) -> &[u8] {
24        self.inner.as_slice()
25    }
26
27    /// Builds IPv4 header with randomized `identification` field
28    #[inline]
29    pub fn build_ipv4_header(
30        time_to_live: u8,
31        protocol: IpNumber,
32        source: [u8; 4],
33        destination: [u8; 4],
34    ) -> IpHeaders {
35        let identification = rand::rng().random();
36        IpHeaders::Ipv4(
37            Ipv4Header {
38                identification,
39                time_to_live,
40                protocol,
41                source,
42                destination,
43                ..Default::default()
44            },
45            Default::default(),
46        )
47    }
48
49    /// Writes UDP packet into buffer with given parameters
50    #[inline]
51    pub fn write_udp_packet(
52        &mut self,
53        source: [u8; 4],
54        source_port: u16,
55        destination: [u8; 4],
56        destination_port: u16,
57        payload: &[u8],
58        time_to_live: u8,
59    ) -> Result<()> {
60        self.inner.clear();
61
62        let ip_header = Self::build_ipv4_header(time_to_live, IpNumber::UDP, source, destination);
63
64        PacketBuilder::ip(ip_header)
65            .udp(source_port, destination_port)
66            .write(&mut self.inner, payload)?;
67
68        Ok(())
69    }
70
71    /// Writes TCP-SYN packet into buffer with given parameters
72    #[inline]
73    pub fn write_tcp_syn_packet(
74        &mut self,
75        source: [u8; 4],
76        source_port: u16,
77        destination: [u8; 4],
78        destination_port: u16,
79        payload: &[u8],
80        time_to_live: u8,
81        sequence_number: u32,
82        window_size: u16,
83    ) -> Result<()> {
84        self.inner.clear();
85
86        let ip_header = Self::build_ipv4_header(time_to_live, IpNumber::TCP, source, destination);
87
88        PacketBuilder::ip(ip_header)
89            .tcp(source_port, destination_port, sequence_number, window_size)
90            .syn()
91            .write(&mut self.inner, payload)?;
92
93        Ok(())
94    }
95}