1use super::Result;
2
3use etherparse::*;
4use rand::Rng;
5
6#[derive(Debug)]
8pub struct ReusablePacketWriter {
9 inner: Vec<u8>,
10}
11
12impl ReusablePacketWriter {
13 #[inline]
15 pub fn new() -> Self {
16 Self {
17 inner: Vec::with_capacity(u16::MAX as _),
18 }
19 }
20
21 #[inline]
23 pub fn as_slice(&self) -> &[u8] {
24 self.inner.as_slice()
25 }
26
27 #[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 #[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 #[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}