use std::net::Ipv4Addr; use tun_tap::Mode; use crate::ethernet::{EtherType, EthernetFrame, InvalidEtherType, MacAddr}; pub struct Iface { iface: tun_tap::Iface, mac: MacAddr, ip: Option, } impl Iface { pub fn new() -> Iface { Self { iface: tun_tap::Iface::without_packet_info("tap0", Mode::Tap).unwrap(), mac: MacAddr::new([0x9A, 0xB1, 0xB5, 0x22, 0x38, 0xAB]), ip: None, } } pub fn recv(&self) -> Result { let mut frame_buf = [0u8; 2048]; let frame_len = self.iface.recv(&mut frame_buf).unwrap(); EthernetFrame::parse(&frame_buf[0..frame_len]) } pub fn mac_to_self(&self, mac: MacAddr) -> bool { mac == self.mac || mac.is_broadcast() } pub fn send(&self, dst: MacAddr, typ: EtherType, data: &[u8]) { let frame = EthernetFrame::new(dst, self.mac, typ, data).serialize(); println!("{}", frame); self.iface.send(&frame).unwrap(); } pub fn mac(&self) -> MacAddr { self.mac } pub fn ip(&self) -> Option { self.ip } pub fn set_ip(&mut self, ip: Ipv4Addr) { self.ip = Some(ip); } }