Files
RedBear-OS/src/icmpd/main.rs
T
2017-06-12 19:59:25 +03:00

79 lines
2.1 KiB
Rust

extern crate event;
extern crate syscall;
extern crate netutils;
use error::{Result, Error};
use event::EventQueue;
use scheme::Icmpd;
use std::cell::RefCell;
use std::fs::File;
use std::os::unix::io::{RawFd, FromRawFd};
use std::process;
use std::rc::Rc;
mod error;
mod packet;
mod scheme;
fn run() -> Result<()> {
use syscall::flag::*;
if unsafe { syscall::clone(0).unwrap() } != 0 {
return Ok(());
}
let icmp_fd = syscall::open("ip:1", O_RDWR | O_NONBLOCK)
.map_err(|e| Error::from_syscall_error(e, "failed to open ip:1"))? as
RawFd;
let scheme_fd = syscall::open(":icmp", O_RDWR | O_CREAT | O_NONBLOCK)
.map_err(|e| Error::from_syscall_error(e, "failed to open :icmp"))? as
RawFd;
let icmpd = Rc::new(RefCell::new(Icmpd::new(unsafe { File::from_raw_fd(icmp_fd) },
unsafe { File::from_raw_fd(scheme_fd) })));
let mut event_queue =
EventQueue::<(), Error>::new()
.map_err(|e| Error::from_io_error(e, "failed to create event queue"))?;
let icmpd_ = icmpd.clone();
event_queue
.add(icmp_fd, move |_fd| {
if let Err(err) = icmpd_.borrow_mut().on_icmp_packet() {
if err.is_unrecoverable() {
return Err(err);
} else {
println!("icmpd: network error: {}", err);
}
}
Ok(None)
})
.map_err(|e| Error::from_io_error(e, "failed to listen to events on ip:1"))?;
event_queue
.add(scheme_fd, move |_fd| {
if let Err(err) = icmpd.borrow_mut().on_scheme_event() {
if err.is_unrecoverable() {
return Err(err);
} else {
println!("icmpd: scheme error: {}", err);
}
}
Ok(None)
})
.map_err(|e| Error::from_io_error(e, "failed to listen to events on icmp"))?;
event_queue.run()
}
fn main() {
if let Err(err) = run() {
println!("icmpd: {}", err);
process::exit(1);
}
process::exit(0);
}