1use std::net::Ipv4Addr;
2
3use pnet::packet::{ethernet, ip, ipv4, tcp};
4use pnet::{datalink, util::MacAddr};
5
6use crate::Result;
7use crate::util::get_random_ip;
8
9pub struct SynPayload {
11 pub src_ip: Ipv4Addr,
13 pub dst_ip: Ipv4Addr,
15 pub src_port: u16,
17 pub dst_port: u16,
19 pub interface: datalink::NetworkInterface,
21}
22
23impl SynPayload {
24 pub fn new(dst_ip: Ipv4Addr, dst_port: u16, interface: &datalink::NetworkInterface) -> Self {
25 Self {
26 src_ip: get_random_ip(),
27 dst_ip,
28 src_port: fastrand::u16(1024..65535),
29 dst_port,
30 interface: interface.clone(),
31 }
32 }
33
34 pub fn random(interface: &datalink::NetworkInterface) -> Self {
35 Self {
36 src_ip: get_random_ip(),
37 dst_ip: get_random_ip(),
38 src_port: fastrand::u16(1024..65535),
39 dst_port: fastrand::u16(1..65535),
40 interface: interface.clone(),
41 }
42 }
43
44 pub fn source_ip(&mut self, src_ip: Ipv4Addr) {
45 self.src_ip = src_ip;
46 }
47
48 pub fn destination_ip(&mut self, dst_ip: Ipv4Addr) {
49 self.dst_ip = dst_ip;
50 }
51
52 pub fn source_port(&mut self, src_port: u16) {
53 self.src_port = src_port;
54 }
55
56 pub fn destination_port(&mut self, dst_port: u16) {
57 self.dst_port = dst_port;
58 }
59}
60
61impl super::Payload for SynPayload {
62 fn build(&mut self, packet: &mut [u8]) -> Result<()> {
63 {
64 let mut ethernet_header =
65 ethernet::MutableEthernetPacket::new(&mut packet[..super::PKT_ETH_SIZE])
66 .ok_or(crate::error::Error::InsufficientBuffer)?;
67 ethernet_header.set_destination(MacAddr::broadcast());
68 ethernet_header.set_source(self.interface.mac.ok_or(
69 crate::error::Error::InvalidInterface(format!(
70 "Mac address for {} is not found",
71 self.interface.name
72 )),
73 )?);
74 ethernet_header.set_ethertype(ethernet::EtherTypes::Ipv4);
75 }
76
77 {
78 let mut ipv4_header = ipv4::MutableIpv4Packet::new(
79 &mut packet[super::PKT_ETH_SIZE..(super::PKT_ETH_SIZE + super::PKT_IPV4_SIZE)],
80 )
81 .ok_or(crate::error::Error::InsufficientBuffer)?;
82 ipv4_header.set_header_length(69);
83 ipv4_header.set_total_length(52);
84 ipv4_header.set_next_level_protocol(ip::IpNextHeaderProtocols::Tcp);
85 ipv4_header.set_source(self.src_ip);
86 ipv4_header.set_destination(self.dst_ip);
87 ipv4_header.set_identification(fastrand::u16(..));
88 ipv4_header.set_ttl(64);
89 ipv4_header.set_version(4);
90 ipv4_header.set_flags(ipv4::Ipv4Flags::DontFragment);
91
92 let checksum = ipv4::checksum(&ipv4_header.to_immutable());
93 ipv4_header.set_checksum(checksum);
94 }
95
96 {
97 let mut tcp_header = tcp::MutableTcpPacket::new(
98 &mut packet[(super::PKT_ETH_SIZE + super::PKT_IPV4_SIZE)..],
99 )
100 .ok_or(crate::error::Error::InsufficientBuffer)?;
101
102 tcp_header.set_source(self.src_port);
103 tcp_header.set_destination(self.dst_port);
104
105 tcp_header.set_flags(tcp::TcpFlags::SYN);
106 tcp_header.set_window(64240);
107 tcp_header.set_data_offset(8);
108 tcp_header.set_urgent_ptr(0);
109 tcp_header.set_sequence(0);
110
111 tcp_header.set_options(&[
112 tcp::TcpOption::mss(1460),
113 tcp::TcpOption::sack_perm(),
114 tcp::TcpOption::nop(),
115 tcp::TcpOption::nop(),
116 tcp::TcpOption::wscale(7),
117 ]);
118
119 let checksum =
120 tcp::ipv4_checksum(&tcp_header.to_immutable(), &self.src_ip, &self.dst_ip);
121 tcp_header.set_checksum(checksum);
122 }
123
124 Ok(())
125 }
126}