xenet_packet/
frame.rs

1use xenet_core::mac::MacAddr;
2use xenet_macro_helper::packet::Packet;
3
4use crate::arp::{ArpHeader, ArpPacket};
5use crate::ethernet::EthernetHeader;
6use crate::ethernet::{EtherType, EthernetPacket, MutableEthernetPacket};
7use crate::icmp::{IcmpHeader, IcmpPacket};
8use crate::icmpv6::{Icmpv6Header, Icmpv6Packet};
9use crate::ip::IpNextLevelProtocol;
10use crate::ipv4::{Ipv4Header, Ipv4Packet};
11use crate::ipv6::{Ipv6Header, Ipv6Packet};
12use crate::tcp::{TcpHeader, TcpPacket};
13use crate::udp::{UdpHeader, UdpPacket};
14
15#[cfg(feature = "serde")]
16use serde::{Deserialize, Serialize};
17
18/// Represents a data link layer.
19#[derive(Clone, Debug, PartialEq, Eq)]
20#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
21pub struct DatalinkLayer {
22    pub ethernet: Option<EthernetHeader>,
23    pub arp: Option<ArpHeader>,
24}
25
26/// Represents an IP layer.
27#[derive(Clone, Debug, PartialEq, Eq)]
28#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
29pub struct IpLayer {
30    pub ipv4: Option<Ipv4Header>,
31    pub ipv6: Option<Ipv6Header>,
32    pub icmp: Option<IcmpHeader>,
33    pub icmpv6: Option<Icmpv6Header>,
34}
35
36/// Represents a transport layer.
37#[derive(Clone, Debug, PartialEq, Eq)]
38#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
39pub struct TransportLayer {
40    pub tcp: Option<TcpHeader>,
41    pub udp: Option<UdpHeader>,
42}
43
44/// Parse options.
45#[derive(Clone, Debug, PartialEq, Eq)]
46#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
47pub struct ParseOption {
48    /// Parse from IP packet.
49    pub from_ip_packet: bool,
50    /// Offset of the packet.
51    /// If `from_ip_packet` is true, this value is the offset of the IP packet.
52    pub offset: usize,
53}
54
55impl ParseOption {
56    /// Construct a new ParseOption.
57    pub fn new(from_ip_packet: bool, offset: usize) -> ParseOption {
58        ParseOption {
59            from_ip_packet,
60            offset,
61        }
62    }
63}
64
65impl Default for ParseOption {
66    fn default() -> Self {
67        ParseOption {
68            from_ip_packet: false,
69            offset: 0,
70        }
71    }
72}
73
74/// Represents a packet frame.
75#[derive(Clone, Debug, PartialEq, Eq)]
76#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
77pub struct Frame {
78    /// The datalink layer.
79    pub datalink: Option<DatalinkLayer>,
80    /// The IP layer.
81    pub ip: Option<IpLayer>,
82    /// The transport layer.
83    pub transport: Option<TransportLayer>,
84    /// Rest of the packet that could not be parsed as a header. (Usually payload)
85    pub payload: Vec<u8>,
86    /// Packet length.
87    pub packet_len: usize,
88}
89
90impl Frame {
91    /// Construct a frame from a byte slice.
92    pub fn from_bytes(packet: &[u8], option: ParseOption) -> Frame {
93        parse_packet(packet, option)
94    }
95}
96
97fn create_dummy_ethernet_packet(packet: &[u8], offset: usize) -> Vec<u8> {
98    let mut buf: Vec<u8> = vec![0u8; packet.len() - offset + 14];
99    match MutableEthernetPacket::new(&mut buf[..]) {
100        Some(mut fake_ethernet_frame) => match Ipv4Packet::new(&packet[offset..]) {
101            Some(ipv4_packet) => {
102                let version: u8 = ipv4_packet.get_version();
103                if version == 4 {
104                    fake_ethernet_frame.set_destination(MacAddr(0, 0, 0, 0, 0, 0));
105                    fake_ethernet_frame.set_source(MacAddr(0, 0, 0, 0, 0, 0));
106                    fake_ethernet_frame.set_ethertype(EtherType::Ipv4);
107                    fake_ethernet_frame.set_payload(&packet[offset..]);
108                } else if version == 6 {
109                    fake_ethernet_frame.set_destination(MacAddr(0, 0, 0, 0, 0, 0));
110                    fake_ethernet_frame.set_source(MacAddr(0, 0, 0, 0, 0, 0));
111                    fake_ethernet_frame.set_ethertype(EtherType::Ipv6);
112                    fake_ethernet_frame.set_payload(&packet[offset..]);
113                }
114                return fake_ethernet_frame.packet().to_vec();
115            }
116            None => {
117                return Vec::new();
118            }
119        },
120        None => {
121            return Vec::new();
122        }
123    }
124}
125
126fn parse_packet(packet: &[u8], option: ParseOption) -> Frame {
127    let mut frame = Frame {
128        datalink: None,
129        ip: None,
130        transport: None,
131        payload: Vec::new(),
132        packet_len: packet.len(),
133    };
134    let dummy_ethernet_packet: Vec<u8>;
135    let ethernet_packet = if option.from_ip_packet {
136        dummy_ethernet_packet = create_dummy_ethernet_packet(packet, option.offset);
137        match EthernetPacket::new(&dummy_ethernet_packet) {
138            Some(ethernet_packet) => ethernet_packet,
139            None => {
140                return frame;
141            }
142        }
143    } else {
144        match EthernetPacket::new(packet) {
145            Some(ethernet_packet) => ethernet_packet,
146            None => {
147                return frame;
148            }
149        }
150    };
151    let ethernet_header = EthernetHeader::from_packet(&ethernet_packet);
152    frame.datalink = Some(DatalinkLayer {
153        ethernet: Some(ethernet_header),
154        arp: None,
155    });
156    match ethernet_packet.get_ethertype() {
157        EtherType::Ipv4 => {
158            parse_ipv4_packet(&ethernet_packet, &mut frame);
159        }
160        EtherType::Ipv6 => {
161            parse_ipv6_packet(&ethernet_packet, &mut frame);
162        }
163        EtherType::Arp => {
164            parse_arp_packet(&ethernet_packet, &mut frame);
165        }
166        _ => {}
167    }
168    frame
169}
170
171fn parse_arp_packet(ethernet_packet: &EthernetPacket, frame: &mut Frame) {
172    match ArpPacket::new(ethernet_packet.payload()) {
173        Some(arp_packet) => {
174            let arp_header = ArpHeader::from_packet(&arp_packet);
175            if let Some(datalink) = &mut frame.datalink {
176                datalink.arp = Some(arp_header);
177            }
178        }
179        None => {
180            if let Some(datalink) = &mut frame.datalink {
181                datalink.arp = None;
182            }
183            frame.payload = ethernet_packet.payload().to_vec();
184        }
185    }
186}
187
188fn parse_ipv4_packet(ethernet_packet: &EthernetPacket, frame: &mut Frame) {
189    match Ipv4Packet::new(ethernet_packet.payload()) {
190        Some(ipv4_packet) => {
191            let ipv4_header = Ipv4Header::from_packet(&ipv4_packet);
192            frame.ip = Some(IpLayer {
193                ipv4: Some(ipv4_header),
194                ipv6: None,
195                icmp: None,
196                icmpv6: None,
197            });
198            match ipv4_packet.get_next_level_protocol() {
199                IpNextLevelProtocol::Tcp => {
200                    parse_ipv4_tcp_packet(&ipv4_packet, frame);
201                }
202                IpNextLevelProtocol::Udp => {
203                    parse_ipv4_udp_packet(&ipv4_packet, frame);
204                }
205                IpNextLevelProtocol::Icmp => {
206                    parse_icmp_packet(&ipv4_packet, frame);
207                }
208                _ => {
209                    frame.payload = ipv4_packet.payload().to_vec();
210                }
211            }
212        }
213        None => {
214            frame.ip = Some(IpLayer {
215                ipv4: None,
216                ipv6: None,
217                icmp: None,
218                icmpv6: None,
219            });
220        }
221    }
222}
223
224fn parse_ipv6_packet(ethernet_packet: &EthernetPacket, frame: &mut Frame) {
225    match Ipv6Packet::new(ethernet_packet.payload()) {
226        Some(ipv6_packet) => {
227            let ipv6_header = Ipv6Header::from_packet(&ipv6_packet);
228            frame.ip = Some(IpLayer {
229                ipv4: None,
230                ipv6: Some(ipv6_header),
231                icmp: None,
232                icmpv6: None,
233            });
234            match ipv6_packet.get_next_header() {
235                IpNextLevelProtocol::Tcp => {
236                    parse_ipv6_tcp_packet(&ipv6_packet, frame);
237                }
238                IpNextLevelProtocol::Udp => {
239                    parse_ipv6_udp_packet(&ipv6_packet, frame);
240                }
241                IpNextLevelProtocol::Icmpv6 => {
242                    parse_icmpv6_packet(&ipv6_packet, frame);
243                }
244                _ => {
245                    frame.payload = ipv6_packet.payload().to_vec();
246                }
247            }
248        }
249        None => {
250            frame.ip = Some(IpLayer {
251                ipv4: None,
252                ipv6: None,
253                icmp: None,
254                icmpv6: None,
255            });
256        }
257    }
258}
259
260fn parse_ipv4_tcp_packet(ipv4_packet: &Ipv4Packet, frame: &mut Frame) {
261    match TcpPacket::new(ipv4_packet.payload()) {
262        Some(tcp_packet) => {
263            let tcp_header = TcpHeader::from_packet(&tcp_packet);
264            frame.transport = Some(TransportLayer {
265                tcp: Some(tcp_header),
266                udp: None,
267            });
268            frame.payload = tcp_packet.payload().to_vec();
269        }
270        None => {
271            frame.transport = Some(TransportLayer {
272                tcp: None,
273                udp: None,
274            });
275            frame.payload = ipv4_packet.payload().to_vec();
276        }
277    }
278}
279
280fn parse_ipv6_tcp_packet(ipv6_packet: &Ipv6Packet, frame: &mut Frame) {
281    match TcpPacket::new(ipv6_packet.payload()) {
282        Some(tcp_packet) => {
283            let tcp_header = TcpHeader::from_packet(&tcp_packet);
284            frame.transport = Some(TransportLayer {
285                tcp: Some(tcp_header),
286                udp: None,
287            });
288            frame.payload = tcp_packet.payload().to_vec();
289        }
290        None => {
291            frame.transport = Some(TransportLayer {
292                tcp: None,
293                udp: None,
294            });
295            frame.payload = ipv6_packet.payload().to_vec();
296        }
297    }
298}
299
300fn parse_ipv4_udp_packet(ipv4_packet: &Ipv4Packet, frame: &mut Frame) {
301    match UdpPacket::new(ipv4_packet.payload()) {
302        Some(udp_packet) => {
303            let udp_header = UdpHeader::from_packet(&udp_packet);
304            frame.transport = Some(TransportLayer {
305                tcp: None,
306                udp: Some(udp_header),
307            });
308            frame.payload = udp_packet.payload().to_vec();
309        }
310        None => {
311            frame.transport = Some(TransportLayer {
312                tcp: None,
313                udp: None,
314            });
315            frame.payload = ipv4_packet.payload().to_vec();
316        }
317    }
318}
319
320fn parse_ipv6_udp_packet(ipv6_packet: &Ipv6Packet, frame: &mut Frame) {
321    match UdpPacket::new(ipv6_packet.payload()) {
322        Some(udp_packet) => {
323            let udp_header = UdpHeader::from_packet(&udp_packet);
324            frame.transport = Some(TransportLayer {
325                tcp: None,
326                udp: Some(udp_header),
327            });
328            frame.payload = udp_packet.payload().to_vec();
329        }
330        None => {
331            frame.transport = Some(TransportLayer {
332                tcp: None,
333                udp: None,
334            });
335            frame.payload = ipv6_packet.payload().to_vec();
336        }
337    }
338}
339
340fn parse_icmp_packet(ipv4_packet: &Ipv4Packet, frame: &mut Frame) {
341    match IcmpPacket::new(ipv4_packet.payload()) {
342        Some(icmp_packet) => {
343            let icmp_header = IcmpHeader::from_packet(&icmp_packet);
344            if let Some(ip) = &mut frame.ip {
345                ip.icmp = Some(icmp_header);
346            }
347            frame.payload = icmp_packet.payload().to_vec();
348        }
349        None => {
350            if let Some(ip) = &mut frame.ip {
351                ip.icmp = None;
352            }
353            frame.payload = ipv4_packet.payload().to_vec();
354        }
355    }
356}
357
358fn parse_icmpv6_packet(ipv6_packet: &Ipv6Packet, frame: &mut Frame) {
359    match Icmpv6Packet::new(ipv6_packet.payload()) {
360        Some(icmpv6_packet) => {
361            let icmpv6_header = Icmpv6Header::from_packet(&icmpv6_packet);
362            if let Some(ip) = &mut frame.ip {
363                ip.icmpv6 = Some(icmpv6_header);
364            }
365            frame.payload = icmpv6_packet.payload().to_vec();
366        }
367        None => {
368            if let Some(ip) = &mut frame.ip {
369                ip.icmpv6 = None;
370            }
371            frame.payload = ipv6_packet.payload().to_vec();
372        }
373    }
374}