#![no_std]
#[macro_use]
extern crate log;
extern crate alloc;
mod consts;
mod device;
mod general;
mod listen_table;
pub mod options;
mod router;
mod service;
mod socket;
pub(crate) mod state;
pub mod tcp;
pub mod udp;
pub mod unix;
#[cfg(feature = "vsock")]
pub mod vsock;
mod wrapper;
use alloc::{borrow::ToOwned, boxed::Box};
use ax_driver::{AxDeviceContainer, prelude::*};
use ax_sync::Mutex;
use smoltcp::wire::{EthernetAddress, Ipv4Address, Ipv4Cidr};
use spin::{Lazy, Once};
pub use self::socket::*;
use self::{
consts::{GATEWAY, IP, IP_PREFIX},
device::{EthernetDevice, LoopbackDevice},
listen_table::ListenTable,
router::{Router, Rule},
service::Service,
wrapper::SocketSetWrapper,
};
static LISTEN_TABLE: Lazy<ListenTable> = Lazy::new(ListenTable::new);
static SOCKET_SET: Lazy<SocketSetWrapper> = Lazy::new(SocketSetWrapper::new);
static SERVICE: Once<Mutex<Service>> = Once::new();
fn get_service() -> ax_sync::MutexGuard<'static, Service> {
SERVICE
.get()
.expect("Network service not initialized")
.lock()
}
pub fn init_network(mut net_devs: AxDeviceContainer<AxNetDevice>) {
info!("Initialize network subsystem...");
let mut router = Router::new();
let lo_dev = router.add_device(Box::new(LoopbackDevice::new()));
let lo_ip = Ipv4Cidr::new(Ipv4Address::new(127, 0, 0, 1), 8);
router.add_rule(Rule::new(
lo_ip.into(),
None,
lo_dev,
lo_ip.address().into(),
));
let eth0_ip = if let Some(dev) = net_devs.take_one() {
info!(" use NIC 0: {:?}", dev.device_name());
let eth0_address = EthernetAddress(dev.mac_address().0);
let eth0_ip = Ipv4Cidr::new(IP.parse().expect("Invalid IPv4 address"), IP_PREFIX);
let eth0_dev = router.add_device(Box::new(EthernetDevice::new(
"eth0".to_owned(),
dev,
eth0_ip,
)));
router.add_rule(Rule::new(
Ipv4Cidr::new(Ipv4Address::UNSPECIFIED, 0).into(),
Some(GATEWAY.parse().expect("Invalid gateway address")),
eth0_dev,
eth0_ip.address().into(),
));
info!("eth0:");
info!(" mac: {}", eth0_address);
info!(" ip: {}", eth0_ip);
Some(eth0_ip)
} else {
warn!(" No network device found!");
None
};
for dev in &router.devices {
info!("Device: {}", dev.name());
}
let mut service = Service::new(router);
service.iface.update_ip_addrs(|ip_addrs| {
ip_addrs.push(lo_ip.into()).unwrap();
if let Some(eth0_ip) = eth0_ip {
ip_addrs.push(eth0_ip.into()).unwrap();
}
});
SERVICE.call_once(|| Mutex::new(service));
}
#[cfg(feature = "vsock")]
pub fn init_vsock(mut vsock_devs: AxDeviceContainer<AxVsockDevice>) {
use self::device::register_vsock_device;
info!("Initialize vsock subsystem...");
if let Some(dev) = vsock_devs.take_one() {
info!(" use vsock 0: {:?}", dev.device_name());
if let Err(e) = register_vsock_device(dev) {
warn!("Failed to initialize vsock device: {:?}", e);
}
} else {
warn!(" No vsock device found!");
}
}
pub fn poll_interfaces() {
while get_service().poll(&mut SOCKET_SET.inner.lock()) {}
}