1use smoltcp::phy::ChecksumCapabilities;
2use smoltcp::wire::{
3 IpAddress, IpProtocol, Ipv4Packet, Ipv4Repr, Ipv6Packet, Ipv6Repr, TcpPacket, TcpRepr,
4 UdpPacket, UdpRepr,
5};
6
7use crate::Flow;
8
9pub(crate) fn parse_v4(rx: &[u8]) -> Option<Flow> {
10 if let Ok(pkt) = Ipv4Packet::new_checked(rx) {
11 let nocksum = ChecksumCapabilities::ignored();
12 let pkt = Ipv4Packet::new_unchecked(pkt.into_inner());
13 if let Ok(ipv4) = Ipv4Repr::parse(&pkt, &nocksum) {
14 let source_ip = IpAddress::from(ipv4.src_addr);
15 let dest_ip = IpAddress::from(ipv4.dst_addr);
16 match pkt.next_header() {
17 IpProtocol::Tcp => {
18 if let Ok(tpkt) = TcpPacket::new_checked(pkt.payload()) {
19 if let Ok(tcp) = TcpRepr::parse(&tpkt, &source_ip, &dest_ip, &nocksum) {
20 return Some(Flow {
21 source_ip,
22 dest_ip,
23 source_port: tcp.src_port,
24 dest_port: tcp.dst_port,
25 protocol: crate::TCP,
26 });
27 }
28 }
29 }
30 IpProtocol::Udp => {
31 if let Ok(upkt) = UdpPacket::new_checked(pkt.payload()) {
32 if let Ok(udp) = UdpRepr::parse(&upkt, &source_ip, &dest_ip, &nocksum) {
33 return Some(Flow {
34 source_ip,
35 dest_ip,
36 source_port: udp.src_port,
37 dest_port: udp.dst_port,
38 protocol: crate::UDP,
39 });
40 }
41 }
42 }
43 _ => {}
44 }
45 }
46 }
47 None
48}
49
50pub(crate) fn parse_v6(rx: &[u8]) -> Option<Flow> {
51 if let Ok(pkt) = Ipv6Packet::new_checked(rx) {
52 let pkt = Ipv6Packet::new_unchecked(pkt.into_inner());
53 let nocksum = ChecksumCapabilities::ignored();
54 if let Ok(ipv6) = Ipv6Repr::parse(&pkt) {
55 let source_ip = IpAddress::from(ipv6.src_addr);
56 let dest_ip = IpAddress::from(ipv6.dst_addr);
57 match pkt.next_header() {
58 IpProtocol::Tcp => {
59 if let Ok(tpkt) = TcpPacket::new_checked(pkt.payload()) {
60 if let Ok(tcp) = TcpRepr::parse(&tpkt, &source_ip, &dest_ip, &nocksum) {
61 return Some(Flow {
62 source_ip,
63 dest_ip,
64 source_port: tcp.src_port,
65 dest_port: tcp.dst_port,
66 protocol: crate::TCP,
67 });
68 }
69 }
70 }
71 IpProtocol::Udp => {
72 if let Ok(upkt) = UdpPacket::new_checked(pkt.payload()) {
73 if let Ok(udp) = UdpRepr::parse(&upkt, &source_ip, &dest_ip, &nocksum) {
74 return Some(Flow {
75 source_ip,
76 dest_ip,
77 source_port: udp.src_port,
78 dest_port: udp.dst_port,
79 protocol: crate::UDP,
80 });
81 }
82 }
83 }
84 _ => {}
85 }
86 }
87 }
88 None
89}