xenet_packet_builder/
icmp.rs

1use std::net::Ipv4Addr;
2use xenet_packet::icmp::echo_request::MutableEchoRequestPacket;
3use xenet_packet::icmp::IcmpType;
4use xenet_packet::icmp::ICMPV4_HEADER_LEN;
5use xenet_packet::Packet;
6
7/// Build ICMP packet.
8pub(crate) fn build_icmp_echo_packet(icmp_packet: &mut MutableEchoRequestPacket) {
9    icmp_packet.set_icmp_type(IcmpType::EchoRequest);
10    icmp_packet.set_sequence_number(rand::random::<u16>());
11    icmp_packet.set_identifier(rand::random::<u16>());
12    let icmp_check_sum = xenet_packet::util::checksum(&icmp_packet.packet(), 1);
13    icmp_packet.set_checksum(icmp_check_sum);
14}
15
16/// ICMP Packet Builder.
17#[derive(Clone, Debug)]
18pub struct IcmpPacketBuilder {
19    /// Source IPv4 address.
20    pub src_ip: Ipv4Addr,
21    /// Destination IPv4 address.
22    pub dst_ip: Ipv4Addr,
23    /// ICMP type.
24    pub icmp_type: IcmpType,
25    /// ICMP sequence number.
26    pub sequence_number: Option<u16>,
27    /// ICMP identifier.
28    pub identifier: Option<u16>,
29}
30
31impl IcmpPacketBuilder {
32    /// Constructs a new IcmpPacketBuilder.
33    pub fn new(src_ip: Ipv4Addr, dst_ip: Ipv4Addr) -> IcmpPacketBuilder {
34        IcmpPacketBuilder {
35            src_ip: src_ip,
36            dst_ip: dst_ip,
37            icmp_type: IcmpType::EchoRequest,
38            sequence_number: None,
39            identifier: None,
40        }
41    }
42    /// Build ICMP packet and return bytes.
43    pub fn build(&self) -> Vec<u8> {
44        let buffer: &mut [u8] = &mut [0u8; ICMPV4_HEADER_LEN];
45        let mut icmp_packet = MutableEchoRequestPacket::new(buffer).unwrap();
46        icmp_packet.set_icmp_type(self.icmp_type);
47        if let Some(sequence_number) = self.sequence_number {
48            icmp_packet.set_sequence_number(sequence_number);
49        } else {
50            icmp_packet.set_sequence_number(rand::random::<u16>());
51        }
52        if let Some(identifier) = self.identifier {
53            icmp_packet.set_identifier(identifier);
54        } else {
55            icmp_packet.set_identifier(rand::random::<u16>());
56        }
57        let icmp_check_sum = xenet_packet::util::checksum(&icmp_packet.packet(), 1);
58        icmp_packet.set_checksum(icmp_check_sum);
59        icmp_packet.packet().to_vec()
60    }
61}