xenet_packet_builder/
ipv4.rs1use std::net::Ipv4Addr;
2use xenet_packet::ip::IpNextLevelProtocol;
3use xenet_packet::ipv4::Ipv4Flags;
4use xenet_packet::ipv4::MutableIpv4Packet;
5use xenet_packet::ipv4::IPV4_HEADER_LEN;
6use xenet_packet::ipv4::IPV4_HEADER_LENGTH_BYTE_UNITS;
7use xenet_packet::Packet;
8
9pub(crate) fn build_ipv4_packet(
11 ipv4_packet: &mut MutableIpv4Packet,
12 src_ip: Ipv4Addr,
13 dst_ip: Ipv4Addr,
14 next_protocol: IpNextLevelProtocol,
15) {
16 ipv4_packet.set_header_length((IPV4_HEADER_LEN / IPV4_HEADER_LENGTH_BYTE_UNITS) as u8);
17 ipv4_packet.set_source(src_ip);
18 ipv4_packet.set_destination(dst_ip);
19 ipv4_packet.set_identification(rand::random::<u16>());
20 ipv4_packet.set_ttl(64);
21 ipv4_packet.set_version(4);
22 ipv4_packet.set_flags(Ipv4Flags::DontFragment);
23 match next_protocol {
24 IpNextLevelProtocol::Tcp => {
25 ipv4_packet.set_total_length(52);
26 ipv4_packet.set_next_level_protocol(IpNextLevelProtocol::Tcp);
27 }
28 IpNextLevelProtocol::Udp => {
29 ipv4_packet.set_total_length(28);
30 ipv4_packet.set_next_level_protocol(IpNextLevelProtocol::Udp);
31 }
32 IpNextLevelProtocol::Icmp => {
33 ipv4_packet.set_total_length(28);
34 ipv4_packet.set_next_level_protocol(IpNextLevelProtocol::Icmp);
35 }
36 _ => {}
37 }
38 let checksum = xenet_packet::ipv4::checksum(&ipv4_packet.to_immutable());
39 ipv4_packet.set_checksum(checksum);
40}
41
42#[derive(Clone, Debug)]
44pub struct Ipv4PacketBuilder {
45 pub src_ip: Ipv4Addr,
46 pub dst_ip: Ipv4Addr,
47 pub next_protocol: IpNextLevelProtocol,
48 pub total_length: Option<u16>,
49 pub identification: Option<u16>,
50 pub ttl: Option<u8>,
51 pub flags: Option<u8>,
52}
53
54impl Ipv4PacketBuilder {
55 pub fn new(src_ip: Ipv4Addr, dst_ip: Ipv4Addr, next_protocol: IpNextLevelProtocol) -> Self {
57 Ipv4PacketBuilder {
58 src_ip,
59 dst_ip,
60 next_protocol,
61 total_length: None,
62 identification: None,
63 ttl: None,
64 flags: None,
65 }
66 }
67 pub fn build(&self) -> Vec<u8> {
69 let mut buffer = vec![0; IPV4_HEADER_LEN];
70 let mut ipv4_packet = MutableIpv4Packet::new(&mut buffer).unwrap();
71 ipv4_packet.set_header_length((IPV4_HEADER_LEN / IPV4_HEADER_LENGTH_BYTE_UNITS) as u8);
72 ipv4_packet.set_source(self.src_ip);
73 ipv4_packet.set_destination(self.dst_ip);
74 ipv4_packet.set_identification(self.identification.unwrap_or(rand::random::<u16>()));
75 ipv4_packet.set_ttl(self.ttl.unwrap_or(64));
76 ipv4_packet.set_version(4);
77 ipv4_packet.set_next_level_protocol(self.next_protocol);
78 if let Some(flags) = self.flags {
79 match flags {
80 Ipv4Flags::DontFragment => {
81 ipv4_packet.set_flags(Ipv4Flags::DontFragment);
82 }
83 Ipv4Flags::MoreFragments => {
84 ipv4_packet.set_flags(Ipv4Flags::MoreFragments);
85 }
86 _ => {}
87 }
88 } else {
89 ipv4_packet.set_flags(Ipv4Flags::DontFragment);
90 }
91 match self.next_protocol {
92 IpNextLevelProtocol::Tcp => {
93 if let Some(total_length) = self.total_length {
94 ipv4_packet.set_total_length(total_length);
95 } else {
96 ipv4_packet.set_total_length(52);
97 }
98 }
99 IpNextLevelProtocol::Udp => {
100 if let Some(total_length) = self.total_length {
101 ipv4_packet.set_total_length(total_length);
102 } else {
103 ipv4_packet.set_total_length(28);
104 }
105 }
106 IpNextLevelProtocol::Icmp => {
107 if let Some(total_length) = self.total_length {
108 ipv4_packet.set_total_length(total_length);
109 } else {
110 ipv4_packet.set_total_length(28);
111 }
112 }
113 _ => {}
114 }
115 let checksum = xenet_packet::ipv4::checksum(&ipv4_packet.to_immutable());
116 ipv4_packet.set_checksum(checksum);
117 ipv4_packet.packet().to_vec()
118 }
119}