50 lines
1.2 KiB
Plaintext
50 lines
1.2 KiB
Plaintext
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<Ipv4Addr>,
|
|
}
|
|
|
|
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<EthernetFrame, InvalidEtherType> {
|
|
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<Ipv4Addr> {
|
|
self.ip
|
|
}
|
|
|
|
pub fn set_ip(&mut self, ip: Ipv4Addr) {
|
|
self.ip = Some(ip);
|
|
}
|
|
}
|