1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use std::{
collections::BTreeMap,
sync::{Arc, Mutex},
};
use twizzler_async::Task;
use crate::{
link::ethernet::{handle_incoming_ethernet_packets, EthernetAddr},
link::nic::NetworkInterface,
};
mod loopback;
lazy_static::lazy_static! {
static ref NIC_MANAGER: NicManager = NicManager::new();
}
struct NicManagerInner {
nics: BTreeMap<EthernetAddr, Arc<dyn NetworkInterface + Sync + Send>>,
}
struct NicManager {
inner: Mutex<NicManagerInner>,
}
impl NicManager {
fn new() -> Self {
Self {
inner: Mutex::new(NicManagerInner {
nics: BTreeMap::new(),
}),
}
}
}
pub fn init() {
let mut inner = NIC_MANAGER.inner.lock().unwrap();
let lo = Arc::new(loopback::Loopback::new());
inner.nics.insert(lo.get_ethernet_addr(), lo.clone());
Task::spawn(async move {
loop {
let recv = lo.recv_ethernet().await;
if let Ok(recv) = recv {
handle_incoming_ethernet_packets(&recv).await;
} else {
eprintln!("loopback recv thread encountered an error: {:?}", recv);
break;
}
}
})
.detach();
}
pub fn lookup_nic(addr: &EthernetAddr) -> Option<Arc<dyn NetworkInterface + Send + Sync>> {
let inner = NIC_MANAGER.inner.lock().unwrap();
inner.nics.get(addr).cloned()
}