From eeab2460b4ea3987d9137e169c683789a7b4ca68 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 15 Oct 2020 13:16:58 +0200 Subject: [PATCH] Add medium-ip, medium-ethernet feature flags. --- .travis.yml | 30 +++--- Cargo.toml | 5 +- fuzz/fuzz_targets/tcp_headers.rs | 4 +- src/iface/interface.rs | 156 ++++++++++++++++++------------- src/iface/mod.rs | 10 +- src/lib.rs | 4 +- src/parsers.rs | 10 +- src/phy/mod.rs | 13 ++- src/socket/icmp.rs | 92 +++++++++--------- src/socket/tcp.rs | 15 ++- src/wire/icmpv6.rs | 10 +- src/wire/mod.rs | 16 ++-- 12 files changed, 198 insertions(+), 167 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1490e63c9..1f82e9145 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,35 +12,41 @@ matrix: env: FEATURES='default' MODE='test' ### Test select feature permutations, chosen to be as orthogonal as possible - rust: nightly - env: FEATURES='std ethernet phy-raw_socket proto-ipv6 socket-udp' MODE='test' + env: FEATURES='std medium-ethernet phy-raw_socket proto-ipv6 socket-udp' MODE='test' - rust: nightly - env: FEATURES='std ethernet phy-tap_interface proto-ipv6 socket-udp' MODE='test' + env: FEATURES='std medium-ethernet phy-tap_interface proto-ipv6 socket-udp' MODE='test' - rust: nightly - env: FEATURES='std ethernet proto-ipv4 proto-igmp socket-raw' MODE='test' + env: FEATURES='std medium-ethernet proto-ipv4 proto-igmp socket-raw' MODE='test' - rust: nightly - env: FEATURES='std ethernet proto-ipv4 socket-udp socket-tcp' MODE='test' + env: FEATURES='std medium-ethernet proto-ipv4 socket-udp socket-tcp' MODE='test' - rust: nightly - env: FEATURES='std ethernet proto-ipv4 proto-dhcpv4 socket-udp' MODE='test' + env: FEATURES='std medium-ethernet proto-ipv4 proto-dhcpv4 socket-udp' MODE='test' - rust: nightly - env: FEATURES='std ethernet proto-ipv6 socket-udp' MODE='test' + env: FEATURES='std medium-ethernet proto-ipv6 socket-udp' MODE='test' - rust: nightly - env: FEATURES='std ethernet proto-ipv6 socket-tcp' MODE='test' + env: FEATURES='std medium-ethernet proto-ipv6 socket-tcp' MODE='test' - rust: nightly - env: FEATURES='std ethernet proto-ipv4 socket-icmp socket-tcp' MODE='test' + env: FEATURES='std medium-ethernet proto-ipv4 socket-icmp socket-tcp' MODE='test' - rust: nightly - env: FEATURES='std ethernet proto-ipv6 socket-icmp socket-tcp' MODE='test' + env: FEATURES='std medium-ethernet proto-ipv6 socket-icmp socket-tcp' MODE='test' ### Test select feature permutations, chosen to be as aggressive as possible - rust: nightly - env: FEATURES='ethernet proto-ipv4 proto-ipv6 socket-raw socket-udp socket-tcp socket-icmp std' + env: FEATURES='medium-ethernet medium-ip proto-ipv4 proto-ipv6 proto-dhcpv4 proto-igmp socket-raw socket-udp socket-tcp socket-icmp std' MODE='test' - rust: nightly - env: FEATURES='ethernet proto-ipv4 proto-ipv6 socket-raw socket-udp socket-tcp socket-icmp alloc' + env: FEATURES='medium-ip proto-ipv4 proto-ipv6 proto-igmp socket-raw socket-udp socket-tcp socket-icmp std' + MODE='test' + - rust: nightly + env: FEATURES='medium-ethernet proto-ipv4 proto-ipv6 socket-raw socket-udp socket-tcp socket-icmp std' + MODE='test' + - rust: nightly + env: FEATURES='medium-ethernet proto-ipv4 proto-ipv6 socket-raw socket-udp socket-tcp socket-icmp alloc' MODE='test' - rust: nightly env: FEATURES='proto-ipv4 proto-ipv6 socket-raw socket-udp socket-tcp socket-icmp alloc' MODE='test' - rust: nightly - env: FEATURES='ethernet proto-ipv4 proto-ipv6 proto-igmp proto-dhcpv4 socket-raw socket-udp socket-tcp socket-icmp' + env: FEATURES='medium-ethernet proto-ipv4 proto-ipv6 proto-igmp proto-dhcpv4 socket-raw socket-udp socket-tcp socket-icmp' MODE='build' - rust: nightly env: MODE='fuzz run' ARGS='packet_parser -- -max_len=1536 -max_total_time=30' diff --git a/Cargo.toml b/Cargo.toml index e0b1ed5b3..1fb6b2a88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,8 @@ url = "1.0" std = ["managed/std"] alloc = ["managed/alloc"] verbose = [] -ethernet = [] +"medium-ethernet" = [] +"medium-ip" = [] "phy-raw_socket" = ["std", "libc"] "phy-tap_interface" = ["std", "libc"] "phy-tun_interface" = ["std", "libc"] @@ -45,7 +46,7 @@ ethernet = [] "socket-icmp" = [] default = [ "std", "log", # needed for `cargo test --no-default-features --features default` :/ - "ethernet", + "medium-ethernet", "medium-ip", "phy-raw_socket", "phy-tap_interface", "phy-tun_interface", "proto-ipv4", "proto-igmp", "proto-ipv6", "socket-raw", "socket-icmp", "socket-udp", "socket-tcp" diff --git a/fuzz/fuzz_targets/tcp_headers.rs b/fuzz/fuzz_targets/tcp_headers.rs index ca82723de..aec7a2523 100644 --- a/fuzz/fuzz_targets/tcp_headers.rs +++ b/fuzz/fuzz_targets/tcp_headers.rs @@ -6,7 +6,7 @@ use std as core; extern crate getopts; use core::cmp; -use smoltcp::phy::Loopback; +use smoltcp::phy::{Loopback, Medium}; use smoltcp::wire::{EthernetAddress, EthernetFrame, EthernetProtocol}; use smoltcp::wire::{IpAddress, IpCidr, Ipv4Packet, Ipv6Packet, TcpPacket}; use smoltcp::iface::{NeighborCache, InterfaceBuilder}; @@ -118,7 +118,7 @@ fuzz_target!(|data: &[u8]| { utils::add_middleware_options(&mut opts, &mut free); let mut matches = utils::parse_options(&opts, free); - let device = utils::parse_middleware_options(&mut matches, Loopback::new(), + let device = utils::parse_middleware_options(&mut matches, Loopback::new(Medium::Ethernet), /*loopback=*/true); smoltcp::phy::FuzzInjector::new(device, diff --git a/src/iface/interface.rs b/src/iface/interface.rs index f49c4302d..c5499d972 100644 --- a/src/iface/interface.rs +++ b/src/iface/interface.rs @@ -4,22 +4,24 @@ use core::cmp; use managed::{ManagedSlice, ManagedMap}; -#[cfg(not(all(feature = "ethernet", feature = "proto-igmp")))] +#[cfg(not(all(feature = "medium-ethernet", feature = "proto-igmp")))] use core::marker::PhantomData; use {Error, Result}; use phy::{Device, DeviceCapabilities, RxToken, TxToken, Medium}; use time::{Duration, Instant}; -#[cfg(feature = "ethernet")] +#[cfg(feature = "medium-ethernet")] use wire::pretty_print::PrettyPrinter; -#[cfg(feature = "ethernet")] +#[cfg(feature = "medium-ethernet")] use wire::{EthernetAddress, EthernetProtocol, EthernetFrame}; -use wire::{IpAddress, IpProtocol, IpRepr, IpCidr, IpVersion}; +use wire::{IpAddress, IpProtocol, IpRepr, IpCidr}; +#[cfg(feature = "medium-ip")] +use wire::IpVersion; #[cfg(feature = "proto-ipv6")] use wire::{Ipv6Address, Ipv6Packet, Ipv6Repr, IPV6_MIN_MTU}; #[cfg(feature = "proto-ipv4")] use wire::{Ipv4Address, Ipv4Packet, Ipv4Repr, IPV4_MIN_MTU}; -#[cfg(all(feature = "ethernet", feature = "proto-ipv4"))] +#[cfg(all(feature = "medium-ethernet", feature = "proto-ipv4"))] use wire::{ArpPacket, ArpRepr, ArpOperation}; #[cfg(feature = "proto-ipv4")] use wire::{Icmpv4Packet, Icmpv4Repr, Icmpv4DstUnreachable}; @@ -33,7 +35,7 @@ use wire::IcmpRepr; use wire::{Ipv6HopByHopHeader, Ipv6HopByHopRepr}; #[cfg(feature = "proto-ipv6")] use wire::{Ipv6OptionRepr, Ipv6OptionFailureType}; -#[cfg(all(feature = "ethernet", feature = "proto-ipv6"))] +#[cfg(all(feature = "medium-ethernet", feature = "proto-ipv6"))] use wire::{NdiscNeighborFlags, NdiscRepr}; #[cfg(all(feature = "proto-ipv6", feature = "socket-udp"))] use wire::Icmpv6DstUnreachable; @@ -51,7 +53,7 @@ use socket::IcmpSocket; use socket::UdpSocket; #[cfg(feature = "socket-tcp")] use socket::TcpSocket; -#[cfg(feature = "ethernet")] +#[cfg(feature = "medium-ethernet")] use super::{NeighborCache, NeighborAnswer}; use super::Routes; @@ -73,11 +75,11 @@ pub struct Interface<'b, 'c, 'e, DeviceT: for<'d> Device<'d>> { /// methods on the `Interface` in this time (since its `device` field is borrowed /// exclusively). However, it is still possible to call methods on its `inner` field. struct InterfaceInner<'b, 'c, 'e> { - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] neighbor_cache: Option>, - #[cfg(not(feature = "ethernet"))] + #[cfg(not(feature = "medium-ethernet"))] _neighbor_cache: PhantomData<&'b ()>, - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] ethernet_addr: Option, ip_addrs: ManagedSlice<'c, IpCidr>, #[cfg(feature = "proto-ipv4")] @@ -96,11 +98,11 @@ struct InterfaceInner<'b, 'c, 'e> { /// A builder structure used for creating a network interface. pub struct InterfaceBuilder <'b, 'c, 'e, DeviceT: for<'d> Device<'d>> { device: DeviceT, - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] ethernet_addr: Option, - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] neighbor_cache: Option>, - #[cfg(not(feature = "ethernet"))] + #[cfg(not(feature = "medium-ethernet"))] _neighbor_cache: PhantomData<&'b ()>, ip_addrs: ManagedSlice<'c, IpCidr>, #[cfg(feature = "proto-ipv4")] @@ -117,7 +119,7 @@ impl<'b, 'c, 'e, DeviceT> InterfaceBuilder<'b, 'c, 'e, DeviceT> where DeviceT: for<'d> Device<'d> { /// Create a builder used for creating a network interface using the /// given device and address. - #[cfg_attr(feature = "ethernet", doc = r##" + #[cfg_attr(feature = "medium-ethernet", doc = r##" # Examples ``` @@ -144,11 +146,11 @@ impl<'b, 'c, 'e, DeviceT> InterfaceBuilder<'b, 'c, 'e, DeviceT> pub fn new(device: DeviceT) -> Self { InterfaceBuilder { device: device, - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] ethernet_addr: None, - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] neighbor_cache: None, - #[cfg(not(feature = "ethernet"))] + #[cfg(not(feature = "medium-ethernet"))] _neighbor_cache: PhantomData, ip_addrs: ManagedSlice::Borrowed(&mut []), #[cfg(feature = "proto-ipv4")] @@ -168,7 +170,7 @@ impl<'b, 'c, 'e, DeviceT> InterfaceBuilder<'b, 'c, 'e, DeviceT> /// This function panics if the address is not unicast. /// /// [ethernet_addr]: struct.Interface.html#method.ethernet_addr - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] pub fn ethernet_addr(mut self, addr: EthernetAddress) -> Self { InterfaceInner::check_ethernet_addr(&addr); self.ethernet_addr = Some(addr); @@ -240,7 +242,7 @@ impl<'b, 'c, 'e, DeviceT> InterfaceBuilder<'b, 'c, 'e, DeviceT> } /// Set the Neighbor Cache the interface will use. - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] pub fn neighbor_cache(mut self, neighbor_cache: NeighborCache<'b>) -> Self { self.neighbor_cache = Some(neighbor_cache); self @@ -260,37 +262,33 @@ impl<'b, 'c, 'e, DeviceT> InterfaceBuilder<'b, 'c, 'e, DeviceT> pub fn finalize(self) -> Interface<'b, 'c, 'e, DeviceT> { let device_capabilities = self.device.capabilities(); - #[cfg(feature = "ethernet")] - let mut ethernet_addr = None; - #[cfg(feature = "ethernet")] - let mut neighbor_cache = None; - match device_capabilities.medium { - #[cfg(feature = "ethernet")] - Medium::Ethernet => { - ethernet_addr = Some(self.ethernet_addr.expect("ethernet_addr required option was not set")); - neighbor_cache = Some(self.neighbor_cache.expect("neighbor_cache required option was not set")); - } + #[cfg(feature = "medium-ethernet")] + let (ethernet_addr, neighbor_cache) = match device_capabilities.medium { + Medium::Ethernet => ( + Some(self.ethernet_addr.expect("ethernet_addr required option was not set")), + Some(self.neighbor_cache.expect("neighbor_cache required option was not set")) + ), + #[cfg(feature = "medium-ip")] Medium::Ip => { - #[cfg(feature = "ethernet")] assert!(self.ethernet_addr.is_none(), "ethernet_addr is set, but device medium is IP"); - #[cfg(feature = "ethernet")] assert!(self.neighbor_cache.is_none(), "neighbor_cache is set, but device medium is IP"); + (None, None) } - } + }; Interface { device: self.device, inner: InterfaceInner { - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] ethernet_addr, ip_addrs: self.ip_addrs, #[cfg(feature = "proto-ipv4")] any_ip: self.any_ip, routes: self.routes, device_capabilities, - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] neighbor_cache, - #[cfg(not(feature = "ethernet"))] + #[cfg(not(feature = "medium-ethernet"))] _neighbor_cache: PhantomData, #[cfg(feature = "proto-igmp")] ipv4_multicast_groups: self.ipv4_multicast_groups, @@ -304,7 +302,7 @@ impl<'b, 'c, 'e, DeviceT> InterfaceBuilder<'b, 'c, 'e, DeviceT> } #[derive(Debug, PartialEq)] -#[cfg(feature = "ethernet")] +#[cfg(feature = "medium-ethernet")] enum EthernetPacket<'a> { #[cfg(feature = "proto-ipv4")] Arp(ArpRepr), @@ -432,7 +430,7 @@ impl<'b, 'c, 'e, DeviceT> Interface<'b, 'c, 'e, DeviceT> /// # Panics /// This function panics if if the interface's medium is not Ethernet. - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] pub fn ethernet_addr(&self) -> EthernetAddress { self.inner.ethernet_addr.unwrap() } @@ -442,7 +440,7 @@ impl<'b, 'c, 'e, DeviceT> Interface<'b, 'c, 'e, DeviceT> /// # Panics /// This function panics if the address is not unicast, or if the /// interface's medium is not Ethernet. - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] pub fn set_ethernet_addr(&mut self, addr: EthernetAddress) { assert!(self.device.capabilities().medium == Medium::Ethernet); InterfaceInner::check_ethernet_addr(&addr); @@ -652,7 +650,7 @@ impl<'b, 'c, 'e, DeviceT> Interface<'b, 'c, 'e, DeviceT> }; rx_token.consume(timestamp, |frame| { match inner.device_capabilities.medium { - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] Medium::Ethernet => { inner.process_ethernet(sockets, timestamp, &frame).map_err(|err| { net_debug!("cannot process ingress packet: {}", err); @@ -672,6 +670,7 @@ impl<'b, 'c, 'e, DeviceT> Interface<'b, 'c, 'e, DeviceT> } }) } + #[cfg(feature = "medium-ip")] Medium::Ip => { inner.process_ip(sockets, timestamp, &frame).map_err(|err| { net_debug!("cannot process ingress packet: {}", err); @@ -700,10 +699,10 @@ impl<'b, 'c, 'e, DeviceT> Interface<'b, 'c, 'e, DeviceT> fn socket_egress(&mut self, sockets: &mut SocketSet, timestamp: Instant) -> Result { let mut caps = self.device.capabilities(); match caps.medium { - #[cfg(feature = "ethernet")] - Medium::Ethernet => - caps.max_transmission_unit -= EthernetFrame::<&[u8]>::header_len(), - _ => {} + #[cfg(feature = "medium-ethernet")] + Medium::Ethernet => caps.max_transmission_unit -= EthernetFrame::<&[u8]>::header_len(), + #[cfg(feature = "medium-ip")] + Medium::Ip => {} } let mut emitted_any = false; @@ -735,7 +734,7 @@ impl<'b, 'c, 'e, DeviceT> Interface<'b, 'c, 'e, DeviceT> respond!(IpPacket::Raw(response))), #[cfg(all(feature = "socket-icmp", any(feature = "proto-ipv4", feature = "proto-ipv6")))] Socket::Icmp(ref mut socket) => - socket.dispatch(&caps, |response| { + socket.dispatch(|response| { match response { #[cfg(feature = "proto-ipv4")] (IpRepr::Ipv4(ipv4_repr), IcmpRepr::Ipv4(icmpv4_repr)) => @@ -752,7 +751,7 @@ impl<'b, 'c, 'e, DeviceT> Interface<'b, 'c, 'e, DeviceT> respond!(IpPacket::Udp(response))), #[cfg(feature = "socket-tcp")] Socket::Tcp(ref mut socket) => - socket.dispatch(timestamp, &caps, |response| + socket.dispatch(timestamp, caps.max_transmission_unit, |response| respond!(IpPacket::Tcp(response))), Socket::__Nonexhaustive(_) => unreachable!() }; @@ -830,7 +829,7 @@ impl<'b, 'c, 'e, DeviceT> Interface<'b, 'c, 'e, DeviceT> } impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> { - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] fn check_ethernet_addr(addr: &EthernetAddress) { if addr.is_multicast() { panic!("Ethernet address {} is not unicast", addr) @@ -897,7 +896,7 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> { } } - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] fn process_ethernet<'frame, T: AsRef<[u8]>> (&mut self, sockets: &mut SocketSet, timestamp: Instant, frame: &'frame T) -> Result>> @@ -948,6 +947,7 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> { } } + #[cfg(feature = "medium-ip")] fn process_ip<'frame, T: AsRef<[u8]>> (&mut self, sockets: &mut SocketSet, timestamp: Instant, ip_payload: &'frame T) -> Result>> @@ -968,7 +968,7 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> { } } - #[cfg(all(feature = "ethernet", feature = "proto-ipv4"))] + #[cfg(all(feature = "medium-ethernet", feature = "proto-ipv4"))] fn process_arp<'frame, T: AsRef<[u8]>> (&mut self, timestamp: Instant, eth_frame: &EthernetFrame<&'frame T>) -> Result>> @@ -1270,7 +1270,7 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> { Icmpv6Repr::EchoReply { .. } => Ok(None), // Forward any NDISC packets to the ndisc packet handler - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] Icmpv6Repr::Ndisc(repr) if ip_repr.hop_limit() == 0xff => match ip_repr { IpRepr::Ipv6(ipv6_repr) => self.process_ndisc(_timestamp, ipv6_repr, repr), _ => Ok(None) @@ -1286,7 +1286,7 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> { } } - #[cfg(all(feature = "ethernet", feature = "proto-ipv6"))] + #[cfg(all(feature = "medium-ethernet", feature = "proto-ipv6"))] fn process_ndisc<'frame>(&mut self, timestamp: Instant, ip_repr: Ipv6Repr, repr: NdiscRepr<'frame>) -> Result>> { match repr { @@ -1567,7 +1567,7 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> { } } - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] fn dispatch(&mut self, tx_token: Tx, timestamp: Instant, packet: EthernetPacket) -> Result<()> where Tx: TxToken @@ -1595,7 +1595,7 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> { } } - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] fn dispatch_ethernet(&mut self, tx_token: Tx, timestamp: Instant, buffer_len: usize, f: F) -> Result<()> where Tx: TxToken, F: FnOnce(EthernetFrame<&mut [u8]>) @@ -1636,10 +1636,11 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> { match self.route(addr, timestamp) { Ok(_routed_addr) => { match self.device_capabilities.medium { - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] Medium::Ethernet => self.neighbor_cache.as_ref().unwrap() .lookup(&_routed_addr, timestamp) .found(), + #[cfg(feature = "medium-ip")] Medium::Ip => true, } } @@ -1647,7 +1648,7 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> { } } - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] fn lookup_hardware_addr(&mut self, tx_token: Tx, timestamp: Instant, src_addr: &IpAddress, dst_addr: &IpAddress) -> Result<(EthernetAddress, Tx)> @@ -1755,7 +1756,7 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> { let caps = self.device_capabilities.clone(); match self.device_capabilities.medium { - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] Medium::Ethernet => { let (dst_hardware_addr, tx_token) = self.lookup_hardware_addr(tx_token, timestamp, @@ -1777,6 +1778,7 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> { packet.emit_payload(ip_repr, payload, &caps); }) } + #[cfg(feature = "medium-ip")] Medium::Ip => { let tx_len = ip_repr.total_len(); tx_token.consume(timestamp, tx_len, |mut tx_buffer| { @@ -1837,7 +1839,7 @@ mod test { use {Result, Error}; use super::InterfaceBuilder; - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] use iface::NeighborCache; use iface::Interface; use phy::{self, Loopback, ChecksumCapabilities}; @@ -1846,9 +1848,9 @@ mod test { use phy::{Device, RxToken, TxToken}; use time::Instant; use socket::SocketSet; - #[cfg(all(feature = "ethernet", feature = "proto-ipv4"))] + #[cfg(all(feature = "medium-ethernet", feature = "proto-ipv4"))] use wire::{ArpOperation, ArpPacket, ArpRepr}; - #[cfg(all(feature = "ethernet"))] + #[cfg(all(feature = "medium-ethernet"))] use wire::{EthernetAddress, EthernetFrame, EthernetProtocol}; use wire::{IpAddress, IpCidr, IpProtocol, IpRepr}; #[cfg(feature = "proto-ipv4")] @@ -1863,17 +1865,27 @@ mod test { use wire::{Ipv6Address, Ipv6Repr, Ipv6Packet}; #[cfg(feature = "proto-ipv6")] use wire::{Icmpv6Packet, Icmpv6Repr, Icmpv6ParamProblem}; - #[cfg(all(feature = "ethernet", feature = "proto-ipv6"))] + #[cfg(all(feature = "medium-ethernet", feature = "proto-ipv6"))] use wire::{NdiscNeighborFlags, NdiscRepr}; #[cfg(feature = "proto-ipv6")] use wire::{Ipv6HopByHopHeader, Ipv6Option, Ipv6OptionRepr}; - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] use super::EthernetPacket; use super::IpPacket; fn create_loopback<'a, 'b, 'c>() -> (Interface<'static, 'b, 'c, Loopback>, SocketSet<'static, 'a, 'b>) { + #[cfg(feature = "medium-ethernet")] + return create_loopback_ethernet(); + #[cfg(not(feature = "medium-ethernet"))] + return create_loopback_ip(); + } + + #[cfg(all(feature = "medium-ip"))] + #[allow(unused)] + fn create_loopback_ip<'a, 'b, 'c>() -> (Interface<'static, 'b, 'c, Loopback>, + SocketSet<'static, 'a, 'b>) { // Create a basic device let device = Loopback::new(Medium::Ip); let ip_addrs = [ @@ -1896,7 +1908,7 @@ mod test { (iface, SocketSet::new(vec![])) } - #[cfg(all(feature = "ethernet"))] + #[cfg(all(feature = "medium-ethernet"))] fn create_loopback_ethernet<'a, 'b, 'c>() -> (Interface<'static, 'b, 'c, Loopback>, SocketSet<'static, 'a, 'b>) { // Create a basic device @@ -1947,7 +1959,7 @@ mod test { #[test] #[should_panic(expected = "ethernet_addr required option was not set")] - #[cfg(all(feature = "ethernet"))] + #[cfg(all(feature = "medium-ethernet"))] fn test_builder_initialization_panic() { InterfaceBuilder::new(Loopback::new(Medium::Ethernet)).finalize(); } @@ -2368,7 +2380,7 @@ mod test { } #[test] - #[cfg(all(feature = "ethernet", feature = "proto-ipv4"))] + #[cfg(all(feature = "medium-ethernet", feature = "proto-ipv4"))] fn test_handle_valid_arp_request() { let (mut iface, mut socket_set) = create_loopback_ethernet(); @@ -2413,7 +2425,7 @@ mod test { } #[test] - #[cfg(all(feature = "ethernet", feature = "proto-ipv6"))] + #[cfg(all(feature = "medium-ethernet", feature = "proto-ipv6"))] fn test_handle_valid_ndisc_request() { let (mut iface, mut socket_set) = create_loopback_ethernet(); @@ -2473,7 +2485,7 @@ mod test { } #[test] - #[cfg(all(feature = "ethernet", feature = "proto-ipv4"))] + #[cfg(all(feature = "medium-ethernet", feature = "proto-ipv4"))] fn test_handle_other_arp_request() { let (mut iface, mut socket_set) = create_loopback_ethernet(); @@ -2657,11 +2669,21 @@ mod test { #[cfg(feature = "proto-igmp")] fn test_handle_igmp() { fn recv_igmp<'b>(mut iface: &mut Interface<'static, 'b, 'static, Loopback>, timestamp: Instant) -> Vec<(Ipv4Repr, IgmpRepr)> { - let checksum_caps = &iface.device.capabilities().checksum; + let caps = iface.device.capabilities(); + let checksum_caps = &caps.checksum; recv_all(&mut iface, timestamp) .iter() .filter_map(|frame| { - let ipv4_packet = Ipv4Packet::new_checked(frame).ok()?; + + let ipv4_packet = match caps.medium { + #[cfg(feature = "medium-ethernet")] + Medium::Ethernet => { + let eth_frame = EthernetFrame::new_checked(frame).ok()?; + Ipv4Packet::new_checked(eth_frame.payload()).ok()? + } + #[cfg(feature = "medium-ip")] + Medium::Ip => Ipv4Packet::new_checked(&frame[..]).ok()? + }; let ipv4_repr = Ipv4Repr::parse(&ipv4_packet, &checksum_caps).ok()?; let ip_payload = ipv4_packet.payload(); let igmp_packet = IgmpPacket::new_checked(ip_payload).ok()?; diff --git a/src/iface/mod.rs b/src/iface/mod.rs index a21bc2536..1b4f32d95 100644 --- a/src/iface/mod.rs +++ b/src/iface/mod.rs @@ -4,17 +4,19 @@ The `iface` module deals with the *network interfaces*. It filters incoming fram provides lookup and caching of hardware addresses, and handles management packets. */ -#[cfg(feature = "ethernet")] +#[cfg(feature = "medium-ethernet")] mod neighbor; mod route; +#[cfg(any(feature = "medium-ethernet", feature = "medium-ip"))] mod interface; -#[cfg(feature = "ethernet")] +#[cfg(feature = "medium-ethernet")] pub use self::neighbor::Neighbor as Neighbor; -#[cfg(feature = "ethernet")] +#[cfg(feature = "medium-ethernet")] pub(crate) use self::neighbor::Answer as NeighborAnswer; -#[cfg(feature = "ethernet")] +#[cfg(feature = "medium-ethernet")] pub use self::neighbor::Cache as NeighborCache; pub use self::route::{Route, Routes}; +#[cfg(any(feature = "medium-ethernet", feature = "medium-ip"))] pub use self::interface::{Interface, InterfaceBuilder}; diff --git a/src/lib.rs b/src/lib.rs index 4af96235b..101c703d2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ #![cfg_attr(feature = "alloc", feature(alloc))] #![no_std] #![deny(unsafe_code)] -#![cfg_attr(all(any(feature = "proto-ipv4", feature = "proto-ipv6"), feature = "ethernet"), deny(unused))] +#![cfg_attr(all(any(feature = "proto-ipv4", feature = "proto-ipv6"), feature = "medium-ethernet"), deny(unused))] //! The _smoltcp_ library is built in a layered structure, with the layers corresponding //! to the levels of API abstraction. Only the highest layers would be used by a typical @@ -91,7 +91,7 @@ compile_error!("at least one socket needs to be enabled"); */ // FIXME(dlrobertson): clippy fails with this lint #![cfg_attr(feature = "cargo-clippy", allow(if_same_then_else))] -#[cfg(all(feature = "proto-ipv6", feature = "ethernet"))] +#[cfg(all(feature = "proto-ipv6", feature = "medium-ethernet"))] #[macro_use] extern crate bitflags; extern crate byteorder; diff --git a/src/parsers.rs b/src/parsers.rs index e6452633b..31b8d746b 100644 --- a/src/parsers.rs +++ b/src/parsers.rs @@ -3,7 +3,7 @@ use core::str::FromStr; use core::result; -#[cfg(feature = "ethernet")] +#[cfg(feature = "medium-ethernet")] use wire::EthernetAddress; use wire::{IpAddress, IpCidr, IpEndpoint}; #[cfg(feature = "proto-ipv4")] @@ -118,7 +118,7 @@ impl<'a> Parser<'a> { } } - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] fn accept_mac_joined_with(&mut self, separator: u8) -> Result { let mut octets = [0u8; 6]; for n in 0..6 { @@ -130,7 +130,7 @@ impl<'a> Parser<'a> { Ok(EthernetAddress(octets)) } - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] fn accept_mac(&mut self) -> Result { if let Some(mac) = self.try(|p| p.accept_mac_joined_with(b'-')) { return Ok(mac) @@ -348,7 +348,7 @@ impl<'a> Parser<'a> { } } -#[cfg(feature = "ethernet")] +#[cfg(feature = "medium-ethernet")] impl FromStr for EthernetAddress { type Err = (); @@ -467,7 +467,7 @@ mod test { } #[test] - #[cfg(all(feature = "proto-ipv4", feature = "ethernet"))] + #[cfg(all(feature = "proto-ipv4", feature = "medium-ethernet"))] fn test_mac() { assert_eq!(EthernetAddress::from_str(""), Err(())); assert_eq!(EthernetAddress::from_str("02:00:00:00:00:00"), diff --git a/src/phy/mod.rs b/src/phy/mod.rs index 2761ff6fe..1e8d62557 100644 --- a/src/phy/mod.rs +++ b/src/phy/mod.rs @@ -11,7 +11,7 @@ and implementations of it: [TapInterface](struct.TapInterface.html), to transmit and receive frames on the host OS. */ -#![cfg_attr(feature = "ethernet", doc = r##" +#![cfg_attr(feature = "medium-ethernet", doc = r##" # Examples An implementation of the [Device](trait.Device.html) trait for a simple hardware @@ -122,7 +122,7 @@ pub use self::tap_interface::TapInterface; pub use self::tun_interface::TunInterface; -#[cfg(feature = "ethernet")] +#[cfg(feature = "medium-ethernet")] /// A tracer device for Ethernet frames. pub type EthernetTracer = Tracer>; @@ -241,23 +241,26 @@ pub enum Medium { /// and interfaces using it must do neighbor discovery via ARP or NDISC. /// /// Examples of devices of this type are Ethernet, WiFi (802.11), Linux `tap`, and VPNs in tap (layer 2) mode. - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] Ethernet, /// IP medium. Devices of this type send and receive IP frames, without an /// Ethernet header. MAC addresses are not used, and no neighbor discovery (ARP, NDISC) is done. /// /// Examples of devices of this type are the Linux `tun`, PPP interfaces, VPNs in tun (layer 3) mode. + #[cfg(feature = "medium-ip")] Ip, } impl Default for Medium { fn default() -> Medium { - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] return Medium::Ethernet; - #[cfg(not(feature = "ethernet"))] + #[cfg(all(feature = "medium-ip", not(feature = "medium-ethernet")))] return Medium::Ip; + #[cfg(all(not(feature = "medium-ip"), not(feature = "medium-ethernet")))] + panic!("No medium enabled"); } } diff --git a/src/socket/icmp.rs b/src/socket/icmp.rs index b06daaf14..5ae3f4aa8 100644 --- a/src/socket/icmp.rs +++ b/src/socket/icmp.rs @@ -1,7 +1,7 @@ use core::cmp; use {Error, Result}; -use phy::{ChecksumCapabilities, DeviceCapabilities}; +use phy::ChecksumCapabilities; use socket::{Socket, SocketMeta, SocketHandle, PollAt}; use storage::{PacketBuffer, PacketMetadata}; use wire::{IpAddress, IpEndpoint, IpProtocol, IpRepr}; @@ -342,7 +342,7 @@ impl<'a, 'b> IcmpSocket<'a, 'b> { Ok(()) } - pub(crate) fn dispatch(&mut self, _caps: &DeviceCapabilities, emit: F) -> Result<()> + pub(crate) fn dispatch(&mut self, emit: F) -> Result<()> where F: FnOnce((IpRepr, IcmpRepr)) -> Result<()> { let handle = self.meta.handle; @@ -465,9 +465,9 @@ mod test_ipv4 { #[test] fn test_send_dispatch() { let mut socket = socket(buffer(0), buffer(1)); - let caps = DeviceCapabilities::default(); + let checksum = ChecksumCapabilities::default(); - assert_eq!(socket.dispatch(&caps, |_| unreachable!()), + assert_eq!(socket.dispatch(|_| unreachable!()), Err(Error::Exhausted)); // This buffer is too long @@ -476,13 +476,13 @@ mod test_ipv4 { let mut bytes = [0xff; 24]; let mut packet = Icmpv4Packet::new_unchecked(&mut bytes); - ECHOV4_REPR.emit(&mut packet, &caps.checksum); + ECHOV4_REPR.emit(&mut packet, &checksum); assert_eq!(socket.send_slice(&packet.into_inner()[..], REMOTE_IPV4.into()), Ok(())); assert_eq!(socket.send_slice(b"123456", REMOTE_IPV4.into()), Err(Error::Exhausted)); assert!(!socket.can_send()); - assert_eq!(socket.dispatch(&caps, |(ip_repr, icmp_repr)| { + assert_eq!(socket.dispatch(|(ip_repr, icmp_repr)| { assert_eq!(ip_repr, LOCAL_IPV4_REPR); assert_eq!(icmp_repr, ECHOV4_REPR.into()); Err(Error::Unaddressable) @@ -490,7 +490,7 @@ mod test_ipv4 { // buffer is not taken off of the tx queue due to the error assert!(!socket.can_send()); - assert_eq!(socket.dispatch(&caps, |(ip_repr, icmp_repr)| { + assert_eq!(socket.dispatch(|(ip_repr, icmp_repr)| { assert_eq!(ip_repr, LOCAL_IPV4_REPR); assert_eq!(icmp_repr, ECHOV4_REPR.into()); Ok(()) @@ -502,16 +502,16 @@ mod test_ipv4 { #[test] fn test_set_hop_limit_v4() { let mut s = socket(buffer(0), buffer(1)); - let caps = DeviceCapabilities::default(); + let checksum = ChecksumCapabilities::default(); let mut bytes = [0xff; 24]; let mut packet = Icmpv4Packet::new_unchecked(&mut bytes); - ECHOV4_REPR.emit(&mut packet, &caps.checksum); + ECHOV4_REPR.emit(&mut packet, &checksum); s.set_hop_limit(Some(0x2a)); assert_eq!(s.send_slice(&packet.into_inner()[..], REMOTE_IPV4.into()), Ok(())); - assert_eq!(s.dispatch(&caps, |(ip_repr, _)| { + assert_eq!(s.dispatch(|(ip_repr, _)| { assert_eq!(ip_repr, IpRepr::Ipv4(Ipv4Repr { src_addr: Ipv4Address::UNSPECIFIED, dst_addr: REMOTE_IPV4, @@ -531,20 +531,20 @@ mod test_ipv4 { assert!(!socket.can_recv()); assert_eq!(socket.recv(), Err(Error::Exhausted)); - let caps = DeviceCapabilities::default(); + let checksum = ChecksumCapabilities::default(); let mut bytes = [0xff; 24]; let mut packet = Icmpv4Packet::new_unchecked(&mut bytes); - ECHOV4_REPR.emit(&mut packet, &caps.checksum); + ECHOV4_REPR.emit(&mut packet, &checksum); let data = &packet.into_inner()[..]; - assert!(socket.accepts(&REMOTE_IPV4_REPR, &ECHOV4_REPR.into(), &caps.checksum)); - assert_eq!(socket.process(&REMOTE_IPV4_REPR, &ECHOV4_REPR.into(), &caps.checksum), + assert!(socket.accepts(&REMOTE_IPV4_REPR, &ECHOV4_REPR.into(), &checksum)); + assert_eq!(socket.process(&REMOTE_IPV4_REPR, &ECHOV4_REPR.into(), &checksum), Ok(())); assert!(socket.can_recv()); - assert!(socket.accepts(&REMOTE_IPV4_REPR, &ECHOV4_REPR.into(), &caps.checksum)); - assert_eq!(socket.process(&REMOTE_IPV4_REPR, &ECHOV4_REPR.into(), &caps.checksum), + assert!(socket.accepts(&REMOTE_IPV4_REPR, &ECHOV4_REPR.into(), &checksum)); + assert_eq!(socket.process(&REMOTE_IPV4_REPR, &ECHOV4_REPR.into(), &checksum), Err(Error::Exhausted)); assert_eq!(socket.recv(), Ok((&data[..], REMOTE_IPV4.into()))); @@ -556,7 +556,7 @@ mod test_ipv4 { let mut socket = socket(buffer(1), buffer(1)); assert_eq!(socket.bind(Endpoint::Ident(0x1234)), Ok(())); - let caps = DeviceCapabilities::default(); + let checksum = ChecksumCapabilities::default(); let mut bytes = [0xff; 20]; let mut packet = Icmpv4Packet::new_unchecked(&mut bytes); let icmp_repr = Icmpv4Repr::EchoRequest { @@ -564,11 +564,11 @@ mod test_ipv4 { seq_no: 0x5678, data: &[0xff; 16] }; - icmp_repr.emit(&mut packet, &caps.checksum); + icmp_repr.emit(&mut packet, &checksum); // Ensure that a packet with an identifier that isn't the bound // ID is not accepted - assert!(!socket.accepts(&REMOTE_IPV4_REPR, &icmp_repr.into(), &caps.checksum)); + assert!(!socket.accepts(&REMOTE_IPV4_REPR, &icmp_repr.into(), &checksum)); } #[test] @@ -576,11 +576,11 @@ mod test_ipv4 { let mut socket = socket(buffer(1), buffer(1)); assert_eq!(socket.bind(Endpoint::Udp(LOCAL_END_V4)), Ok(())); - let caps = DeviceCapabilities::default(); + let checksum = ChecksumCapabilities::default(); let mut bytes = [0xff; 18]; let mut packet = UdpPacket::new_unchecked(&mut bytes); - UDP_REPR.emit(&mut packet, &REMOTE_IPV4.into(), &LOCAL_IPV4.into(), &caps.checksum); + UDP_REPR.emit(&mut packet, &REMOTE_IPV4.into(), &LOCAL_IPV4.into(), &checksum); let data = &packet.into_inner()[..]; @@ -607,14 +607,14 @@ mod test_ipv4 { // Ensure we can accept ICMP error response to the bound // UDP port - assert!(socket.accepts(&ip_repr, &icmp_repr.into(), &caps.checksum)); - assert_eq!(socket.process(&ip_repr, &icmp_repr.into(), &caps.checksum), + assert!(socket.accepts(&ip_repr, &icmp_repr.into(), &checksum)); + assert_eq!(socket.process(&ip_repr, &icmp_repr.into(), &checksum), Ok(())); assert!(socket.can_recv()); let mut bytes = [0x00; 46]; let mut packet = Icmpv4Packet::new_unchecked(&mut bytes[..]); - icmp_repr.emit(&mut packet, &caps.checksum); + icmp_repr.emit(&mut packet, &checksum); assert_eq!(socket.recv(), Ok((&packet.into_inner()[..], REMOTE_IPV4.into()))); assert!(!socket.can_recv()); } @@ -664,9 +664,9 @@ mod test_ipv6 { #[test] fn test_send_dispatch() { let mut socket = socket(buffer(0), buffer(1)); - let caps = DeviceCapabilities::default(); + let checksum = ChecksumCapabilities::default(); - assert_eq!(socket.dispatch(&caps, |_| unreachable!()), + assert_eq!(socket.dispatch(|_| unreachable!()), Err(Error::Exhausted)); // This buffer is too long @@ -675,13 +675,13 @@ mod test_ipv6 { let mut bytes = vec![0xff; 24]; let mut packet = Icmpv6Packet::new_unchecked(&mut bytes); - ECHOV6_REPR.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &caps.checksum); + ECHOV6_REPR.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &checksum); assert_eq!(socket.send_slice(&packet.into_inner()[..], REMOTE_IPV6.into()), Ok(())); assert_eq!(socket.send_slice(b"123456", REMOTE_IPV6.into()), Err(Error::Exhausted)); assert!(!socket.can_send()); - assert_eq!(socket.dispatch(&caps, |(ip_repr, icmp_repr)| { + assert_eq!(socket.dispatch(|(ip_repr, icmp_repr)| { assert_eq!(ip_repr, LOCAL_IPV6_REPR); assert_eq!(icmp_repr, ECHOV6_REPR.into()); Err(Error::Unaddressable) @@ -689,7 +689,7 @@ mod test_ipv6 { // buffer is not taken off of the tx queue due to the error assert!(!socket.can_send()); - assert_eq!(socket.dispatch(&caps, |(ip_repr, icmp_repr)| { + assert_eq!(socket.dispatch(|(ip_repr, icmp_repr)| { assert_eq!(ip_repr, LOCAL_IPV6_REPR); assert_eq!(icmp_repr, ECHOV6_REPR.into()); Ok(()) @@ -701,16 +701,16 @@ mod test_ipv6 { #[test] fn test_set_hop_limit() { let mut s = socket(buffer(0), buffer(1)); - let caps = DeviceCapabilities::default(); + let checksum = ChecksumCapabilities::default(); let mut bytes = vec![0xff; 24]; let mut packet = Icmpv6Packet::new_unchecked(&mut bytes); - ECHOV6_REPR.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &caps.checksum); + ECHOV6_REPR.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &checksum); s.set_hop_limit(Some(0x2a)); assert_eq!(s.send_slice(&packet.into_inner()[..], REMOTE_IPV6.into()), Ok(())); - assert_eq!(s.dispatch(&caps, |(ip_repr, _)| { + assert_eq!(s.dispatch(|(ip_repr, _)| { assert_eq!(ip_repr, IpRepr::Ipv6(Ipv6Repr { src_addr: Ipv6Address::UNSPECIFIED, dst_addr: REMOTE_IPV6, @@ -730,20 +730,20 @@ mod test_ipv6 { assert!(!socket.can_recv()); assert_eq!(socket.recv(), Err(Error::Exhausted)); - let caps = DeviceCapabilities::default(); + let checksum = ChecksumCapabilities::default(); let mut bytes = [0xff; 24]; let mut packet = Icmpv6Packet::new_unchecked(&mut bytes); - ECHOV6_REPR.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &caps.checksum); + ECHOV6_REPR.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &checksum); let data = &packet.into_inner()[..]; - assert!(socket.accepts(&REMOTE_IPV6_REPR, &ECHOV6_REPR.into(), &caps.checksum)); - assert_eq!(socket.process(&REMOTE_IPV6_REPR, &ECHOV6_REPR.into(), &caps.checksum), + assert!(socket.accepts(&REMOTE_IPV6_REPR, &ECHOV6_REPR.into(), &checksum)); + assert_eq!(socket.process(&REMOTE_IPV6_REPR, &ECHOV6_REPR.into(), &checksum), Ok(())); assert!(socket.can_recv()); - assert!(socket.accepts(&REMOTE_IPV6_REPR, &ECHOV6_REPR.into(), &caps.checksum)); - assert_eq!(socket.process(&REMOTE_IPV6_REPR, &ECHOV6_REPR.into(), &caps.checksum), + assert!(socket.accepts(&REMOTE_IPV6_REPR, &ECHOV6_REPR.into(), &checksum)); + assert_eq!(socket.process(&REMOTE_IPV6_REPR, &ECHOV6_REPR.into(), &checksum), Err(Error::Exhausted)); assert_eq!(socket.recv(), Ok((&data[..], REMOTE_IPV6.into()))); @@ -755,7 +755,7 @@ mod test_ipv6 { let mut socket = socket(buffer(1), buffer(1)); assert_eq!(socket.bind(Endpoint::Ident(0x1234)), Ok(())); - let caps = DeviceCapabilities::default(); + let checksum = ChecksumCapabilities::default(); let mut bytes = [0xff; 20]; let mut packet = Icmpv6Packet::new_unchecked(&mut bytes); let icmp_repr = Icmpv6Repr::EchoRequest { @@ -763,11 +763,11 @@ mod test_ipv6 { seq_no: 0x5678, data: &[0xff; 16] }; - icmp_repr.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &caps.checksum); + icmp_repr.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &checksum); // Ensure that a packet with an identifier that isn't the bound // ID is not accepted - assert!(!socket.accepts(&REMOTE_IPV6_REPR, &icmp_repr.into(), &caps.checksum)); + assert!(!socket.accepts(&REMOTE_IPV6_REPR, &icmp_repr.into(), &checksum)); } #[test] @@ -775,11 +775,11 @@ mod test_ipv6 { let mut socket = socket(buffer(1), buffer(1)); assert_eq!(socket.bind(Endpoint::Udp(LOCAL_END_V6)), Ok(())); - let caps = DeviceCapabilities::default(); + let checksum = ChecksumCapabilities::default(); let mut bytes = [0xff; 18]; let mut packet = UdpPacket::new_unchecked(&mut bytes); - UDP_REPR.emit(&mut packet, &REMOTE_IPV6.into(), &LOCAL_IPV6.into(), &caps.checksum); + UDP_REPR.emit(&mut packet, &REMOTE_IPV6.into(), &LOCAL_IPV6.into(), &checksum); let data = &packet.into_inner()[..]; @@ -806,14 +806,14 @@ mod test_ipv6 { // Ensure we can accept ICMP error response to the bound // UDP port - assert!(socket.accepts(&ip_repr, &icmp_repr.into(), &caps.checksum)); - assert_eq!(socket.process(&ip_repr, &icmp_repr.into(), &caps.checksum), + assert!(socket.accepts(&ip_repr, &icmp_repr.into(), &checksum)); + assert_eq!(socket.process(&ip_repr, &icmp_repr.into(), &checksum), Ok(())); assert!(socket.can_recv()); let mut bytes = [0x00; 66]; let mut packet = Icmpv6Packet::new_unchecked(&mut bytes[..]); - icmp_repr.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &caps.checksum); + icmp_repr.emit(&LOCAL_IPV6.into(), &REMOTE_IPV6.into(), &mut packet, &checksum); assert_eq!(socket.recv(), Ok((&packet.into_inner()[..], REMOTE_IPV6.into()))); assert!(!socket.can_recv()); } diff --git a/src/socket/tcp.rs b/src/socket/tcp.rs index 8cdbf2123..d2138e103 100644 --- a/src/socket/tcp.rs +++ b/src/socket/tcp.rs @@ -5,7 +5,6 @@ use core::{cmp, fmt, mem}; use {Error, Result}; -use phy::DeviceCapabilities; use time::{Duration, Instant}; use socket::{Socket, SocketMeta, SocketHandle, PollAt}; use storage::{Assembler, RingBuffer}; @@ -1433,7 +1432,7 @@ impl<'a> TcpSocket<'a> { } } - pub(crate) fn dispatch(&mut self, timestamp: Instant, caps: &DeviceCapabilities, + pub(crate) fn dispatch(&mut self, timestamp: Instant, mtu: usize, emit: F) -> Result<()> where F: FnOnce((IpRepr, TcpRepr)) -> Result<()> { if !self.remote_endpoint.is_specified() { return Err(Error::Exhausted) } @@ -1621,7 +1620,7 @@ impl<'a> TcpSocket<'a> { if repr.control == TcpControl::Syn { // Fill the MSS option. See RFC 6691 for an explanation of this calculation. - let mut max_segment_size = caps.max_transmission_unit; + let mut max_segment_size = mtu; max_segment_size -= ip_repr.buffer_len(); max_segment_size -= repr.mss_header_len(); repr.max_seg_size = Some(max_segment_size as u16); @@ -1797,9 +1796,8 @@ mod test { fn recv(socket: &mut TcpSocket, timestamp: Instant, mut f: F) where F: FnMut(Result) { - let mut caps = DeviceCapabilities::default(); - caps.max_transmission_unit = 1520; - let result = socket.dispatch(timestamp, &caps, |(ip_repr, tcp_repr)| { + let mtu = 1520; + let result = socket.dispatch(timestamp, mtu, |(ip_repr, tcp_repr)| { let ip_repr = ip_repr.lower(&[IpCidr::new(LOCAL_END.addr, 24)]).unwrap(); assert_eq!(ip_repr.protocol(), IpProtocol::Tcp); @@ -4593,11 +4591,10 @@ mod test { #[test] fn test_set_hop_limit() { let mut s = socket_syn_received(); - let mut caps = DeviceCapabilities::default(); - caps.max_transmission_unit = 1520; + let mtu = 1520; s.set_hop_limit(Some(0x2a)); - assert_eq!(s.dispatch(Instant::from_millis(0), &caps, |(ip_repr, _)| { + assert_eq!(s.dispatch(Instant::from_millis(0), mtu, |(ip_repr, _)| { assert_eq!(ip_repr.hop_limit(), 0x2a); Ok(()) }), Ok(())); diff --git a/src/wire/icmpv6.rs b/src/wire/icmpv6.rs index fd180630c..cd8f12aa2 100644 --- a/src/wire/icmpv6.rs +++ b/src/wire/icmpv6.rs @@ -6,7 +6,7 @@ use phy::ChecksumCapabilities; use super::ip::checksum; use super::{IpAddress, IpProtocol, Ipv6Packet, Ipv6Repr}; use super::MldRepr; -#[cfg(feature = "ethernet")] +#[cfg(feature = "medium-ethernet")] use super::NdiscRepr; enum_with_unknown! { @@ -539,7 +539,7 @@ pub enum Repr<'a> { seq_no: u16, data: &'a [u8] }, - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] Ndisc(NdiscRepr<'a>), Mld(MldRepr<'a>), #[doc(hidden)] @@ -622,7 +622,7 @@ impl<'a> Repr<'a> { data: packet.payload() }) }, - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] (msg_type, 0) if msg_type.is_ndisc() => { NdiscRepr::parse(packet).map(|repr| Repr::Ndisc(repr)) }, @@ -644,7 +644,7 @@ impl<'a> Repr<'a> { &Repr::EchoReply { data, .. } => { field::ECHO_SEQNO.end + data.len() }, - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] &Repr::Ndisc(ndisc) => { ndisc.buffer_len() }, @@ -716,7 +716,7 @@ impl<'a> Repr<'a> { packet.payload_mut()[..data_len].copy_from_slice(&data[..data_len]) }, - #[cfg(feature = "ethernet")] + #[cfg(feature = "medium-ethernet")] &Repr::Ndisc(ndisc) => { ndisc.emit(packet) }, diff --git a/src/wire/mod.rs b/src/wire/mod.rs index 8641f1438..0430f8b29 100644 --- a/src/wire/mod.rs +++ b/src/wire/mod.rs @@ -77,9 +77,9 @@ mod field { pub mod pretty_print; -#[cfg(feature = "ethernet")] +#[cfg(feature = "medium-ethernet")] mod ethernet; -#[cfg(all(feature = "proto-ipv4", feature = "ethernet"))] +#[cfg(all(feature = "proto-ipv4", feature = "medium-ethernet"))] mod arp; pub(crate) mod ip; #[cfg(feature = "proto-ipv4")] @@ -102,9 +102,9 @@ mod icmpv6; mod icmp; #[cfg(feature = "proto-igmp")] mod igmp; -#[cfg(all(feature = "proto-ipv6", feature = "ethernet"))] +#[cfg(all(feature = "proto-ipv6", feature = "medium-ethernet"))] mod ndisc; -#[cfg(all(feature = "proto-ipv6", feature = "ethernet"))] +#[cfg(all(feature = "proto-ipv6", feature = "medium-ethernet"))] mod ndiscoption; #[cfg(feature = "proto-ipv6")] mod mld; @@ -115,13 +115,13 @@ pub(crate) mod dhcpv4; pub use self::pretty_print::PrettyPrinter; -#[cfg(feature = "ethernet")] +#[cfg(feature = "medium-ethernet")] pub use self::ethernet::{EtherType as EthernetProtocol, Address as EthernetAddress, Frame as EthernetFrame, Repr as EthernetRepr}; -#[cfg(all(feature = "proto-ipv4", feature = "ethernet"))] +#[cfg(all(feature = "proto-ipv4", feature = "medium-ethernet"))] pub use self::arp::{Hardware as ArpHardware, Operation as ArpOperation, Packet as ArpPacket, @@ -192,12 +192,12 @@ pub use self::icmpv6::{Message as Icmpv6Message, pub use self::icmp::Repr as IcmpRepr; -#[cfg(all(feature = "proto-ipv6", feature = "ethernet"))] +#[cfg(all(feature = "proto-ipv6", feature = "medium-ethernet"))] pub use self::ndisc::{Repr as NdiscRepr, RouterFlags as NdiscRouterFlags, NeighborFlags as NdiscNeighborFlags}; -#[cfg(all(feature = "proto-ipv6", feature = "ethernet"))] +#[cfg(all(feature = "proto-ipv6", feature = "medium-ethernet"))] pub use self::ndiscoption::{NdiscOption, Repr as NdiscOptionRepr, Type as NdiscOptionType,