Skip to content

Commit

Permalink
Add support for up to 32 NDISC options and factorize options handling.
Browse files Browse the repository at this point in the history
  • Loading branch information
progval committed May 14, 2018
1 parent 1bde6e7 commit 4bb602f
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 170 deletions.
24 changes: 14 additions & 10 deletions src/iface/ethernet.rs
Expand Up @@ -23,7 +23,7 @@ use wire::{Icmpv6Packet, Icmpv6Repr, Icmpv6ParamProblem};
#[cfg(all(feature = "socket-icmp", any(feature = "proto-ipv4", feature = "proto-ipv6")))]
use wire::IcmpRepr;
#[cfg(feature = "proto-ipv6")]
use wire::{NdiscNeighborFlags, NdiscRepr};
use wire::{NdiscNeighborFlags, NdiscRepr, NdiscOptionRepr, NdiscOptionsRepr};
#[cfg(all(feature = "proto-ipv6", feature = "socket-udp"))]
use wire::Icmpv6DstUnreachable;
#[cfg(feature = "socket-udp")]
Expand Down Expand Up @@ -856,9 +856,9 @@ impl<'b, 'c> InterfaceInner<'b, 'c> {
fn process_ndisc<'frame>(&mut self, timestamp: Instant, ip_repr: Ipv6Repr,
repr: NdiscRepr<'frame>) -> Result<Packet<'frame>> {
let packet = match repr {
NdiscRepr::NeighborAdvert { lladdr, target_addr, flags } => {
NdiscRepr::NeighborAdvert { target_addr, flags, options } => {
let ip_addr = ip_repr.src_addr.into();
match lladdr {
match options.slladdr() {
Some(lladdr) if lladdr.is_unicast() && target_addr.is_unicast() => {
if flags.contains(NdiscNeighborFlags::OVERRIDE) {
self.neighbor_cache.fill(ip_addr, lladdr, timestamp)
Expand All @@ -872,18 +872,19 @@ impl<'b, 'c> InterfaceInner<'b, 'c> {
}
Ok(Packet::None)
}
NdiscRepr::NeighborSolicit { target_addr, lladdr, .. } => {
match lladdr {
NdiscRepr::NeighborSolicit { target_addr, options, .. } => {
match options.slladdr() {
Some(lladdr) if lladdr.is_unicast() && target_addr.is_unicast() => {
self.neighbor_cache.fill(ip_repr.src_addr.into(), lladdr, timestamp)
},
_ => (),
}
if self.has_solicited_node(ip_repr.dst_addr) && self.has_ip_addr(target_addr) {
let addr_opt = [NdiscOptionRepr::SourceLinkLayerAddr(self.ethernet_addr)];
let advert = Icmpv6Repr::Ndisc(NdiscRepr::NeighborAdvert {
flags: NdiscNeighborFlags::SOLICITED,
target_addr: target_addr,
lladdr: Some(self.ethernet_addr)
options: NdiscOptionsRepr::new(addr_opt.iter()),
});
let ip_repr = Ipv6Repr {
src_addr: target_addr,
Expand Down Expand Up @@ -1294,9 +1295,10 @@ impl<'b, 'c> InterfaceInner<'b, 'c> {

let checksum_caps = self.device_capabilities.checksum.clone();

let addr_opt = NdiscOptionRepr::SourceLinkLayerAddr(self.ethernet_addr);
let solicit = Icmpv6Repr::Ndisc(NdiscRepr::NeighborSolicit {
target_addr: src_addr,
lladdr: Some(self.ethernet_addr),
options: NdiscOptionsRepr::new([addr_opt].iter()),
});

let ip_repr = IpRepr::Ipv6(Ipv6Repr {
Expand Down Expand Up @@ -1373,7 +1375,7 @@ mod test {
#[cfg(feature = "proto-ipv6")]
use wire::{Icmpv6Packet, Icmpv6Repr, Icmpv6ParamProblem};
#[cfg(feature = "proto-ipv6")]
use wire::{NdiscNeighborFlags, NdiscRepr};
use wire::{NdiscNeighborFlags, NdiscRepr, NdiscOptionRepr, NdiscOptionsRepr};

use super::Packet;

Expand Down Expand Up @@ -1765,10 +1767,11 @@ mod test {
let remote_ip_addr = Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 2);
let local_hw_addr = EthernetAddress([0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
let remote_hw_addr = EthernetAddress([0x52, 0x54, 0x00, 0x00, 0x00, 0x00]);
let addr_opt = [NdiscOptionRepr::SourceLinkLayerAddr(remote_hw_addr)];

let solicit = Icmpv6Repr::Ndisc(NdiscRepr::NeighborSolicit {
target_addr: local_ip_addr,
lladdr: Some(remote_hw_addr),
options: NdiscOptionsRepr::new(addr_opt.iter()),
});
let ip_repr = IpRepr::Ipv6(Ipv6Repr {
src_addr: remote_ip_addr,
Expand All @@ -1789,10 +1792,11 @@ mod test {
&ChecksumCapabilities::default());
}

let addr_opt = [NdiscOptionRepr::SourceLinkLayerAddr(local_hw_addr)];
let icmpv6_expected = Icmpv6Repr::Ndisc(NdiscRepr::NeighborAdvert {
flags: NdiscNeighborFlags::SOLICITED,
target_addr: local_ip_addr,
lladdr: Some(local_hw_addr)
options: NdiscOptionsRepr::new(addr_opt.iter()),
});

let ipv6_expected = Ipv6Repr {
Expand Down
7 changes: 7 additions & 0 deletions src/wire/mod.rs
Expand Up @@ -103,6 +103,8 @@ mod igmp;
mod ndisc;
#[cfg(feature = "proto-ipv6")]
mod ndiscoption;
#[cfg(feature = "proto-ipv6")]
mod ndiscoptions;
mod udp;
mod tcp;
#[cfg(feature = "proto-ipv4")]
Expand Down Expand Up @@ -186,6 +188,11 @@ pub use self::icmpv6::{RouterFlags as NdiscRouterFlags,
#[cfg(feature = "proto-ipv6")]
pub use self::ndisc::Repr as NdiscRepr;

#[cfg(feature = "proto-ipv6")]
pub use self::ndiscoptions::{NdiscOptions,
Repr as NdiscOptionsRepr,
MAX_NDISC_OPTIONS};

#[cfg(feature = "proto-ipv6")]
pub use self::ndiscoption::{NdiscOption,
Repr as NdiscOptionRepr,
Expand Down

0 comments on commit 4bb602f

Please sign in to comment.