Don't put non-unicast (IP or Ethernet) addresses into ARP cache.
Thanks @little-dude for pointing this out--it's probably a DoS bug.
This commit is contained in:
parent
b305797cb4
commit
393ebbe682
|
@ -95,6 +95,9 @@ impl<'a> SliceCache<'a> {
|
|||
|
||||
impl<'a> Cache for SliceCache<'a> {
|
||||
fn fill(&mut self, protocol_addr: &IpAddress, hardware_addr: &EthernetAddress) {
|
||||
debug_assert!(protocol_addr.is_unicast());
|
||||
debug_assert!(hardware_addr.is_unicast());
|
||||
|
||||
if let None = self.find(protocol_addr) {
|
||||
let lru_index = self.lru();
|
||||
|
||||
|
|
|
@ -137,7 +137,10 @@ impl<'a, 'b, 'c, DeviceT: Device + 'a> Interface<'a, 'b, 'c, DeviceT> {
|
|||
source_hardware_addr, source_protocol_addr,
|
||||
target_protocol_addr, ..
|
||||
} => {
|
||||
self.arp_cache.fill(&source_protocol_addr.into(), &source_hardware_addr);
|
||||
if source_protocol_addr.is_unicast() && source_hardware_addr.is_unicast() {
|
||||
self.arp_cache.fill(&source_protocol_addr.into(),
|
||||
&source_hardware_addr);
|
||||
}
|
||||
|
||||
if self.has_protocol_addr(target_protocol_addr) {
|
||||
response = Response::Arp(ArpRepr::EthernetIpv4 {
|
||||
|
@ -155,7 +158,10 @@ impl<'a, 'b, 'c, DeviceT: Device + 'a> Interface<'a, 'b, 'c, DeviceT> {
|
|||
operation: ArpOperation::Reply,
|
||||
source_hardware_addr, source_protocol_addr, ..
|
||||
} => {
|
||||
self.arp_cache.fill(&source_protocol_addr.into(), &source_hardware_addr)
|
||||
if source_protocol_addr.is_unicast() && source_hardware_addr.is_unicast() {
|
||||
self.arp_cache.fill(&source_protocol_addr.into(),
|
||||
&source_hardware_addr);
|
||||
}
|
||||
},
|
||||
|
||||
_ => return Err(Error::Unrecognized)
|
||||
|
@ -168,7 +174,10 @@ impl<'a, 'b, 'c, DeviceT: Device + 'a> Interface<'a, 'b, 'c, DeviceT> {
|
|||
let ipv4_repr = try!(Ipv4Repr::parse(&ipv4_packet));
|
||||
|
||||
// Fill the ARP cache from IP header.
|
||||
self.arp_cache.fill(&IpAddress::Ipv4(ipv4_repr.src_addr), ð_frame.src_addr());
|
||||
if ipv4_repr.src_addr.is_unicast() && eth_frame.src_addr().is_unicast() {
|
||||
self.arp_cache.fill(&IpAddress::Ipv4(ipv4_repr.src_addr),
|
||||
ð_frame.src_addr());
|
||||
}
|
||||
|
||||
match ipv4_repr {
|
||||
// Ignore IP packets not directed at us.
|
||||
|
|
|
@ -45,6 +45,12 @@ impl Address {
|
|||
&self.0
|
||||
}
|
||||
|
||||
/// Query whether the address is an unicast address.
|
||||
pub fn is_unicast(&self) -> bool {
|
||||
!(self.is_broadcast() ||
|
||||
self.is_multicast())
|
||||
}
|
||||
|
||||
/// Query whether this address is the broadcast address.
|
||||
pub fn is_broadcast(&self) -> bool {
|
||||
self.0 == [0xff; 6]
|
||||
|
|
Loading…
Reference in New Issue