1use super::{Result, ReusablePacketWriter};
2
3use nix::sys::socket::{
4 AddressFamily, MsgFlags, SockFlag, SockProtocol, SockType, SockaddrIn, sendto, socket,
5};
6use std::os::fd::{AsRawFd, OwnedFd, RawFd};
7
8#[derive(Debug)]
10pub struct RawSocket {
11 fd: OwnedFd,
12}
13
14impl RawSocket {
15 #[inline]
17 pub fn new() -> Result<Self> {
18 let fd = socket(
19 AddressFamily::Inet,
20 SockType::Raw,
21 SockFlag::empty(),
22 Some(SockProtocol::Raw),
23 )?;
24 Ok(Self { fd })
25 }
26
27 #[inline]
29 pub fn sendto(&self, buf: &[u8], addr: [u8; 4]) -> Result<usize> {
30 let [a, b, c, d] = addr;
31 let addr = SockaddrIn::new(a, b, c, d, 0);
32 let len = sendto(self.as_raw_fd(), buf, &addr, MsgFlags::empty())?;
33 Ok(len)
34 }
35
36 #[inline]
38 pub fn send_fake_udp_packet(
39 &self,
40 writer: &mut ReusablePacketWriter,
41 source: [u8; 4],
42 source_port: u16,
43 destination: [u8; 4],
44 destination_port: u16,
45 payload: &[u8],
46 time_to_live: u8,
47 ) -> Result<usize> {
48 writer.write_udp_packet(
49 source,
50 source_port,
51 destination,
52 destination_port,
53 payload,
54 time_to_live,
55 )?;
56 self.sendto(writer.as_slice(), destination)
57 }
58
59 #[inline]
61 pub fn send_fake_tcp_syn_packet(
62 &self,
63 writer: &mut ReusablePacketWriter,
64 source: [u8; 4],
65 source_port: u16,
66 destination: [u8; 4],
67 destination_port: u16,
68 payload: &[u8],
69 time_to_live: u8,
70 sequence_number: u32,
71 window_size: u16,
72 ) -> Result<usize> {
73 writer.write_tcp_syn_packet(
74 source,
75 source_port,
76 destination,
77 destination_port,
78 payload,
79 time_to_live,
80 sequence_number,
81 window_size,
82 )?;
83 self.sendto(writer.as_slice(), destination)
84 }
85}
86
87impl AsRawFd for RawSocket {
89 fn as_raw_fd(&self) -> RawFd {
90 self.fd.as_raw_fd()
91 }
92}