nstack-rs/2
2022-12-05 12:13:32 -06:00

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);
}
}