forked from libpnet/libpnet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
arp_packet.rs
109 lines (91 loc) · 3.37 KB
/
arp_packet.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
extern crate pnet;
use std::env;
use std::io::{self, Write};
use std::net::{AddrParseError, IpAddr, Ipv4Addr};
use std::process;
use pnet::datalink::{Channel, MacAddr, NetworkInterface};
use pnet::packet::arp::{ArpHardwareTypes, ArpOperations, ArpPacket, MutableArpPacket};
use pnet::packet::ethernet::EtherTypes;
use pnet::packet::ethernet::MutableEthernetPacket;
use pnet::packet::{MutablePacket, Packet};
fn get_mac_through_arp(interface: NetworkInterface, target_ip: Ipv4Addr) -> MacAddr {
let source_ip = interface
.ips
.iter()
.find(|ip| ip.is_ipv4())
.map(|ip| match ip.ip() {
IpAddr::V4(ip) => ip,
_ => unreachable!(),
})
.unwrap();
let (mut sender, mut receiver) = match pnet::datalink::channel(&interface, Default::default()) {
Ok(Channel::Ethernet(tx, rx)) => (tx, rx),
Ok(_) => panic!("Unknown channel type"),
Err(e) => panic!("Error happened {}", e),
};
let mut ethernet_buffer = [0u8; 42];
let mut ethernet_packet = MutableEthernetPacket::new(&mut ethernet_buffer).unwrap();
ethernet_packet.set_destination(MacAddr::broadcast());
ethernet_packet.set_source(interface.mac.unwrap());
ethernet_packet.set_ethertype(EtherTypes::Arp);
let mut arp_buffer = [0u8; 28];
let mut arp_packet = MutableArpPacket::new(&mut arp_buffer).unwrap();
arp_packet.set_hardware_type(ArpHardwareTypes::Ethernet);
arp_packet.set_protocol_type(EtherTypes::Ipv4);
arp_packet.set_hw_addr_len(6);
arp_packet.set_proto_addr_len(4);
arp_packet.set_operation(ArpOperations::Request);
arp_packet.set_sender_hw_addr(interface.mac.unwrap());
arp_packet.set_sender_proto_addr(source_ip);
arp_packet.set_target_hw_addr(MacAddr::zero());
arp_packet.set_target_proto_addr(target_ip);
ethernet_packet.set_payload(arp_packet.packet_mut());
sender
.send_to(ethernet_packet.packet(), None)
.unwrap()
.unwrap();
println!("Sent ARP request");
while let buf = receiver.next().unwrap() {
let arp = ArpPacket::new(&buf[MutableEthernetPacket::minimum_packet_size()..]).unwrap();
if arp.get_sender_proto_addr() == target_ip
&& arp.get_target_hw_addr() == interface.mac.unwrap()
{
println!("Received reply");
return arp.get_sender_hw_addr();
}
}
panic!("Never reach here")
}
fn main() {
let mut args = env::args().skip(1);
let iface_name = match args.next() {
Some(n) => n,
None => {
writeln!(
io::stderr(),
"USAGE: arp_packet <NETWORK INTERFACE> <TARGET IP>"
)
.unwrap();
process::exit(1);
}
};
let target_ip: Result<Ipv4Addr, AddrParseError> = match args.next() {
Some(n) => n.parse(),
None => {
writeln!(
io::stderr(),
"USAGE: arp_packet <NETWORK INTERFACE> <TARGET IP>"
)
.unwrap();
process::exit(1);
}
};
let interfaces = pnet::datalink::interfaces();
let interface = interfaces
.into_iter()
.find(|iface| iface.name == iface_name)
.unwrap();
let _source_mac = interface.mac.unwrap();
let target_mac = get_mac_through_arp(interface, target_ip.unwrap());
println!("Target MAC address: {}", target_mac);
}