use std::net::Ipv4Addr;
use xenet_packet::icmp::echo_request::MutableEchoRequestPacket;
use xenet_packet::icmp::IcmpType;
use xenet_packet::icmp::ICMPV4_HEADER_LEN;
use xenet_packet::Packet;
pub(crate) fn build_icmp_echo_packet(icmp_packet: &mut MutableEchoRequestPacket) {
icmp_packet.set_icmp_type(IcmpType::EchoRequest);
icmp_packet.set_sequence_number(rand::random::<u16>());
icmp_packet.set_identifier(rand::random::<u16>());
let icmp_check_sum = xenet_packet::util::checksum(&icmp_packet.packet(), 1);
icmp_packet.set_checksum(icmp_check_sum);
}
#[derive(Clone, Debug)]
pub struct IcmpPacketBuilder {
pub src_ip: Ipv4Addr,
pub dst_ip: Ipv4Addr,
pub icmp_type: IcmpType,
pub sequence_number: Option<u16>,
pub identifier: Option<u16>,
}
impl IcmpPacketBuilder {
pub fn new(src_ip: Ipv4Addr, dst_ip: Ipv4Addr) -> IcmpPacketBuilder {
IcmpPacketBuilder {
src_ip: src_ip,
dst_ip: dst_ip,
icmp_type: IcmpType::EchoRequest,
sequence_number: None,
identifier: None,
}
}
pub fn build(&self) -> Vec<u8> {
let buffer: &mut [u8] = &mut [0u8; ICMPV4_HEADER_LEN];
let mut icmp_packet = MutableEchoRequestPacket::new(buffer).unwrap();
icmp_packet.set_icmp_type(self.icmp_type);
if let Some(sequence_number) = self.sequence_number {
icmp_packet.set_sequence_number(sequence_number);
} else {
icmp_packet.set_sequence_number(rand::random::<u16>());
}
if let Some(identifier) = self.identifier {
icmp_packet.set_identifier(identifier);
} else {
icmp_packet.set_identifier(rand::random::<u16>());
}
let icmp_check_sum = xenet_packet::util::checksum(&icmp_packet.packet(), 1);
icmp_packet.set_checksum(icmp_check_sum);
icmp_packet.packet().to_vec()
}
}