xenet_packet_builder/
util.rs

1use crate::icmp::build_icmp_echo_packet;
2use crate::icmpv6::build_icmpv6_echo_packet;
3use crate::ipv6::build_ipv6_packet;
4use crate::tcp::{build_tcp_packet, TCP_DEFAULT_OPTION_LEN};
5use crate::udp::build_udp_packet;
6use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
7use xenet_core::mac::MacAddr;
8use xenet_packet::arp::{MutableArpPacket, ARP_HEADER_LEN};
9use xenet_packet::ethernet::ETHERNET_HEADER_LEN;
10use xenet_packet::ethernet::{EtherType, MutableEthernetPacket};
11use xenet_packet::icmp::ICMPV4_HEADER_LEN;
12use xenet_packet::icmpv6::ICMPV6_HEADER_LEN;
13use xenet_packet::ip::IpNextLevelProtocol;
14use xenet_packet::ipv4::{MutableIpv4Packet, IPV4_HEADER_LEN};
15use xenet_packet::ipv6::{MutableIpv6Packet, IPV6_HEADER_LEN};
16use xenet_packet::tcp::{MutableTcpPacket, TCP_HEADER_LEN};
17use xenet_packet::udp::{MutableUdpPacket, UDP_HEADER_LEN};
18use xenet_packet::Packet;
19
20use crate::arp::build_arp_packet;
21use crate::ethernet::{build_ethernet_arp_packet, build_ethernet_packet};
22use crate::ipv4::build_ipv4_packet;
23
24/// Higher level packet build option.
25/// For building packet, use PacketBuilder or protocol specific packet builder.
26#[derive(Clone, Debug)]
27pub struct PacketBuildOption {
28    pub src_mac: MacAddr,
29    pub dst_mac: MacAddr,
30    pub ether_type: EtherType,
31    pub src_ip: IpAddr,
32    pub dst_ip: IpAddr,
33    pub src_port: Option<u16>,
34    pub dst_port: Option<u16>,
35    pub ip_protocol: Option<IpNextLevelProtocol>,
36    pub payload: Vec<u8>,
37    pub use_tun: bool,
38}
39
40impl PacketBuildOption {
41    /// Constructs a new PacketBuildOption.
42    pub fn new() -> Self {
43        PacketBuildOption {
44            src_mac: MacAddr::zero(),
45            dst_mac: MacAddr::zero(),
46            ether_type: EtherType::Ipv4,
47            src_ip: IpAddr::V4(Ipv4Addr::UNSPECIFIED),
48            dst_ip: IpAddr::V4(Ipv4Addr::UNSPECIFIED),
49            src_port: None,
50            dst_port: None,
51            ip_protocol: None,
52            payload: Vec::new(),
53            use_tun: false,
54        }
55    }
56}
57
58/// Build ARP Packet from PacketBuildOption.
59pub fn build_full_arp_packet(packet_option: PacketBuildOption) -> Vec<u8> {
60    let src_ip: Ipv4Addr = match packet_option.src_ip {
61        IpAddr::V4(ipv4_addr) => ipv4_addr,
62        _ => return Vec::new(),
63    };
64    let dst_ip: Ipv4Addr = match packet_option.dst_ip {
65        IpAddr::V4(ipv4_addr) => ipv4_addr,
66        _ => return Vec::new(),
67    };
68    let mut ethernet_buffer = [0u8; ETHERNET_HEADER_LEN + ARP_HEADER_LEN];
69    let mut ethernet_packet: MutableEthernetPacket =
70        MutableEthernetPacket::new(&mut ethernet_buffer).unwrap();
71    build_ethernet_arp_packet(&mut ethernet_packet, packet_option.src_mac.clone());
72    let mut arp_buffer = [0u8; ARP_HEADER_LEN];
73    let mut arp_packet = MutableArpPacket::new(&mut arp_buffer).unwrap();
74    build_arp_packet(
75        &mut arp_packet,
76        packet_option.src_mac,
77        packet_option.dst_mac,
78        src_ip,
79        dst_ip,
80    );
81    ethernet_packet.set_payload(arp_packet.packet());
82    ethernet_packet.packet().to_vec()
83}
84
85/// Build ICMP Packet from PacketBuildOption. Build full packet with ethernet and ipv4 header.
86pub fn build_full_icmp_packet(packet_option: PacketBuildOption) -> Vec<u8> {
87    let src_ip: Ipv4Addr = match packet_option.src_ip {
88        IpAddr::V4(ipv4_addr) => ipv4_addr,
89        _ => return Vec::new(),
90    };
91    let dst_ip: Ipv4Addr = match packet_option.dst_ip {
92        IpAddr::V4(ipv4_addr) => ipv4_addr,
93        _ => return Vec::new(),
94    };
95    let mut ethernet_buffer = [0u8; ETHERNET_HEADER_LEN + IPV4_HEADER_LEN + ICMPV4_HEADER_LEN];
96    let mut ethernet_packet: MutableEthernetPacket =
97        MutableEthernetPacket::new(&mut ethernet_buffer).unwrap();
98    build_ethernet_packet(
99        &mut ethernet_packet,
100        packet_option.src_mac.clone(),
101        packet_option.dst_mac.clone(),
102        packet_option.ether_type,
103    );
104    let mut ipv4_buffer = [0u8; IPV4_HEADER_LEN + ICMPV4_HEADER_LEN];
105    let mut ipv4_packet = MutableIpv4Packet::new(&mut ipv4_buffer).unwrap();
106    build_ipv4_packet(
107        &mut ipv4_packet,
108        src_ip,
109        dst_ip,
110        packet_option.ip_protocol.unwrap(),
111    );
112    let mut icmp_buffer = [0u8; ICMPV4_HEADER_LEN];
113    let mut icmp_packet =
114        xenet_packet::icmp::echo_request::MutableEchoRequestPacket::new(&mut icmp_buffer).unwrap();
115    build_icmp_echo_packet(&mut icmp_packet);
116    ipv4_packet.set_payload(icmp_packet.packet());
117    ethernet_packet.set_payload(ipv4_packet.packet());
118    if packet_option.use_tun {
119        ethernet_packet.packet()[ETHERNET_HEADER_LEN..].to_vec()
120    } else {
121        ethernet_packet.packet().to_vec()
122    }
123}
124
125/// Build ICMP Packet.
126pub fn build_min_icmp_packet() -> Vec<u8> {
127    let mut icmp_buffer = [0u8; ICMPV4_HEADER_LEN];
128    let mut icmp_packet =
129        xenet_packet::icmp::echo_request::MutableEchoRequestPacket::new(&mut icmp_buffer).unwrap();
130    build_icmp_echo_packet(&mut icmp_packet);
131    icmp_packet.packet().to_vec()
132}
133
134/// Build ICMPv6 Packet from PacketBuildOption. Build full packet with ethernet and ipv6 header.
135pub fn build_full_icmpv6_packet(packet_option: PacketBuildOption) -> Vec<u8> {
136    let src_ip: Ipv6Addr = match packet_option.src_ip {
137        IpAddr::V6(ipv6_addr) => ipv6_addr,
138        _ => return Vec::new(),
139    };
140    let dst_ip: Ipv6Addr = match packet_option.dst_ip {
141        IpAddr::V6(ipv6_addr) => ipv6_addr,
142        _ => return Vec::new(),
143    };
144    let mut ethernet_buffer = [0u8; ETHERNET_HEADER_LEN + IPV6_HEADER_LEN + ICMPV6_HEADER_LEN];
145    let mut ethernet_packet: MutableEthernetPacket =
146        MutableEthernetPacket::new(&mut ethernet_buffer).unwrap();
147    build_ethernet_packet(
148        &mut ethernet_packet,
149        packet_option.src_mac.clone(),
150        packet_option.dst_mac.clone(),
151        packet_option.ether_type,
152    );
153    let mut ipv6_buffer = [0u8; IPV6_HEADER_LEN + ICMPV6_HEADER_LEN];
154    let mut ipv6_packet = MutableIpv6Packet::new(&mut ipv6_buffer).unwrap();
155    build_ipv6_packet(
156        &mut ipv6_packet,
157        src_ip,
158        dst_ip,
159        packet_option.ip_protocol.unwrap(),
160    );
161    let mut icmpv6_buffer = [0u8; ICMPV6_HEADER_LEN];
162    let mut icmpv6_packet =
163        xenet_packet::icmpv6::echo_request::MutableEchoRequestPacket::new(&mut icmpv6_buffer)
164            .unwrap();
165    build_icmpv6_echo_packet(&mut icmpv6_packet, src_ip, dst_ip);
166    ipv6_packet.set_payload(icmpv6_packet.packet());
167    ethernet_packet.set_payload(ipv6_packet.packet());
168    if packet_option.use_tun {
169        ethernet_packet.packet()[ETHERNET_HEADER_LEN..].to_vec()
170    } else {
171        ethernet_packet.packet().to_vec()
172    }
173}
174
175/// Build ICMPv6 Packet from PacketBuildOption.
176pub fn build_min_icmpv6_packet(packet_option: PacketBuildOption) -> Vec<u8> {
177    let src_ip: Ipv6Addr = match packet_option.src_ip {
178        IpAddr::V6(ipv6_addr) => ipv6_addr,
179        _ => return Vec::new(),
180    };
181    let dst_ip: Ipv6Addr = match packet_option.dst_ip {
182        IpAddr::V6(ipv6_addr) => ipv6_addr,
183        _ => return Vec::new(),
184    };
185    let mut icmpv6_buffer = [0u8; ICMPV6_HEADER_LEN];
186    let mut icmpv6_packet =
187        xenet_packet::icmpv6::echo_request::MutableEchoRequestPacket::new(&mut icmpv6_buffer)
188            .unwrap();
189    build_icmpv6_echo_packet(&mut icmpv6_packet, src_ip, dst_ip);
190    icmpv6_packet.packet().to_vec()
191}
192
193/// Build TCP Packet from PacketBuildOption. Build full packet with Ethernet and IP header.
194pub fn build_full_tcp_syn_packet(packet_option: PacketBuildOption) -> Vec<u8> {
195    match packet_option.src_ip {
196        IpAddr::V4(src_ip) => match packet_option.dst_ip {
197            IpAddr::V4(dst_ip) => {
198                let mut ethernet_buffer = [0u8; ETHERNET_HEADER_LEN
199                    + IPV4_HEADER_LEN
200                    + TCP_HEADER_LEN
201                    + TCP_DEFAULT_OPTION_LEN];
202                let mut ethernet_packet: MutableEthernetPacket =
203                    MutableEthernetPacket::new(&mut ethernet_buffer).unwrap();
204                build_ethernet_packet(
205                    &mut ethernet_packet,
206                    packet_option.src_mac.clone(),
207                    packet_option.dst_mac.clone(),
208                    packet_option.ether_type,
209                );
210                let mut ipv4_buffer =
211                    [0u8; IPV4_HEADER_LEN + TCP_HEADER_LEN + TCP_DEFAULT_OPTION_LEN];
212                let mut ipv4_packet = MutableIpv4Packet::new(&mut ipv4_buffer).unwrap();
213                build_ipv4_packet(
214                    &mut ipv4_packet,
215                    src_ip,
216                    dst_ip,
217                    packet_option.ip_protocol.unwrap(),
218                );
219                let mut tcp_buffer = [0u8; TCP_HEADER_LEN + TCP_DEFAULT_OPTION_LEN];
220                let mut tcp_packet = MutableTcpPacket::new(&mut tcp_buffer).unwrap();
221                build_tcp_packet(
222                    &mut tcp_packet,
223                    packet_option.src_ip,
224                    packet_option.src_port.unwrap(),
225                    packet_option.dst_ip,
226                    packet_option.dst_port.unwrap(),
227                );
228                ipv4_packet.set_payload(tcp_packet.packet());
229                ethernet_packet.set_payload(ipv4_packet.packet());
230                if packet_option.use_tun {
231                    ethernet_packet.packet()[ETHERNET_HEADER_LEN..].to_vec()
232                } else {
233                    ethernet_packet.packet().to_vec()
234                }
235            }
236            IpAddr::V6(_) => return Vec::new(),
237        },
238        IpAddr::V6(src_ip) => match packet_option.dst_ip {
239            IpAddr::V4(_) => return Vec::new(),
240            IpAddr::V6(dst_ip) => {
241                let mut ethernet_buffer = [0u8; ETHERNET_HEADER_LEN
242                    + IPV6_HEADER_LEN
243                    + TCP_HEADER_LEN
244                    + TCP_DEFAULT_OPTION_LEN];
245                let mut ethernet_packet: MutableEthernetPacket =
246                    MutableEthernetPacket::new(&mut ethernet_buffer).unwrap();
247                build_ethernet_packet(
248                    &mut ethernet_packet,
249                    packet_option.src_mac.clone(),
250                    packet_option.dst_mac.clone(),
251                    packet_option.ether_type,
252                );
253                let mut ipv6_buffer =
254                    [0u8; IPV6_HEADER_LEN + TCP_HEADER_LEN + TCP_DEFAULT_OPTION_LEN];
255                let mut ipv6_packet = MutableIpv6Packet::new(&mut ipv6_buffer).unwrap();
256                build_ipv6_packet(
257                    &mut ipv6_packet,
258                    src_ip,
259                    dst_ip,
260                    packet_option.ip_protocol.unwrap(),
261                );
262                let mut tcp_buffer = [0u8; TCP_HEADER_LEN + TCP_DEFAULT_OPTION_LEN];
263                let mut tcp_packet = MutableTcpPacket::new(&mut tcp_buffer).unwrap();
264                build_tcp_packet(
265                    &mut tcp_packet,
266                    packet_option.src_ip,
267                    packet_option.src_port.unwrap(),
268                    packet_option.dst_ip,
269                    packet_option.dst_port.unwrap(),
270                );
271                ipv6_packet.set_payload(tcp_packet.packet());
272                ethernet_packet.set_payload(ipv6_packet.packet());
273                if packet_option.use_tun {
274                    ethernet_packet.packet()[ETHERNET_HEADER_LEN..].to_vec()
275                } else {
276                    ethernet_packet.packet().to_vec()
277                }
278            }
279        },
280    }
281}
282
283/// Build TCP Packet from PacketBuildOption.
284pub fn build_min_tcp_syn_packet(packet_option: PacketBuildOption) -> Vec<u8> {
285    let mut tcp_buffer = [0u8; TCP_HEADER_LEN + TCP_DEFAULT_OPTION_LEN];
286    let mut tcp_packet = MutableTcpPacket::new(&mut tcp_buffer).unwrap();
287    build_tcp_packet(
288        &mut tcp_packet,
289        packet_option.src_ip,
290        packet_option.src_port.unwrap(),
291        packet_option.dst_ip,
292        packet_option.dst_port.unwrap(),
293    );
294    tcp_packet.packet().to_vec()
295}
296
297/// Build UDP Packet from PacketBuildOption. Build full packet with Ethernet and IP header.
298pub fn build_full_udp_packet(packet_option: PacketBuildOption) -> Vec<u8> {
299    match packet_option.src_ip {
300        IpAddr::V4(src_ip) => match packet_option.dst_ip {
301            IpAddr::V4(dst_ip) => {
302                let mut ethernet_buffer =
303                    [0u8; ETHERNET_HEADER_LEN + IPV4_HEADER_LEN + UDP_HEADER_LEN];
304                let mut ethernet_packet: MutableEthernetPacket =
305                    MutableEthernetPacket::new(&mut ethernet_buffer).unwrap();
306                build_ethernet_packet(
307                    &mut ethernet_packet,
308                    packet_option.src_mac.clone(),
309                    packet_option.dst_mac.clone(),
310                    packet_option.ether_type,
311                );
312                let mut ipv4_buffer = [0u8; IPV4_HEADER_LEN + UDP_HEADER_LEN];
313                let mut ipv4_packet = MutableIpv4Packet::new(&mut ipv4_buffer).unwrap();
314                build_ipv4_packet(
315                    &mut ipv4_packet,
316                    src_ip,
317                    dst_ip,
318                    packet_option.ip_protocol.unwrap(),
319                );
320                let mut udp_buffer = [0u8; UDP_HEADER_LEN];
321                let mut udp_packet = MutableUdpPacket::new(&mut udp_buffer).unwrap();
322                build_udp_packet(
323                    &mut udp_packet,
324                    packet_option.src_ip,
325                    packet_option.src_port.unwrap(),
326                    packet_option.dst_ip,
327                    packet_option.dst_port.unwrap(),
328                );
329                ipv4_packet.set_payload(udp_packet.packet());
330                ethernet_packet.set_payload(ipv4_packet.packet());
331                if packet_option.use_tun {
332                    ethernet_packet.packet()[ETHERNET_HEADER_LEN..].to_vec()
333                } else {
334                    ethernet_packet.packet().to_vec()
335                }
336            }
337            IpAddr::V6(_) => return Vec::new(),
338        },
339        IpAddr::V6(src_ip) => match packet_option.dst_ip {
340            IpAddr::V4(_) => return Vec::new(),
341            IpAddr::V6(dst_ip) => {
342                let mut ethernet_buffer =
343                    [0u8; ETHERNET_HEADER_LEN + IPV6_HEADER_LEN + UDP_HEADER_LEN];
344                let mut ethernet_packet: MutableEthernetPacket =
345                    MutableEthernetPacket::new(&mut ethernet_buffer).unwrap();
346                build_ethernet_packet(
347                    &mut ethernet_packet,
348                    packet_option.src_mac.clone(),
349                    packet_option.dst_mac.clone(),
350                    packet_option.ether_type,
351                );
352                let mut ipv6_buffer = [0u8; IPV6_HEADER_LEN + UDP_HEADER_LEN];
353                let mut ipv6_packet = MutableIpv6Packet::new(&mut ipv6_buffer).unwrap();
354                build_ipv6_packet(
355                    &mut ipv6_packet,
356                    src_ip,
357                    dst_ip,
358                    packet_option.ip_protocol.unwrap(),
359                );
360                let mut udp_buffer = [0u8; UDP_HEADER_LEN];
361                let mut udp_packet = MutableUdpPacket::new(&mut udp_buffer).unwrap();
362                build_udp_packet(
363                    &mut udp_packet,
364                    packet_option.src_ip,
365                    packet_option.src_port.unwrap(),
366                    packet_option.dst_ip,
367                    packet_option.dst_port.unwrap(),
368                );
369                ipv6_packet.set_payload(udp_packet.packet());
370                ethernet_packet.set_payload(ipv6_packet.packet());
371                if packet_option.use_tun {
372                    ethernet_packet.packet()[ETHERNET_HEADER_LEN..].to_vec()
373                } else {
374                    ethernet_packet.packet().to_vec()
375                }
376            }
377        },
378    }
379}
380
381/// Build UDP Packet from PacketBuildOption.
382pub fn build_min_udp_packet(packet_option: PacketBuildOption) -> Vec<u8> {
383    let mut udp_buffer = [0u8; UDP_HEADER_LEN];
384    let mut udp_packet = MutableUdpPacket::new(&mut udp_buffer).unwrap();
385    build_udp_packet(
386        &mut udp_packet,
387        packet_option.src_ip,
388        packet_option.src_port.unwrap(),
389        packet_option.dst_ip,
390        packet_option.dst_port.unwrap(),
391    );
392    udp_packet.packet().to_vec()
393}