Replace EthernetInterface::new with EthernetInterfaceBuilder.
parent
278bb4b2c9
commit
4a98190f9b
|
@ -12,7 +12,7 @@ use std::time::Instant;
|
|||
use std::os::unix::io::AsRawFd;
|
||||
use smoltcp::phy::wait as phy_wait;
|
||||
use smoltcp::wire::{EthernetAddress, Ipv4Address, IpAddress, IpCidr};
|
||||
use smoltcp::iface::{NeighborCache, EthernetInterface};
|
||||
use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder};
|
||||
use smoltcp::socket::{SocketSet, TcpSocket, TcpSocketBuffer};
|
||||
|
||||
fn main() {
|
||||
|
@ -42,8 +42,12 @@ fn main() {
|
|||
let ethernet_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x02]);
|
||||
let ip_addrs = [IpCidr::new(IpAddress::v4(192, 168, 69, 2), 24)];
|
||||
let default_v4_gw = Ipv4Address::new(192, 168, 69, 100);
|
||||
let mut iface = EthernetInterface::new(
|
||||
device, neighbor_cache, ethernet_addr, ip_addrs, Some(default_v4_gw));
|
||||
let mut iface = EthernetInterfaceBuilder::new(device)
|
||||
.ethernet_addr(ethernet_addr)
|
||||
.neighbor_cache(neighbor_cache)
|
||||
.ip_addrs(ip_addrs)
|
||||
.ipv4_gateway(default_v4_gw)
|
||||
.finalize();
|
||||
|
||||
let mut sockets = SocketSet::new(vec![]);
|
||||
let tcp_handle = sockets.add(tcp_socket);
|
||||
|
|
|
@ -18,7 +18,7 @@ mod utils;
|
|||
use core::str;
|
||||
use smoltcp::phy::Loopback;
|
||||
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr};
|
||||
use smoltcp::iface::{NeighborCache, EthernetInterface};
|
||||
use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder};
|
||||
use smoltcp::socket::{SocketSet, TcpSocket, TcpSocketBuffer};
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
|
@ -89,8 +89,11 @@ fn main() {
|
|||
let mut neighbor_cache = NeighborCache::new(&mut neighbor_cache_entries[..]);
|
||||
|
||||
let mut ip_addrs = [IpCidr::new(IpAddress::v4(127, 0, 0, 1), 8)];
|
||||
let mut iface = EthernetInterface::new(
|
||||
device, neighbor_cache, EthernetAddress::default(), &mut ip_addrs[..], None);
|
||||
let mut iface = EthernetInterfaceBuilder::new(device)
|
||||
.ethernet_addr(EthernetAddress::default())
|
||||
.neighbor_cache(neighbor_cache)
|
||||
.ip_addrs(ip_addrs)
|
||||
.finalize();
|
||||
|
||||
let server_socket = {
|
||||
// It is not strictly necessary to use a `static mut` and unsafe code here, but
|
||||
|
|
|
@ -15,7 +15,7 @@ use smoltcp::phy::Device;
|
|||
use smoltcp::phy::wait as phy_wait;
|
||||
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr,
|
||||
Ipv4Address, Icmpv4Repr, Icmpv4Packet};
|
||||
use smoltcp::iface::{NeighborCache, EthernetInterface};
|
||||
use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder};
|
||||
use smoltcp::socket::{SocketSet, IcmpSocket, IcmpSocketBuffer, IcmpPacketBuffer, IcmpEndpoint};
|
||||
use std::collections::HashMap;
|
||||
use byteorder::{ByteOrder, NetworkEndian};
|
||||
|
@ -58,8 +58,12 @@ fn main() {
|
|||
let ethernet_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x02]);
|
||||
let ip_addr = IpCidr::new(IpAddress::from(local_addr), 24);
|
||||
let default_v4_gw = Ipv4Address::new(192, 168, 69, 100);
|
||||
let mut iface = EthernetInterface::new(
|
||||
device, neighbor_cache, ethernet_addr, [ip_addr], Some(default_v4_gw));
|
||||
let mut iface = EthernetInterfaceBuilder::new(device)
|
||||
.ethernet_addr(ethernet_addr)
|
||||
.ip_addrs([ip_addr])
|
||||
.ipv4_gateway(default_v4_gw)
|
||||
.neighbor_cache(neighbor_cache)
|
||||
.finalize();
|
||||
|
||||
let mut sockets = SocketSet::new(vec![]);
|
||||
let icmp_handle = sockets.add(icmp_socket);
|
||||
|
|
|
@ -13,7 +13,7 @@ use std::time::Instant;
|
|||
use std::os::unix::io::AsRawFd;
|
||||
use smoltcp::phy::wait as phy_wait;
|
||||
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr};
|
||||
use smoltcp::iface::{NeighborCache, EthernetInterface};
|
||||
use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder};
|
||||
use smoltcp::socket::SocketSet;
|
||||
use smoltcp::socket::{UdpSocket, UdpSocketBuffer, UdpPacketBuffer};
|
||||
use smoltcp::socket::{TcpSocket, TcpSocketBuffer};
|
||||
|
@ -56,8 +56,11 @@ fn main() {
|
|||
|
||||
let ethernet_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]);
|
||||
let ip_addrs = [IpCidr::new(IpAddress::v4(192, 168, 69, 1), 24)];
|
||||
let mut iface = EthernetInterface::new(
|
||||
device, neighbor_cache, ethernet_addr, ip_addrs, None);
|
||||
let mut iface = EthernetInterfaceBuilder::new(device)
|
||||
.ethernet_addr(ethernet_addr)
|
||||
.neighbor_cache(neighbor_cache)
|
||||
.ip_addrs(ip_addrs)
|
||||
.finalize();
|
||||
|
||||
let mut sockets = SocketSet::new(vec![]);
|
||||
let udp_handle = sockets.add(udp_socket);
|
||||
|
|
|
@ -54,6 +54,132 @@ struct InterfaceInner<'b, 'c> {
|
|||
device_capabilities: DeviceCapabilities,
|
||||
}
|
||||
|
||||
/// A builder structure used for creating a Ethernet network
|
||||
/// interface.
|
||||
pub struct InterfaceBuilder <'b, 'c, DeviceT: for<'d> Device<'d>> {
|
||||
device: DeviceT,
|
||||
ethernet_addr: Option<EthernetAddress>,
|
||||
neighbor_cache: Option<NeighborCache<'b>>,
|
||||
ip_addrs: Option<ManagedSlice<'c, IpCidr>>,
|
||||
ipv4_gateway: Option<Ipv4Address>,
|
||||
}
|
||||
|
||||
impl<'b, 'c, DeviceT> InterfaceBuilder<'b, 'c, DeviceT>
|
||||
where DeviceT: for<'d> Device<'d> {
|
||||
/// Create a builder used for creating a network interface using the
|
||||
/// given device and address.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use std::collections::BTreeMap;
|
||||
/// use smoltcp::iface::{EthernetInterfaceBuilder, NeighborCache};
|
||||
/// # use smoltcp::phy::Loopback;
|
||||
/// use smoltcp::wire::{EthernetAddress, IpCidr, IpAddress};
|
||||
///
|
||||
/// let device = // ...
|
||||
/// # Loopback::new();
|
||||
/// let hw_addr = // ...
|
||||
/// # EthernetAddress::default();
|
||||
/// let neighbor_cache = // ...
|
||||
/// # NeighborCache::new(BTreeMap::new());
|
||||
/// let ip_addrs = // ...
|
||||
/// # [];
|
||||
/// let iface = EthernetInterfaceBuilder::new(device)
|
||||
/// .ethernet_addr(hw_addr)
|
||||
/// .neighbor_cache(neighbor_cache)
|
||||
/// .ip_addrs(ip_addrs)
|
||||
/// .finalize();
|
||||
/// ```
|
||||
pub fn new(device: DeviceT) -> InterfaceBuilder<'b, 'c, DeviceT> {
|
||||
InterfaceBuilder {
|
||||
device: device,
|
||||
ethernet_addr: None,
|
||||
neighbor_cache: None,
|
||||
ip_addrs: None,
|
||||
ipv4_gateway: None
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the Ethernet address the interface will use. See also
|
||||
/// [ethernet_addr].
|
||||
///
|
||||
/// # Panics
|
||||
/// This function panics if the address is not unicast.
|
||||
///
|
||||
/// [ethernet_addr]: struct.EthernetInterface.html#method.ethernet_addr
|
||||
pub fn ethernet_addr(mut self, addr: EthernetAddress) -> InterfaceBuilder<'b, 'c, DeviceT> {
|
||||
InterfaceInner::check_ethernet_addr(&addr);
|
||||
self.ethernet_addr = Some(addr);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the IP addresses the interface will use. See also
|
||||
/// [ip_addrs].
|
||||
///
|
||||
/// # Panics
|
||||
/// This function panics if any of the addresses is not unicast.
|
||||
///
|
||||
/// [ip_addrs]: struct.EthernetInterface.html#method.ip_addrs
|
||||
pub fn ip_addrs<T: Into<ManagedSlice<'c, IpCidr>>>(mut self, ips: T) -> InterfaceBuilder<'b, 'c, DeviceT> {
|
||||
let ips = ips.into();
|
||||
InterfaceInner::check_ip_addrs(&ips);
|
||||
self.ip_addrs = Some(ips);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the IPv4 gateway the interface will use. See also
|
||||
/// [ipv4_gateway].
|
||||
///
|
||||
/// # Panics
|
||||
/// This function panics if the given address is not unicast.
|
||||
///
|
||||
/// [ipv4_gateway]: struct.EthernetInterface.html#method.ipv4_gateway
|
||||
pub fn ipv4_gateway<T>(mut self, gateway: T) -> InterfaceBuilder<'b, 'c, DeviceT>
|
||||
where T: Into<Ipv4Address> {
|
||||
let addr = gateway.into();
|
||||
InterfaceInner::check_gateway_addr(&addr);
|
||||
self.ipv4_gateway = Some(addr);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the Neighbor Cache the interface will use.
|
||||
pub fn neighbor_cache(mut self, neighbor_cache: NeighborCache<'b>) -> InterfaceBuilder<'b, 'c, DeviceT> {
|
||||
self.neighbor_cache = Some(neighbor_cache);
|
||||
self
|
||||
}
|
||||
|
||||
/// Create a network interface using the previously provided configuration.
|
||||
///
|
||||
/// # Panics
|
||||
/// If a required option is not provided, this function will panic. Required
|
||||
/// options are:
|
||||
///
|
||||
/// - [ethernet_addr]
|
||||
/// - [neighbor_cache]
|
||||
/// - [ip_addrs]
|
||||
///
|
||||
/// [ethernet_addr]: #method.ethernet_addr
|
||||
/// [neighbor_cache]: #method.neighbor_cache
|
||||
/// [ip_addrs]: #method.ip_addrs
|
||||
pub fn finalize(self) -> Interface<'b, 'c, DeviceT> {
|
||||
// TODO: Limit the number of required options.
|
||||
match (self.ethernet_addr, self.neighbor_cache, self.ip_addrs) {
|
||||
(Some(ethernet_addr), Some(neighbor_cache), Some(ip_addrs)) => {
|
||||
let device_capabilities = self.device.capabilities();
|
||||
Interface {
|
||||
device: self.device,
|
||||
inner: InterfaceInner {
|
||||
ethernet_addr, device_capabilities, neighbor_cache,
|
||||
ip_addrs, ipv4_gateway: self.ipv4_gateway,
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => panic!("a required option was not set"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum Packet<'a> {
|
||||
None,
|
||||
|
@ -84,33 +210,6 @@ impl<'a> Packet<'a> {
|
|||
|
||||
impl<'b, 'c, DeviceT> Interface<'b, 'c, DeviceT>
|
||||
where DeviceT: for<'d> Device<'d> {
|
||||
/// Create a network interface using the provided network device.
|
||||
///
|
||||
/// # Panics
|
||||
/// See the restrictions on [set_hardware_addr](#method.set_hardware_addr)
|
||||
/// and [set_protocol_addrs](#method.set_protocol_addrs) functions.
|
||||
pub fn new<ProtocolAddrsMT, Ipv4GatewayAddrT>
|
||||
(device: DeviceT,
|
||||
neighbor_cache: NeighborCache<'b>,
|
||||
ethernet_addr: EthernetAddress,
|
||||
ip_addrs: ProtocolAddrsMT,
|
||||
ipv4_gateway: Ipv4GatewayAddrT) ->
|
||||
Interface<'b, 'c, DeviceT>
|
||||
where ProtocolAddrsMT: Into<ManagedSlice<'c, IpCidr>>,
|
||||
Ipv4GatewayAddrT: Into<Option<Ipv4Address>>, {
|
||||
let ip_addrs = ip_addrs.into();
|
||||
InterfaceInner::check_ethernet_addr(ðernet_addr);
|
||||
InterfaceInner::check_ip_addrs(&ip_addrs);
|
||||
|
||||
let inner = InterfaceInner {
|
||||
ethernet_addr, ip_addrs, neighbor_cache,
|
||||
ipv4_gateway: ipv4_gateway.into(),
|
||||
device_capabilities: device.capabilities(),
|
||||
};
|
||||
|
||||
Interface { device, inner }
|
||||
}
|
||||
|
||||
/// Get the Ethernet address of the interface.
|
||||
pub fn ethernet_addr(&self) -> EthernetAddress {
|
||||
self.inner.ethernet_addr
|
||||
|
@ -314,6 +413,12 @@ impl<'b, 'c> InterfaceInner<'b, 'c> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_gateway_addr(addr: &Ipv4Address) {
|
||||
if !addr.is_unicast() {
|
||||
panic!("gateway IP address {} is not unicast", addr);
|
||||
}
|
||||
}
|
||||
|
||||
/// Check whether the interface has the given IP address assigned.
|
||||
fn has_ip_addr<T: Into<IpAddress>>(&self, addr: T) -> bool {
|
||||
let addr = addr.into();
|
||||
|
@ -795,6 +900,7 @@ mod test {
|
|||
use std::collections::BTreeMap;
|
||||
use {Result, Error};
|
||||
|
||||
use super::InterfaceBuilder;
|
||||
use iface::{NeighborCache, EthernetInterface};
|
||||
use phy::{self, Loopback, ChecksumCapabilities};
|
||||
use socket::SocketSet;
|
||||
|
@ -812,12 +918,13 @@ mod test {
|
|||
// Create a basic device
|
||||
let device = Loopback::new();
|
||||
|
||||
let neighbor_cache = NeighborCache::new(BTreeMap::new());
|
||||
let iface = InterfaceBuilder::new(device)
|
||||
.ethernet_addr(EthernetAddress::default())
|
||||
.neighbor_cache(NeighborCache::new(BTreeMap::new()))
|
||||
.ip_addrs([IpCidr::new(IpAddress::v4(127, 0, 0, 1), 8)])
|
||||
.finalize();
|
||||
|
||||
let ip_addr = IpCidr::new(IpAddress::v4(127, 0, 0, 1), 8);
|
||||
(EthernetInterface::new(device, neighbor_cache,
|
||||
EthernetAddress::default(), [ip_addr], None),
|
||||
SocketSet::new(vec![]))
|
||||
(iface, SocketSet::new(vec![]))
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
|
@ -830,6 +937,12 @@ mod test {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "a required option was not set")]
|
||||
fn test_builder_initialization_panic() {
|
||||
InterfaceBuilder::new(Loopback::new()).finalize();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_icmp_to_broadcast() {
|
||||
let (mut iface, mut socket_set) = create_loopback();
|
||||
|
|
|
@ -9,4 +9,5 @@ mod ethernet;
|
|||
pub use self::neighbor::Neighbor as Neighbor;
|
||||
pub(crate) use self::neighbor::Answer as NeighborAnswer;
|
||||
pub use self::neighbor::Cache as NeighborCache;
|
||||
pub use self::ethernet::Interface as EthernetInterface;
|
||||
pub use self::ethernet::{Interface as EthernetInterface,
|
||||
InterfaceBuilder as EthernetInterfaceBuilder};
|
||||
|
|
Loading…
Reference in New Issue