r_lanlib/packet/
arp_packet.rs1use derive_builder::Builder;
4use pnet::{
5 packet::{MutablePacket, arp, ethernet},
6 util,
7};
8use std::net;
9
10const PKT_ETH_SIZE: usize = ethernet::EthernetPacket::minimum_packet_size();
12const PKT_ARP_SIZE: usize = arp::ArpPacket::minimum_packet_size();
13const PKT_TOTAL_SIZE: usize = PKT_ETH_SIZE + PKT_ARP_SIZE;
14
15#[derive(Debug, Builder)]
17#[builder(setter(into))]
18pub struct ArpPacket {
19 source_ip: net::Ipv4Addr,
21 source_mac: util::MacAddr,
23 dest_ip: net::Ipv4Addr,
25}
26
27impl ArpPacket {
28 pub fn to_raw(&self) -> [u8; PKT_TOTAL_SIZE] {
32 let mut pkt_buf = [0u8; PKT_TOTAL_SIZE];
33
34 let mut pkt_eth = ethernet::MutableEthernetPacket::new(&mut pkt_buf)
36 .expect("failed to generate ethernet packet");
37
38 let mut arp_buffer = [0u8; PKT_ARP_SIZE];
39
40 let mut pkt_arp =
41 arp::MutableArpPacket::new(&mut arp_buffer).expect("failed to generate arp packet");
42
43 pkt_eth.set_destination(util::MacAddr::broadcast());
44 pkt_eth.set_source(self.source_mac);
45 pkt_eth.set_ethertype(ethernet::EtherTypes::Arp);
46
47 pkt_arp.set_hardware_type(arp::ArpHardwareTypes::Ethernet);
48 pkt_arp.set_protocol_type(ethernet::EtherTypes::Ipv4);
49 pkt_arp.set_hw_addr_len(6);
50 pkt_arp.set_proto_addr_len(4);
51 pkt_arp.set_operation(arp::ArpOperations::Request);
52 pkt_arp.set_sender_hw_addr(self.source_mac);
53 pkt_arp.set_sender_proto_addr(self.source_ip);
54 pkt_arp.set_target_hw_addr(util::MacAddr::zero());
55 pkt_arp.set_target_proto_addr(self.dest_ip);
56
57 pkt_eth.set_payload(pkt_arp.packet_mut());
58
59 pkt_buf
60 }
61}
62
63#[cfg(test)]
64#[allow(warnings)]
65#[doc(hidden)]
66pub fn create_arp_reply(
68 from_mac: util::MacAddr,
69 from_ip: net::Ipv4Addr,
70 to_mac: util::MacAddr,
71 to_ip: net::Ipv4Addr,
72 packet: &'static mut [u8; PKT_TOTAL_SIZE],
73) {
74 let mut pkt_eth =
75 ethernet::MutableEthernetPacket::new(packet).expect("failed to generate ethernet packet");
76
77 let mut arp_buffer = [0u8; PKT_ARP_SIZE];
78
79 let mut pkt_arp =
80 arp::MutableArpPacket::new(&mut arp_buffer).expect("failed to generate arp packet");
81
82 pkt_eth.set_destination(to_mac);
83 pkt_eth.set_source(from_mac);
84 pkt_eth.set_ethertype(ethernet::EtherTypes::Arp);
85
86 pkt_arp.set_hardware_type(arp::ArpHardwareTypes::Ethernet);
87 pkt_arp.set_protocol_type(ethernet::EtherTypes::Ipv4);
88 pkt_arp.set_hw_addr_len(6);
89 pkt_arp.set_proto_addr_len(4);
90 pkt_arp.set_operation(arp::ArpOperations::Reply);
91 pkt_arp.set_sender_hw_addr(from_mac);
92 pkt_arp.set_sender_proto_addr(from_ip);
93 pkt_arp.set_target_hw_addr(to_mac);
94 pkt_arp.set_target_proto_addr(to_ip);
95
96 pkt_eth.set_payload(pkt_arp.packet_mut());
97}
98
99#[cfg(test)]
100#[path = "./arp_packet_tests.rs"]
101mod tests;