nbpf_sys/
packet_info.rs

1use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
2
3use pnet::util::MacAddr;
4
5use crate::{nbpf_pkt_info_t, nbpf_pkt_info_tuple_t};
6
7pub enum IPversion {
8    IPv4,
9    IPv6,
10}
11
12impl Default for IPversion {
13    fn default() -> Self {
14        Self::IPv4
15    }
16}
17
18impl From<IPversion> for u8 {
19    fn from(value: IPversion) -> Self {
20        match value {
21            IPversion::IPv4 => 4,
22            IPversion::IPv6 => 6,
23        }
24    }
25}
26
27#[derive(Default)]
28pub struct PacketInfoBuilder {
29    /// L2
30    device_id: Option<u16>,
31    interface_id: Option<u16>,
32    dmac: Option<MacAddr>,
33    smac: Option<MacAddr>,
34    vlan_id: Option<u16>,
35    vlan_id_qinq: Option<u16>,
36    l3_eth_type: Option<u16>,
37    /// L3
38    l3_ip_version: Option<IPversion>,
39    l3_proto: Option<u8>,
40    l3_ip_tos: Option<u8>,
41    l3_ip_src: Option<IpAddr>,
42    l3_ip_dst: Option<IpAddr>,
43    /// l4
44    l4_src_port: Option<u16>,
45    l4_dst_port: Option<u16>,
46
47    /// tunnel
48    tunnel_eth_type: Option<u16>,
49    tunnel_ip_version: Option<IPversion>,
50    tunnel_l3_proto: Option<u8>,
51    tunnel_ip_tos: Option<u8>,
52    tunnel_ip_src: Option<IpAddr>,
53    tunnel_ip_dst: Option<IpAddr>,
54    tunnel_l4_src_port: Option<u16>,
55    tunnel_l4_dst_port: Option<u16>,
56
57    /// l7
58    master_l7_proto: Option<u16>,
59    l7_proto: Option<u16>,
60}
61
62impl PacketInfoBuilder {
63    pub fn new() -> Self {
64        Self::default()
65    }
66
67    pub fn with_device_id(&mut self, device_id: u16) {
68        self.device_id = Some(device_id);
69    }
70
71    /// l2
72    pub fn with_l2(&mut self, interface_id: u16, smac: MacAddr, dmac: MacAddr, eth_type: u16) {
73        self.interface_id = Some(interface_id);
74        self.smac = Some(smac);
75        self.dmac = Some(dmac);
76        self.l3_eth_type = Some(eth_type);
77    }
78
79    /// vlan
80    pub fn with_l2_vlan(&mut self, vlan_id: u16, vlan_id_qinq: u16) {
81        self.vlan_id = Some(vlan_id);
82        self.vlan_id_qinq = Some(vlan_id_qinq);
83    }
84
85    pub fn with_tunnel_l2(&mut self, eth_type: u16) {
86        self.tunnel_eth_type = Some(eth_type);
87    }
88
89    /// l3
90    pub fn with_l3(&mut self, ip_version: IPversion, proto: u8, tos: u8, src: IpAddr, dst: IpAddr) {
91        self.l3_ip_version = Some(ip_version);
92        self.l3_proto = Some(proto);
93        self.l3_ip_tos = Some(tos);
94        self.l3_ip_src = Some(src);
95        self.l3_ip_dst = Some(dst);
96    }
97
98    pub fn with_tunnel_l3(
99        &mut self,
100        ip_version: IPversion,
101        proto: u8,
102        tos: u8,
103        src: IpAddr,
104        dst: IpAddr,
105    ) {
106        self.tunnel_ip_version = Some(ip_version);
107        self.tunnel_l3_proto = Some(proto);
108        self.tunnel_ip_tos = Some(tos);
109        self.tunnel_ip_src = Some(src);
110        self.tunnel_ip_dst = Some(dst);
111    }
112
113    /// l4
114    pub fn with_l4(&mut self, src_port: u16, dst_port: u16) {
115        self.l4_src_port = Some(src_port);
116        self.l4_dst_port = Some(dst_port);
117    }
118
119    pub fn with_tunnel_l4(&mut self, src_port: u16, dst_port: u16) {
120        self.tunnel_l4_src_port = Some(src_port);
121        self.tunnel_l4_dst_port = Some(dst_port);
122    }
123
124    /// l7
125    pub fn with_l7_master_proto(&mut self, master_l7_proto: u16) {
126        self.master_l7_proto = Some(master_l7_proto);
127    }
128
129    pub fn with_l7_proto(&mut self, l7_proto: u16) {
130        self.l7_proto = Some(l7_proto);
131    }
132
133    pub fn build(self) -> PacketInfo {
134        let nbpf_pkt_info = Box::new(nbpf_pkt_info_t {
135            device_id: self.device_id.unwrap_or_default(),
136            interface_id: self.interface_id.unwrap_or_default(),
137            dmac: self.dmac.unwrap_or_default().into(),
138            smac: self.smac.unwrap_or_default().into(),
139            vlan_id: self.vlan_id.unwrap_or(0),
140            vlan_id_qinq: self.vlan_id_qinq.unwrap_or(0),
141            tuple: nbpf_pkt_info_tuple_t {
142                eth_type: self.l3_eth_type.unwrap_or(0),
143                ip_version: self.l3_ip_version.unwrap_or_default().into(),
144                l3_proto: self.l3_proto.unwrap_or_default(),
145                ip_tos: self.l3_ip_tos.unwrap_or_default(),
146                ip_src: self
147                    .l3_ip_src
148                    .unwrap_or(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)))
149                    .into(),
150                ip_dst: self
151                    .l3_ip_dst
152                    .unwrap_or(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)))
153                    .into(),
154                l4_src_port: self.l4_src_port.unwrap_or_default().to_be(),
155                l4_dst_port: self.l4_dst_port.unwrap_or_default().to_be(),
156            },
157            tunneled_tuple: nbpf_pkt_info_tuple_t {
158                eth_type: self.tunnel_eth_type.unwrap_or_default(),
159                ip_version: self.tunnel_ip_version.unwrap_or_default().into(),
160                l3_proto: self.tunnel_l3_proto.unwrap_or_default(),
161                ip_tos: self.tunnel_ip_tos.unwrap_or_default(),
162                ip_src: self
163                    .tunnel_ip_src
164                    .unwrap_or(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)))
165                    .into(),
166                ip_dst: self
167                    .tunnel_ip_dst
168                    .unwrap_or(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)))
169                    .into(),
170                l4_src_port: self.tunnel_l4_src_port.unwrap_or_default().to_be(),
171                l4_dst_port: self.tunnel_l4_dst_port.unwrap_or_default().to_be(),
172            },
173            master_l7_proto: self.master_l7_proto.unwrap_or_default(),
174            l7_proto: self.l7_proto.unwrap_or_default(),
175        });
176
177        PacketInfo {
178            ptr: Box::into_raw(nbpf_pkt_info),
179        }
180    }
181}
182
183pub struct PacketInfo {
184    ptr: *mut nbpf_pkt_info_t,
185}
186
187impl PacketInfo {
188    pub(crate) fn get_ptr(&self) -> *mut nbpf_pkt_info_t {
189        self.ptr
190    }
191}
192
193impl Drop for PacketInfo {
194    fn drop(&mut self) {
195        drop(unsafe { Box::from_raw(self.ptr) })
196    }
197}