ipstack_geph/stream/
unknown.rs

1use crate::{
2    packet::{IpHeader, NetworkPacket, TransportHeader},
3    PacketSender, TTL,
4};
5use etherparse::{IpNumber, Ipv4Header, Ipv6FlowLabel, Ipv6Header};
6use std::{
7    io::{Error, ErrorKind},
8    mem,
9    net::IpAddr,
10};
11
12pub struct IpStackUnknownTransport {
13    src_addr: IpAddr,
14    dst_addr: IpAddr,
15    payload: Vec<u8>,
16    protocol: IpNumber,
17    mtu: u16,
18    packet_sender: PacketSender,
19}
20
21impl IpStackUnknownTransport {
22    pub(crate) fn new(
23        src_addr: IpAddr,
24        dst_addr: IpAddr,
25        payload: Vec<u8>,
26        ip: &IpHeader,
27        mtu: u16,
28        packet_sender: PacketSender,
29    ) -> Self {
30        let protocol = match ip {
31            IpHeader::Ipv4(ip) => ip.protocol,
32            IpHeader::Ipv6(ip) => ip.next_header,
33        };
34        IpStackUnknownTransport {
35            src_addr,
36            dst_addr,
37            payload,
38            protocol,
39            mtu,
40            packet_sender,
41        }
42    }
43    pub fn src_addr(&self) -> IpAddr {
44        self.src_addr
45    }
46    pub fn dst_addr(&self) -> IpAddr {
47        self.dst_addr
48    }
49    pub fn payload(&self) -> &[u8] {
50        &self.payload
51    }
52    pub fn ip_protocol(&self) -> IpNumber {
53        self.protocol
54    }
55    pub fn send(&self, mut payload: Vec<u8>) -> Result<(), Error> {
56        loop {
57            let packet = self
58                .create_rev_packet(&mut payload)
59                .map_err(|e| std::io::Error::new(ErrorKind::InvalidData, e))?;
60            self.packet_sender
61                .try_send(packet)
62                .map_err(|_| Error::new(std::io::ErrorKind::Other, "send error"))?;
63            if payload.is_empty() {
64                return Ok(());
65            }
66        }
67    }
68
69    pub fn create_rev_packet(&self, payload: &mut Vec<u8>) -> anyhow::Result<NetworkPacket> {
70        match (self.dst_addr, self.src_addr) {
71            (std::net::IpAddr::V4(dst), std::net::IpAddr::V4(src)) => {
72                let mut ip_h = Ipv4Header::new(0, TTL, self.protocol, dst.octets(), src.octets())?;
73                let line_buffer = self.mtu.saturating_sub(ip_h.header_len() as u16);
74
75                let p = if payload.len() > line_buffer as usize {
76                    payload.drain(0..line_buffer as usize).collect::<Vec<u8>>()
77                } else {
78                    mem::take(payload)
79                };
80                ip_h.set_payload_len(p.len())?;
81                Ok(NetworkPacket {
82                    ip: IpHeader::Ipv4(ip_h),
83                    transport: TransportHeader::Unknown,
84                    payload: p,
85                })
86            }
87            (std::net::IpAddr::V6(dst), std::net::IpAddr::V6(src)) => {
88                let mut ip_h = Ipv6Header {
89                    traffic_class: 0,
90                    flow_label: Ipv6FlowLabel::ZERO,
91                    payload_length: 0,
92                    next_header: IpNumber::UDP,
93                    hop_limit: TTL,
94                    source: dst.octets(),
95                    destination: src.octets(),
96                };
97                let line_buffer = self.mtu.saturating_sub(ip_h.header_len() as u16);
98                payload.truncate(line_buffer as usize);
99                ip_h.payload_length = payload.len() as u16;
100                let p = if payload.len() > line_buffer as usize {
101                    payload.drain(0..line_buffer as usize).collect::<Vec<u8>>()
102                } else {
103                    mem::take(payload)
104                };
105                Ok(NetworkPacket {
106                    ip: IpHeader::Ipv6(ip_h),
107                    transport: TransportHeader::Unknown,
108                    payload: p,
109                })
110            }
111            _ => unreachable!(),
112        }
113    }
114}