diff --git a/src/device.rs b/src/device.rs index c5be829..6a6479a 100644 --- a/src/device.rs +++ b/src/device.rs @@ -15,6 +15,7 @@ trait DeviceSetup { fn setup_device(RawFd, &str) -> IoResult; } +#[allow(dead_code)] struct TapSetup; impl DeviceSetup for TapSetup { @@ -31,7 +32,7 @@ impl DeviceSetup for TapSetup { } } - +#[allow(dead_code)] struct TunSetup; impl DeviceSetup for TunSetup { diff --git a/src/ethernet.rs b/src/ethernet.rs index 89f2480..b37aaa8 100644 --- a/src/ethernet.rs +++ b/src/ethernet.rs @@ -1,10 +1,9 @@ -use std::{mem, fmt, fs}; +use std::{mem, fmt}; use std::net::SocketAddr; use std::collections::HashMap; -use std::os::unix::io::{AsRawFd, RawFd}; -use std::io::{Result as IoResult, Error as IoError, Read, Write}; +use std::io::Write; -use super::cloud::{Error, Table, Protocol, VirtualInterface}; +use super::cloud::{Error, Table, Protocol}; use super::util::as_obj; use time::{Duration, SteadyTime}; diff --git a/src/ip.rs b/src/ip.rs index 708a99b..3dfc66f 100644 --- a/src/ip.rs +++ b/src/ip.rs @@ -53,7 +53,7 @@ impl IpAddress { } } - +#[allow(dead_code)] pub struct InternetProtocol; impl Protocol for InternetProtocol { diff --git a/src/main.rs b/src/main.rs index 5dfea2d..1ebaa95 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,8 +16,10 @@ use time::Duration; use docopt::Docopt; use std::hash::{Hash, SipHasher, Hasher}; +use std::path::PathBuf; -use cloud::{Error, TapCloud}; +use ip::RoutingTable; +use cloud::{Error, TapCloud, TunCloud}; //TODO: Implement IPv6 @@ -39,25 +41,34 @@ impl log::Log for SimpleLogger { } } - static USAGE: &'static str = " Usage: - ethcloud [options] [-d ] [-l ] [-c ...] + ethcloud [options] [-t ] [-d ] [-l ] [-c ...] Options: - -d , --device Name of the tap device [default: ethcloud%d] + -t , --type Set the type of network [default: tap] + -d , --device Name of the virtual device [default: cloud%d] -l , --listen Address to listen on [default: 0.0.0.0:3210] -c , --connect List of peers (addr:port) to connect to --network-id Optional token that identifies the network --peer-timeout Peer timeout in seconds [default: 1800] - --mac-timeout Mac table entry timeout in seconds [default: 300] + --table The file containing the routing table (only for tun) + --mac-timeout Mac table entry timeout in seconds (only for tap) [default: 300] -v, --verbose Log verbosely -q, --quiet Only print error messages -h, --help Display the help "; + +#[derive(RustcDecodable, Debug)] +enum Type { + Tun, Tap +} + #[derive(RustcDecodable, Debug)] struct Args { + flag_type: Type, + flag_table: PathBuf, flag_device: String, flag_listen: String, flag_network_id: Option, @@ -68,20 +79,7 @@ struct Args { flag_quiet: bool } -fn main() { - let args: Args = Docopt::new(USAGE).and_then(|d| d.decode()).unwrap_or_else(|e| e.exit()); - log::set_logger(|max_log_level| { - assert!(!args.flag_verbose || !args.flag_quiet); - if args.flag_verbose { - max_log_level.set(log::LogLevelFilter::Debug); - } else if args.flag_quiet { - max_log_level.set(log::LogLevelFilter::Error); - } else { - max_log_level.set(log::LogLevelFilter::Info); - } - Box::new(SimpleLogger) - }).unwrap(); - debug!("Args: {:?}", args); +fn tap_cloud(args: Args) { let mut tapcloud = TapCloud::new_tap_cloud( &args.flag_device, args.flag_listen, @@ -98,3 +96,43 @@ fn main() { } tapcloud.run() } + +fn tun_cloud(args: Args) { + let mut table = RoutingTable::new(); + table.load_from(&args.flag_table).unwrap(); + let mut tuncloud = TunCloud::new_tun_cloud( + &args.flag_device, + args.flag_listen, + args.flag_network_id.map(|name| { + let mut s = SipHasher::new(); + name.hash(&mut s); + s.finish() + }), + table, + Duration::seconds(args.flag_peer_timeout as i64) + ); + for addr in args.flag_connect { + tuncloud.connect(&addr as &str, true).expect("Failed to send"); + } + tuncloud.run() +} + +fn main() { + let args: Args = Docopt::new(USAGE).and_then(|d| d.decode()).unwrap_or_else(|e| e.exit()); + log::set_logger(|max_log_level| { + assert!(!args.flag_verbose || !args.flag_quiet); + if args.flag_verbose { + max_log_level.set(log::LogLevelFilter::Debug); + } else if args.flag_quiet { + max_log_level.set(log::LogLevelFilter::Error); + } else { + max_log_level.set(log::LogLevelFilter::Info); + } + Box::new(SimpleLogger) + }).unwrap(); + debug!("Args: {:?}", args); + match args.flag_type { + Type::Tap => tap_cloud(args), + Type::Tun => tun_cloud(args) + } +}