Actually commit ARP snooping.

This commit is contained in:
whitequark 2016-12-12 22:41:34 +00:00
parent 2482117682
commit c18d6bf04d
1 changed files with 14 additions and 0 deletions

View File

@ -84,11 +84,15 @@ impl<'a, DeviceT: Device, ArpCacheT: ArpCache> Interface<'a, DeviceT, ArpCacheT>
let packet = try!(ArpPacket::new(frame.payload()));
let repr = try!(ArpRepr::parse(&packet));
match repr {
// Respond to ARP requests aimed at us, and fill the ARP cache
// from all ARP requests, including gratuitous.
ArpRepr::EthernetIpv4 {
operation: ArpOperation::Request,
source_hardware_addr, source_protocol_addr,
target_protocol_addr, ..
} => {
self.arp_cache.fill(source_protocol_addr.into(), source_hardware_addr);
if self.has_protocol_addr(target_protocol_addr) {
response = Response::Arp(ArpRepr::EthernetIpv4 {
operation: ArpOperation::Reply,
@ -99,6 +103,15 @@ impl<'a, DeviceT: Device, ArpCacheT: ArpCache> Interface<'a, DeviceT, ArpCacheT>
})
}
},
// Fill the ARP cache from gratuitous ARP replies.
ArpRepr::EthernetIpv4 {
operation: ArpOperation::Reply,
source_hardware_addr, source_protocol_addr, ..
} => {
self.arp_cache.fill(source_protocol_addr.into(), source_hardware_addr)
},
_ => return Err(Error::Unrecognized)
}
},
@ -107,6 +120,7 @@ impl<'a, DeviceT: Device, ArpCacheT: ArpCache> Interface<'a, DeviceT, ArpCacheT>
match response {
Response::Nop => Ok(()),
Response::Arp(repr) => {
let tx_size = self.device.mtu();
let tx_buffer = try!(self.device.transmit(tx_size));