r_lanlib/packet/
syn_packet.rs

1//! Provides helpers for creating SYN packets
2
3use std::net;
4
5use derive_builder::Builder;
6use pnet::{
7    packet::{MutablePacket, ethernet, ip, ipv4, tcp},
8    util,
9};
10
11const PKT_ETH_SIZE: usize = ethernet::EthernetPacket::minimum_packet_size();
12const PKT_IP4_SIZE: usize = ipv4::Ipv4Packet::minimum_packet_size();
13const PKT_TCP_SIZE: usize = tcp::TcpPacket::minimum_packet_size();
14const PKT_TOTAL_SIZE: usize = PKT_ETH_SIZE + PKT_IP4_SIZE + PKT_TCP_SIZE;
15
16/// Represents a generator for raw SYN packets
17#[derive(Debug, Builder)]
18#[builder(setter(into))]
19pub struct SynPacket {
20    /// IP address of the host machine performing scanning
21    source_ip: net::Ipv4Addr,
22    /// MAC address of host machine performing scanning
23    source_mac: util::MacAddr,
24    /// Source port on which host machine is listening for packets
25    source_port: u16,
26    /// Target destination IP for the packet
27    dest_ip: net::Ipv4Addr,
28    /// Target destination MAC address for the packet
29    dest_mac: util::MacAddr,
30    /// Target destination port for the packet
31    dest_port: u16,
32}
33
34impl SynPacket {
35    /// Builds a new SYN request packet using the provided information
36    pub fn to_raw(&self) -> [u8; PKT_TOTAL_SIZE] {
37        let mut pkt_buf = [0u8; PKT_TOTAL_SIZE];
38
39        let mut eth_header = ethernet::MutableEthernetPacket::new(&mut pkt_buf)
40            .expect("failed to generate ethernet header");
41        eth_header.set_ethertype(ethernet::EtherTypes::Ipv4);
42        eth_header.set_source(self.source_mac);
43        eth_header.set_destination(self.dest_mac);
44
45        // set ip header
46        let mut ip_buffer = [0u8; PKT_IP4_SIZE + PKT_TCP_SIZE];
47
48        let mut ip_header =
49            ipv4::MutableIpv4Packet::new(&mut ip_buffer).expect("failed to generate ip header");
50
51        ip_header.set_next_level_protocol(ip::IpNextHeaderProtocols::Tcp);
52        ip_header.set_source(self.source_ip);
53        ip_header.set_destination(self.dest_ip);
54        ip_header.set_version(4);
55        ip_header.set_ttl(64);
56        ip_header.set_identification(0);
57        ip_header.set_header_length(5);
58        ip_header.set_total_length(40);
59        ip_header.set_checksum(ipv4::checksum(&ip_header.to_immutable()));
60
61        // set tcp header
62        let mut tcp_buffer = [0u8; PKT_TCP_SIZE];
63
64        let mut tcp_header =
65            tcp::MutableTcpPacket::new(&mut tcp_buffer).expect("failed to generate tcp header");
66
67        tcp_header.set_source(self.source_port);
68        tcp_header.set_destination(self.dest_port);
69        tcp_header.set_flags(tcp::TcpFlags::SYN);
70        tcp_header.set_data_offset(5);
71        tcp_header.set_sequence(0);
72        tcp_header.set_checksum(tcp::ipv4_checksum(
73            &tcp_header.to_immutable(),
74            &self.source_ip,
75            &self.dest_ip,
76        ));
77
78        ip_header.set_payload(tcp_header.packet_mut());
79        eth_header.set_payload(ip_header.packet_mut());
80
81        pkt_buf
82    }
83}
84
85#[cfg(test)]
86#[allow(warnings)]
87#[doc(hidden)]
88// only used in tests
89pub fn create_syn_reply(
90    from_mac: util::MacAddr,
91    from_ip: net::Ipv4Addr,
92    from_port: u16,
93    to_mac: util::MacAddr,
94    to_ip: net::Ipv4Addr,
95    to_port: u16,
96    packet: &'static mut [u8; PKT_TOTAL_SIZE],
97) {
98    let mut eth_header =
99        ethernet::MutableEthernetPacket::new(packet).expect("failed to generate ethernet header");
100    eth_header.set_ethertype(ethernet::EtherTypes::Ipv4);
101    eth_header.set_source(from_mac);
102    eth_header.set_destination(to_mac);
103
104    // set ip header
105    let mut ip_buffer = [0u8; PKT_IP4_SIZE + PKT_TCP_SIZE];
106
107    let mut ip_header =
108        ipv4::MutableIpv4Packet::new(&mut ip_buffer).expect("failed to generate ip header");
109
110    ip_header.set_next_level_protocol(ip::IpNextHeaderProtocols::Tcp);
111    ip_header.set_source(from_ip);
112    ip_header.set_destination(to_ip);
113    ip_header.set_version(4);
114    ip_header.set_ttl(64);
115    ip_header.set_identification(0);
116    ip_header.set_header_length(5);
117    ip_header.set_total_length(40);
118    ip_header.set_checksum(ipv4::checksum(&ip_header.to_immutable()));
119
120    // set tcp header
121    let mut tcp_buffer = [0u8; PKT_TCP_SIZE];
122
123    let mut tcp_header =
124        tcp::MutableTcpPacket::new(&mut tcp_buffer).expect("failed to generate tcp header");
125
126    tcp_header.set_source(from_port);
127    tcp_header.set_destination(to_port);
128    tcp_header.set_flags(tcp::TcpFlags::SYN | tcp::TcpFlags::ACK);
129    tcp_header.set_data_offset(5);
130    tcp_header.set_sequence(11111);
131    tcp_header.set_checksum(tcp::ipv4_checksum(
132        &tcp_header.to_immutable(),
133        &from_ip,
134        &to_ip,
135    ));
136
137    ip_header.set_payload(tcp_header.packet_mut());
138    eth_header.set_payload(ip_header.packet_mut());
139}
140
141#[cfg(test)]
142#[path = "./syn_packet_tests.rs"]
143mod tests;