Files
RedBear-OS/src/smolnetd/main.rs
T
Gartox 0b2b4e41c3 Add support for multiple interfaces
- Smoltcp now talk to a IP device that does the routing
- Add RouteTable
- Add trait LinkDevice representing devices (eth0, loopback...)
- Remove old device
2023-09-04 10:11:02 +02:00

165 lines
4.8 KiB
Rust

#![feature(drain_filter)]
extern crate event;
#[macro_use]
extern crate log;
extern crate byteorder;
extern crate netutils;
extern crate redox_netstack;
extern crate smoltcp;
extern crate syscall;
use std::cell::RefCell;
use std::fs::File;
use std::os::unix::io::{FromRawFd, RawFd};
use std::process;
use std::rc::Rc;
use event::EventQueue;
use redox_netstack::error::{Error, Result};
use redox_netstack::logger;
use scheme::Smolnetd;
mod buffer_pool;
mod link;
mod port_set;
mod router;
mod scheme;
fn run(daemon: redox_daemon::Daemon) -> Result<()> {
use syscall::flag::*;
trace!("opening network:");
let network_fd = syscall::open("network:", O_RDWR | O_NONBLOCK)
.map_err(|e| Error::from_syscall_error(e, "failed to open network:"))?
as RawFd;
trace!("opening :ip");
let ip_fd = syscall::open(":ip", O_RDWR | O_CREAT | O_NONBLOCK)
.map_err(|e| Error::from_syscall_error(e, "failed to open :ip"))? as RawFd;
trace!("opening :udp");
let udp_fd = syscall::open(":udp", O_RDWR | O_CREAT | O_NONBLOCK)
.map_err(|e| Error::from_syscall_error(e, "failed to open :udp"))?
as RawFd;
trace!("opening :tcp");
let tcp_fd = syscall::open(":tcp", O_RDWR | O_CREAT | O_NONBLOCK)
.map_err(|e| Error::from_syscall_error(e, "failed to open :tcp"))?
as RawFd;
trace!("opening :icmp");
let icmp_fd = syscall::open(":icmp", O_RDWR | O_CREAT | O_NONBLOCK)
.map_err(|e| Error::from_syscall_error(e, "failed to open :icmp"))?
as RawFd;
trace!("opening :netcfg");
let netcfg_fd = syscall::open(":netcfg", O_RDWR | O_CREAT | O_NONBLOCK)
.map_err(|e| Error::from_syscall_error(e, "failed to open :netcfg"))?
as RawFd;
let time_path = format!("time:{}", syscall::CLOCK_MONOTONIC);
let time_fd = syscall::open(&time_path, syscall::O_RDWR)
.map_err(|e| Error::from_syscall_error(e, "failed to open time:"))?
as RawFd;
let (network_file, ip_file, time_file, udp_file, tcp_file, icmp_file, netcfg_file) = unsafe {
(
File::from_raw_fd(network_fd),
File::from_raw_fd(ip_fd),
File::from_raw_fd(time_fd),
File::from_raw_fd(udp_fd),
File::from_raw_fd(tcp_fd),
File::from_raw_fd(icmp_fd),
File::from_raw_fd(netcfg_fd),
)
};
let smolnetd = Rc::new(RefCell::new(Smolnetd::new(
network_file,
ip_file,
udp_file,
tcp_file,
icmp_file,
time_file,
netcfg_file,
)));
let mut event_queue = EventQueue::<(), Error>::new()
.map_err(|e| Error::from_io_error(e, "failed to create event queue"))?;
syscall::setrens(0, 0).expect("smolnetd: failed to enter null namespace");
daemon.ready().expect("smolnetd: failed to notify parent");
let smolnetd_ = Rc::clone(&smolnetd);
event_queue
.add(network_fd, move |_| {
smolnetd_.borrow_mut().on_network_scheme_event()
})
.map_err(|e| Error::from_io_error(e, "failed to listen to network events"))?;
let smolnetd_ = Rc::clone(&smolnetd);
event_queue
.add(ip_fd, move |_| smolnetd_.borrow_mut().on_ip_scheme_event())
.map_err(|e| Error::from_io_error(e, "failed to listen to ip events"))?;
let smolnetd_ = Rc::clone(&smolnetd);
event_queue
.add(udp_fd, move |_| {
smolnetd_.borrow_mut().on_udp_scheme_event()
})
.map_err(|e| Error::from_io_error(e, "failed to listen to udp events"))?;
let smolnetd_ = Rc::clone(&smolnetd);
event_queue
.add(tcp_fd, move |_| {
smolnetd_.borrow_mut().on_tcp_scheme_event()
})
.map_err(|e| Error::from_io_error(e, "failed to listen to tcp events"))?;
let smolnetd_ = Rc::clone(&smolnetd);
event_queue
.add(icmp_fd, move |_| {
smolnetd_.borrow_mut().on_icmp_scheme_event()
})
.map_err(|e| Error::from_io_error(e, "failed to listen to icmp events"))?;
let smolnetd_ = Rc::clone(&smolnetd);
event_queue
.add(time_fd, move |_| smolnetd_.borrow_mut().on_time_event())
.map_err(|e| Error::from_io_error(e, "failed to listen to time events"))?;
event_queue
.add(netcfg_fd, move |_| {
smolnetd.borrow_mut().on_netcfg_scheme_event()
})
.map_err(|e| Error::from_io_error(e, "failed to listen to netcfg events"))?;
event_queue.trigger_all(event::Event {
fd: 0,
flags: EventFlags::empty(),
})?;
event_queue.run()
}
fn main() {
redox_daemon::Daemon::new(move |daemon| {
logger::init_logger("smolnetd");
if let Err(err) = run(daemon) {
error!("smoltcpd: {}", err);
process::exit(1);
}
process::exit(0);
})
.expect("smoltcp: failed to daemonize");
}