pub mod bond; pub mod bridge; pub mod ethernet; pub mod gre; pub mod ipip; pub mod loopback; pub mod qdisc; pub mod stp; pub mod tun; pub mod vlan; pub mod vxlan; use std::rc::Rc; use smoltcp::time::Instant; use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr}; /// Represent a link layer device (eth0, loopback...) pub trait LinkDevice { /// Send the given packet to the machine with the `next_hop` ip address /// This method cannot fail so it's the implementor responsability /// to buffer packets which can't be sent immediatly or decide to /// drop them if necessary fn send(&mut self, next_hop: IpAddress, packet: &[u8], now: Instant); /// Returns None if nothing is received. /// Returns an Ip packet otherwise fn recv(&mut self, now: Instant) -> Option<&[u8]>; /// Returns the LinkDevice display name used to refer to it and for lookups fn name(&self) -> &Rc; /// Returns wether this device have packets pending fn can_recv(&self) -> bool; fn mac_address(&self) -> Option; fn set_mac_address(&mut self, addr: EthernetAddress); fn ip_address(&self) -> Option; fn set_ip_address(&mut self, addr: IpCidr); fn arp_table(&self) -> String { String::new() } fn flush_arp(&mut self) {} fn arp_stats(&self) -> String { String::new() } fn qdisc_info(&self) -> String { "none\n".to_string() } fn set_qdisc(&mut self, _kind: &str) -> Result<(), String> { Err("qdisc configuration not supported on this device\n".to_string()) } fn add_static_neighbor(&mut self, _ip: IpAddress, _mac: [u8; 6]) -> Result<(), String> { Err("static ARP entry not supported on this device\n".to_string()) } fn remove_neighbor(&mut self, _ip: IpAddress) -> bool { false } fn is_promiscuous(&self) -> bool { false } fn set_promiscuous(&mut self, _enabled: bool) {} fn mtu(&self) -> usize { 1500 } fn set_mtu(&mut self, _mtu: usize) {} fn is_enabled(&self) -> bool { true } fn set_enabled(&mut self, _enabled: bool) {} fn link_state(&self) -> &'static str { "unknown" } fn statistics(&self) -> Stats { Stats::default() } } #[derive(Debug, Default, Clone, Copy)] pub struct Stats { pub rx_bytes: u64, pub rx_packets: u64, pub tx_bytes: u64, pub tx_packets: u64, pub rx_errors: u64, pub tx_errors: u64, pub rx_dropped: u64, pub tx_dropped: u64, } #[derive(Default)] pub struct DeviceList { inner: Vec>, } impl DeviceList { pub fn push(&mut self, dev: T) { self.inner.push(Box::new(dev)) } pub fn get(&self, device_name: &str) -> Option<&dyn LinkDevice> { self.inner .iter() .find(|dev| dev.name().as_ref() == device_name) .map(|device| device.as_ref()) } pub fn get_mut(&mut self, device_name: &str) -> Option<&mut (dyn LinkDevice + 'static)> { self.inner .iter_mut() .find(|dev| dev.name().as_ref() == device_name) .map(|device| device.as_mut()) } pub fn iter(&self) -> impl Iterator { self.inner.iter().map(|b| b.as_ref()) } pub fn iter_mut(&mut self) -> impl Iterator { self.inner.iter_mut().map(|b| b.as_mut()) } }