diff --git a/schemes/ethernetd/src/main.rs b/schemes/ethernetd/src/main.rs index 66357b6..8444081 100644 --- a/schemes/ethernetd/src/main.rs +++ b/schemes/ethernetd/src/main.rs @@ -7,6 +7,7 @@ use std::cell::RefCell; use std::fs::File; use std::io::{Result, Read, Write}; use std::os::unix::io::FromRawFd; +use std::process; use std::rc::Rc; use syscall::{Packet, SchemeMut, EWOULDBLOCK}; @@ -15,80 +16,93 @@ use scheme::EthernetScheme; mod scheme; -fn main() { - // Daemonize - if unsafe { syscall::clone(0).unwrap() } == 0 { - let network_fd = syscall::open("network:", syscall::O_RDWR | syscall::O_NONBLOCK).expect("ethernetd: failed to open network"); - let network = unsafe { File::from_raw_fd(network_fd) }; +fn daemon(network_fd: usize, socket_fd: usize) { + let network = unsafe { File::from_raw_fd(network_fd) }; + let socket = Rc::new(RefCell::new(unsafe { File::from_raw_fd(socket_fd) })); + let scheme = Rc::new(RefCell::new(EthernetScheme::new(network))); + let todo = Rc::new(RefCell::new(Vec::::new())); - let socket_fd = syscall::open(":ethernet", syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK).expect("ethernetd: failed to create ethernet scheme"); - let socket = Rc::new(RefCell::new(unsafe { File::from_raw_fd(socket_fd) })); + let mut event_queue = EventQueue::<()>::new().expect("ethernetd: failed to create event queue"); - let scheme = Rc::new(RefCell::new(EthernetScheme::new(network))); - - let todo = Rc::new(RefCell::new(Vec::::new())); - - let mut event_queue = EventQueue::<()>::new().expect("ethernetd: failed to create event queue"); - - let socket_net = socket.clone(); - let scheme_net = scheme.clone(); - let todo_net = todo.clone(); - event_queue.add(network_fd, move |_count: usize| -> Result> { - if scheme_net.borrow_mut().input()? > 0 { - let mut todo = todo_net.borrow_mut(); - let mut i = 0; - while i < todo.len() { - let a = todo[i].a; - scheme_net.borrow_mut().handle(&mut todo[i]); - if todo[i].a == (-EWOULDBLOCK) as usize { - todo[i].a = a; - i += 1; - } else { - socket_net.borrow_mut().write(&mut todo[i])?; - todo.remove(i); - } - } - - for (id, handle) in scheme_net.borrow_mut().handles.iter() { - if let Some(frame) = handle.frames.get(0) { - socket_net.borrow_mut().write(&Packet { - id: 0, - pid: 0, - uid: 0, - gid: 0, - a: syscall::number::SYS_FEVENT, - b: *id, - c: syscall::flag::EVENT_READ, - d: frame.data.len() - })?; - } - } - } - Ok(None) - }).expect("ethernetd: failed to listen for network events"); - - event_queue.add(socket_fd, move |_count: usize| -> Result> { - loop { - let mut packet = Packet::default(); - if socket.borrow_mut().read(&mut packet)? == 0 { - break; - } - - let a = packet.a; - scheme.borrow_mut().handle(&mut packet); - if packet.a == (-EWOULDBLOCK) as usize { - packet.a = a; - todo.borrow_mut().push(packet); + let socket_net = socket.clone(); + let scheme_net = scheme.clone(); + let todo_net = todo.clone(); + event_queue.add(network_fd, move |_count: usize| -> Result> { + if scheme_net.borrow_mut().input()? > 0 { + let mut todo = todo_net.borrow_mut(); + let mut i = 0; + while i < todo.len() { + let a = todo[i].a; + scheme_net.borrow_mut().handle(&mut todo[i]); + if todo[i].a == (-EWOULDBLOCK) as usize { + todo[i].a = a; + i += 1; } else { - socket.borrow_mut().write(&mut packet)?; + socket_net.borrow_mut().write(&mut todo[i])?; + todo.remove(i); } } - Ok(None) - }).expect("ethernetd: failed to listen for scheme events"); + for (id, handle) in scheme_net.borrow_mut().handles.iter() { + if let Some(frame) = handle.frames.get(0) { + socket_net.borrow_mut().write(&Packet { + id: 0, + pid: 0, + uid: 0, + gid: 0, + a: syscall::number::SYS_FEVENT, + b: *id, + c: syscall::flag::EVENT_READ, + d: frame.data.len() + })?; + } + } + } + Ok(None) + }).expect("ethernetd: failed to listen for network events"); - event_queue.trigger_all(0).expect("ethernetd: failed to trigger events"); + event_queue.add(socket_fd, move |_count: usize| -> Result> { + loop { + let mut packet = Packet::default(); + if socket.borrow_mut().read(&mut packet)? == 0 { + break; + } - event_queue.run().expect("ethernetd: failed to run event loop"); + let a = packet.a; + scheme.borrow_mut().handle(&mut packet); + if packet.a == (-EWOULDBLOCK) as usize { + packet.a = a; + todo.borrow_mut().push(packet); + } else { + socket.borrow_mut().write(&mut packet)?; + } + } + + Ok(None) + }).expect("ethernetd: failed to listen for scheme events"); + + event_queue.trigger_all(0).expect("ethernetd: failed to trigger events"); + + event_queue.run().expect("ethernetd: failed to run event loop"); +} + +fn main() { + match syscall::open("network:", syscall::O_RDWR | syscall::O_NONBLOCK) { + Ok(network_fd) => match syscall::open(":ethernet", syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK) { + Ok(socket_fd) => { + // Daemonize + if unsafe { syscall::clone(0).unwrap() } == 0 { + daemon(network_fd, socket_fd); + } + }, + Err(err) => { + println!("ethernetd: failed to create ethernet scheme: {}", err); + process::exit(1); + } + }, + Err(err) => { + println!("ethernetd: failed to open network: {}", err); + process::exit(1); + } } } diff --git a/schemes/ipd/src/main.rs b/schemes/ipd/src/main.rs index 52ae0cb..019a5e1 100644 --- a/schemes/ipd/src/main.rs +++ b/schemes/ipd/src/main.rs @@ -9,8 +9,8 @@ use std::collections::{BTreeMap, VecDeque}; use std::fs::File; use std::io::{self, Read, Write}; use std::os::unix::io::FromRawFd; +use std::{process, slice, str}; use std::rc::Rc; -use std::{slice, str}; use syscall::data::Packet; use syscall::error::{Error, Result, EACCES, EADDRNOTAVAIL, EBADF, EIO, EINVAL, ENOENT, EWOULDBLOCK}; use syscall::flag::{EVENT_READ, O_NONBLOCK}; @@ -255,64 +255,85 @@ impl SchemeMut for Ipd { } } -fn main() { - // Daemonize - if unsafe { syscall::clone(0).unwrap() } == 0 { - let scheme_fd = syscall::open(":ip", syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK).expect("ipd: failed to create :ip"); - let scheme_file = unsafe { File::from_raw_fd(scheme_fd) }; +fn daemon(arp_fd: usize, ip_fd: usize, scheme_fd: usize) { + let scheme_file = unsafe { File::from_raw_fd(scheme_fd) }; - let ipd = Rc::new(RefCell::new(Ipd::new(scheme_file))); + let ipd = Rc::new(RefCell::new(Ipd::new(scheme_file))); - let mut event_queue = EventQueue::<()>::new().expect("ipd: failed to create event queue"); + let mut event_queue = EventQueue::<()>::new().expect("ipd: failed to create event queue"); - //TODO: Multiple interfaces - { - let arp_fd = syscall::open("ethernet:806", syscall::O_RDWR | syscall::O_NONBLOCK).expect("ipd: failed to open ethernet:806"); - let ip_fd = syscall::open("ethernet:800", syscall::O_RDWR | syscall::O_NONBLOCK).expect("ipd: failed to open ethernet:800"); - let if_id = { - let mut ipd = ipd.borrow_mut(); - let if_id = ipd.interfaces.len(); - ipd.interfaces.push(Box::new(EthernetInterface::new(arp_fd, ip_fd))); - if_id - }; - - let arp_ipd = ipd.clone(); - event_queue.add(arp_fd, move |_count: usize| -> io::Result> { - if let Some(mut interface) = arp_ipd.borrow_mut().interfaces.get_mut(if_id) { - interface.arp_event()?; - } - - Ok(None) - }).expect("ipd: failed to listen to events on ethernet:806"); - - let ip_ipd = ipd.clone(); - event_queue.add(ip_fd, move |_count: usize| -> io::Result> { - ip_ipd.borrow_mut().ip_event(if_id)?; - - Ok(None) - }).expect("ipd: failed to listen to events on ethernet:800"); - } - - let loopback_id = { + //TODO: Multiple interfaces + { + let if_id = { let mut ipd = ipd.borrow_mut(); let if_id = ipd.interfaces.len(); - ipd.interfaces.push(Box::new(LoopbackInterface::new())); + ipd.interfaces.push(Box::new(EthernetInterface::new(arp_fd, ip_fd))); if_id }; - event_queue.add(scheme_fd, move |_count: usize| -> io::Result> { - let mut ipd = ipd.borrow_mut(); - - ipd.loopback_event(loopback_id)?; - ipd.scheme_event()?; - ipd.loopback_event(loopback_id)?; + let arp_ipd = ipd.clone(); + event_queue.add(arp_fd, move |_count: usize| -> io::Result> { + if let Some(mut interface) = arp_ipd.borrow_mut().interfaces.get_mut(if_id) { + interface.arp_event()?; + } Ok(None) - }).expect("ipd: failed to listen to events on :ip"); + }).expect("ipd: failed to listen to events on ethernet:806"); - // Make sure that all descriptors are at EOF - event_queue.trigger_all(0).expect("ipd: failed to trigger event queue"); + let ip_ipd = ipd.clone(); + event_queue.add(ip_fd, move |_count: usize| -> io::Result> { + ip_ipd.borrow_mut().ip_event(if_id)?; - event_queue.run().expect("ipd: failed to run event queue"); + Ok(None) + }).expect("ipd: failed to listen to events on ethernet:800"); + } + + let loopback_id = { + let mut ipd = ipd.borrow_mut(); + let if_id = ipd.interfaces.len(); + ipd.interfaces.push(Box::new(LoopbackInterface::new())); + if_id + }; + + event_queue.add(scheme_fd, move |_count: usize| -> io::Result> { + let mut ipd = ipd.borrow_mut(); + + ipd.loopback_event(loopback_id)?; + ipd.scheme_event()?; + ipd.loopback_event(loopback_id)?; + + Ok(None) + }).expect("ipd: failed to listen to events on :ip"); + + // Make sure that all descriptors are at EOF + event_queue.trigger_all(0).expect("ipd: failed to trigger event queue"); + + event_queue.run().expect("ipd: failed to run event queue"); +} + +fn main() { + match syscall::open("ethernet:806", syscall::O_RDWR | syscall::O_NONBLOCK) { + Ok(arp_fd) => match syscall::open("ethernet:800", syscall::O_RDWR | syscall::O_NONBLOCK) { + Ok(ip_fd) => match syscall::open(":ip", syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK) { + Ok(scheme_fd) => { + // Daemonize + if unsafe { syscall::clone(0).unwrap() } == 0 { + daemon(arp_fd, ip_fd, scheme_fd); + } + }, + Err(err) => { + println!("ipd: failed to create ip scheme: {}", err); + process::exit(1); + } + }, + Err(err) => { + println!("ipd: failed to open ethernet:800: {}", err); + process::exit(1); + } + }, + Err(err) => { + println!("ipd: failed to open ethernet:806: {}", err); + process::exit(1); + } } } diff --git a/schemes/tcpd/src/main.rs b/schemes/tcpd/src/main.rs index 9fb5935..9dfbd02 100644 --- a/schemes/tcpd/src/main.rs +++ b/schemes/tcpd/src/main.rs @@ -8,7 +8,7 @@ use std::collections::{BTreeMap, VecDeque}; use std::cell::RefCell; use std::fs::File; use std::io::{self, Read, Write}; -use std::{mem, slice, str}; +use std::{mem, process, slice, str}; use std::ops::{Deref, DerefMut}; use std::os::unix::io::FromRawFd; use std::rc::Rc; @@ -783,32 +783,47 @@ impl SchemeMut for Tcpd { } } +fn daemon(tcp_fd: usize, scheme_fd: usize) { + let tcp_file = unsafe { File::from_raw_fd(tcp_fd) }; + let scheme_file = unsafe { File::from_raw_fd(scheme_fd) }; + + let tcpd = Rc::new(RefCell::new(Tcpd::new(scheme_file, tcp_file))); + + let mut event_queue = EventQueue::<()>::new().expect("tcpd: failed to create event queue"); + + let tcp_tcpd = tcpd.clone(); + event_queue.add(tcp_fd, move |_count: usize| -> io::Result> { + tcp_tcpd.borrow_mut().tcp_event()?; + Ok(None) + }).expect("tcpd: failed to listen to events on ip:6"); + + event_queue.add(scheme_fd, move |_count: usize| -> io::Result> { + tcpd.borrow_mut().scheme_event()?; + Ok(None) + }).expect("tcpd: failed to listen to events on :tcp"); + + event_queue.trigger_all(0).expect("tcpd: failed to trigger event queue"); + + event_queue.run().expect("tcpd: failed to run event queue"); +} + fn main() { - // Daemonize - if unsafe { syscall::clone(0).unwrap() } == 0 { - let scheme_fd = syscall::open(":tcp", O_RDWR | O_CREAT | O_NONBLOCK).expect("tcpd: failed to create :tcp"); - let scheme_file = unsafe { File::from_raw_fd(scheme_fd) }; - - let tcp_fd = syscall::open("ip:6", O_RDWR | O_NONBLOCK).expect("tcpd: failed to open ip:6"); - let tcp_file = unsafe { File::from_raw_fd(tcp_fd) }; - - let tcpd = Rc::new(RefCell::new(Tcpd::new(scheme_file, tcp_file))); - - let mut event_queue = EventQueue::<()>::new().expect("tcpd: failed to create event queue"); - - let tcp_tcpd = tcpd.clone(); - event_queue.add(tcp_fd, move |_count: usize| -> io::Result> { - tcp_tcpd.borrow_mut().tcp_event()?; - Ok(None) - }).expect("tcpd: failed to listen to events on ip:6"); - - event_queue.add(scheme_fd, move |_count: usize| -> io::Result> { - tcpd.borrow_mut().scheme_event()?; - Ok(None) - }).expect("tcpd: failed to listen to events on :tcp"); - - event_queue.trigger_all(0).expect("tcpd: failed to trigger event queue"); - - event_queue.run().expect("tcpd: failed to run event queue"); + match syscall::open("ip:6", O_RDWR | O_NONBLOCK) { + Ok(tcp_fd) => match syscall::open(":tcp", O_RDWR | O_CREAT | O_NONBLOCK) { + Ok(scheme_fd) => { + // Daemonize + if unsafe { syscall::clone(0).unwrap() } == 0 { + daemon(tcp_fd, scheme_fd); + } + }, + Err(err) => { + println!("tcpd: failed to create tcp scheme: {}", err); + process::exit(1); + } + }, + Err(err) => { + println!("tcpd: failed to open ip:6: {}", err); + process::exit(1); + } } } diff --git a/schemes/udpd/src/main.rs b/schemes/udpd/src/main.rs index bd51751..2c9396a 100644 --- a/schemes/udpd/src/main.rs +++ b/schemes/udpd/src/main.rs @@ -8,7 +8,7 @@ use std::collections::{BTreeMap, VecDeque}; use std::cell::RefCell; use std::fs::File; use std::io::{self, Read, Write}; -use std::{mem, slice, str}; +use std::{mem, process, slice, str}; use std::ops::{Deref, DerefMut}; use std::os::unix::io::FromRawFd; use std::rc::Rc; @@ -450,33 +450,47 @@ impl SchemeMut for Udpd { Ok(0) } } +fn daemon(udp_fd: usize, scheme_fd: usize) { + let udp_file = unsafe { File::from_raw_fd(udp_fd) }; + let scheme_file = unsafe { File::from_raw_fd(scheme_fd) }; + + let udpd = Rc::new(RefCell::new(Udpd::new(scheme_file, udp_file))); + + let mut event_queue = EventQueue::<()>::new().expect("udpd: failed to create event queue"); + + let udp_udpd = udpd.clone(); + event_queue.add(udp_fd, move |_count: usize| -> io::Result> { + udp_udpd.borrow_mut().udp_event()?; + Ok(None) + }).expect("udpd: failed to listen to events on ip:11"); + + event_queue.add(scheme_fd, move |_count: usize| -> io::Result> { + udpd.borrow_mut().scheme_event()?; + Ok(None) + }).expect("udpd: failed to listen to events on :udp"); + + event_queue.trigger_all(0).expect("udpd: failed to trigger event queue"); + + event_queue.run().expect("udpd: failed to run event queue"); +} fn main() { - // Daemonize - if unsafe { syscall::clone(0).unwrap() } == 0 { - let scheme_fd = syscall::open(":udp", O_RDWR | O_CREAT | O_NONBLOCK).expect("udpd: failed to create :udp"); - let scheme_file = unsafe { File::from_raw_fd(scheme_fd) }; - - let udp_fd = syscall::open("ip:11", O_RDWR | O_NONBLOCK).expect("udpd: failed to open ip:11"); - let udp_file = unsafe { File::from_raw_fd(udp_fd) }; - - let udpd = Rc::new(RefCell::new(Udpd::new(scheme_file, udp_file))); - - let mut event_queue = EventQueue::<()>::new().expect("udpd: failed to create event queue"); - - let udp_udpd = udpd.clone(); - event_queue.add(udp_fd, move |_count: usize| -> io::Result> { - udp_udpd.borrow_mut().udp_event()?; - Ok(None) - }).expect("udpd: failed to listen to events on ip:11"); - - event_queue.add(scheme_fd, move |_count: usize| -> io::Result> { - udpd.borrow_mut().scheme_event()?; - Ok(None) - }).expect("udpd: failed to listen to events on :udp"); - - event_queue.trigger_all(0).expect("udpd: failed to trigger event queue"); - - event_queue.run().expect("udpd: failed to run event queue"); + match syscall::open("ip:11", O_RDWR | O_NONBLOCK) { + Ok(udp_fd) => match syscall::open(":udp", O_RDWR | O_CREAT | O_NONBLOCK) { + Ok(scheme_fd) => { + // Daemonize + if unsafe { syscall::clone(0).unwrap() } == 0 { + daemon(udp_fd, scheme_fd); + } + }, + Err(err) => { + println!("udpd: failed to create udp scheme: {}", err); + process::exit(1); + } + }, + Err(err) => { + println!("udpd: failed to open ip:11: {}", err); + process::exit(1); + } } }