From a559a10155ebc1f28a917bcc78fe6dfc462f0dd7 Mon Sep 17 00:00:00 2001 From: Dennis Schwerdel Date: Mon, 23 Nov 2015 01:04:30 +0100 Subject: [PATCH] types in extra module --- src/cloud.rs | 112 ++-------------------------------------------- src/device.rs | 2 +- src/ethernet.rs | 2 +- src/ip.rs | 2 +- src/main.rs | 4 +- src/types.rs | 111 +++++++++++++++++++++++++++++++++++++++++++++ src/udpmessage.rs | 2 +- 7 files changed, 121 insertions(+), 114 deletions(-) create mode 100644 src/types.rs diff --git a/src/cloud.rs b/src/cloud.rs index def8a14..3e62f08 100644 --- a/src/cloud.rs +++ b/src/cloud.rs @@ -1,9 +1,9 @@ -use std::net::{SocketAddr, ToSocketAddrs, Ipv4Addr, Ipv6Addr}; +use std::net::{SocketAddr, ToSocketAddrs}; use std::collections::HashMap; use std::hash::Hasher; use std::net::UdpSocket; use std::io::Read; -use std::{fmt, ptr}; +use std::fmt; use std::os::unix::io::AsRawFd; use std::marker::PhantomData; use std::str::FromStr; @@ -11,117 +11,11 @@ use std::str::FromStr; use time::{Duration, SteadyTime, precise_time_ns}; use epoll; +use super::types::{Table, Protocol, VirtualInterface, Range, Error, NetworkId, Behavior}; use super::device::{TunDevice, TapDevice}; use super::udpmessage::{encode, decode, Options, Message}; use super::ethernet::{Frame, MacTable}; use super::ip::{InternetProtocol, RoutingTable}; -use super::util::as_bytes; - - -pub type NetworkId = u64; - -#[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone)] -pub struct Address(pub Vec); - -impl fmt::Debug for Address { - fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { - match self.0.len() { - 4 => write!(formatter, "{}.{}.{}.{}", self.0[0], self.0[1], self.0[2], self.0[3]), - 6 => write!(formatter, "{:x}:{:x}:{:x}:{:x}:{:x}:{:x}", - self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5]), - 16 => write!(formatter, "{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}", - self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5], self.0[6], self.0[7], - self.0[8], self.0[9], self.0[10], self.0[11], self.0[12], self.0[13], self.0[14], self.0[15] - ), - _ => self.0.fmt(formatter) - } - } -} - -impl FromStr for Address { - type Err=Error; - - fn from_str(text: &str) -> Result { - if let Ok(addr) = Ipv4Addr::from_str(text) { - let ip = addr.octets(); - let mut res = Vec::with_capacity(4); - unsafe { - res.set_len(4); - ptr::copy_nonoverlapping(ip.as_ptr(), res.as_mut_ptr(), ip.len()); - } - return Ok(Address(res)); - } - if let Ok(addr) = Ipv6Addr::from_str(text) { - let mut segments = addr.segments(); - for i in 0..8 { - segments[i] = segments[i].to_be(); - } - let bytes = unsafe { as_bytes(&segments) }; - let mut res = Vec::with_capacity(16); - unsafe { - res.set_len(16); - ptr::copy_nonoverlapping(bytes.as_ptr(), res.as_mut_ptr(), bytes.len()); - } - return Ok(Address(res)); - } - //FIXME: implement for mac addresses - return Err(Error::ParseError("Failed to parse address")) - } -} - - -#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Clone)] -pub struct Range { - pub base: Address, - pub prefix_len: u8 -} - -impl FromStr for Range { - type Err=Error; - - fn from_str(text: &str) -> Result { - let pos = match text.find("/") { - Some(pos) => pos, - None => return Err(Error::ParseError("Invalid range format")) - }; - let prefix_len = try!(u8::from_str(&text[pos+1..]) - .map_err(|_| Error::ParseError("Failed to parse prefix length"))); - let base = try!(Address::from_str(&text[..pos])); - Ok(Range{base: base, prefix_len: prefix_len}) - } -} - - -#[derive(RustcDecodable, Debug)] -pub enum Behavior { - Normal, Hub, Switch, Router -} - -pub trait Table { - fn learn(&mut self, Address, Option, SocketAddr); - fn lookup(&self, &Address) -> Option; - fn housekeep(&mut self); - fn remove_all(&mut self, SocketAddr); -} - -pub trait Protocol: Sized { - fn parse(&[u8]) -> Result<(Address, Address), Error>; -} - -pub trait VirtualInterface: AsRawFd { - fn read(&mut self, &mut [u8]) -> Result; - fn write(&mut self, &[u8]) -> Result<(), Error>; -} - - -#[derive(Debug)] -pub enum Error { - ParseError(&'static str), - WrongNetwork(Option), - SocketError(&'static str), - TunTapDevError(&'static str), -} - struct PeerList { timeout: Duration, diff --git a/src/device.rs b/src/device.rs index 6a6479a..88030f2 100644 --- a/src/device.rs +++ b/src/device.rs @@ -3,7 +3,7 @@ use std::io::{Result as IoResult, Error as IoError, Read, Write}; use std::marker::PhantomData; use std::fs; -use super::cloud::{Error, VirtualInterface}; +use super::types::{Error, VirtualInterface}; extern { fn setup_tap_device(fd: i32, ifname: *mut u8) -> i32; diff --git a/src/ethernet.rs b/src/ethernet.rs index efe2624..896fd9e 100644 --- a/src/ethernet.rs +++ b/src/ethernet.rs @@ -2,7 +2,7 @@ use std::ptr; use std::net::SocketAddr; use std::collections::HashMap; -use super::cloud::{Error, Table, Protocol, Address}; +use super::types::{Error, Table, Protocol, Address}; use time::{Duration, SteadyTime}; diff --git a/src/ip.rs b/src/ip.rs index 767b683..0fcac50 100644 --- a/src/ip.rs +++ b/src/ip.rs @@ -2,7 +2,7 @@ use std::net::SocketAddr; use std::collections::{hash_map, HashMap}; use std::io::Read; -use super::cloud::{Protocol, Error, Table, Address}; +use super::types::{Protocol, Error, Table, Address}; use super::util::to_vec; #[allow(dead_code)] diff --git a/src/main.rs b/src/main.rs index ef5f4af..4ca3362 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ extern crate rustc_serialize; extern crate epoll; mod util; +mod types; mod udpmessage; mod ethernet; mod ip; @@ -16,7 +17,8 @@ use docopt::Docopt; use std::hash::{Hash, SipHasher, Hasher}; -use cloud::{Error, TapCloud, TunCloud, Behavior}; +use types::{Error, Behavior}; +use cloud::{TapCloud, TunCloud}; //TODO: hub behavior diff --git a/src/types.rs b/src/types.rs new file mode 100644 index 0000000..d3539f8 --- /dev/null +++ b/src/types.rs @@ -0,0 +1,111 @@ +use std::net::{SocketAddr, Ipv4Addr, Ipv6Addr}; +use std::hash::Hasher; +use std::{fmt, ptr}; +use std::os::unix::io::AsRawFd; +use std::str::FromStr; + +use super::util::as_bytes; + +pub type NetworkId = u64; + +#[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone)] +pub struct Address(pub Vec); + +impl fmt::Debug for Address { + fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { + match self.0.len() { + 4 => write!(formatter, "{}.{}.{}.{}", self.0[0], self.0[1], self.0[2], self.0[3]), + 6 => write!(formatter, "{:x}:{:x}:{:x}:{:x}:{:x}:{:x}", + self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5]), + 16 => write!(formatter, "{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}", + self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5], self.0[6], self.0[7], + self.0[8], self.0[9], self.0[10], self.0[11], self.0[12], self.0[13], self.0[14], self.0[15] + ), + _ => self.0.fmt(formatter) + } + } +} + +impl FromStr for Address { + type Err=Error; + + fn from_str(text: &str) -> Result { + if let Ok(addr) = Ipv4Addr::from_str(text) { + let ip = addr.octets(); + let mut res = Vec::with_capacity(4); + unsafe { + res.set_len(4); + ptr::copy_nonoverlapping(ip.as_ptr(), res.as_mut_ptr(), ip.len()); + } + return Ok(Address(res)); + } + if let Ok(addr) = Ipv6Addr::from_str(text) { + let mut segments = addr.segments(); + for i in 0..8 { + segments[i] = segments[i].to_be(); + } + let bytes = unsafe { as_bytes(&segments) }; + let mut res = Vec::with_capacity(16); + unsafe { + res.set_len(16); + ptr::copy_nonoverlapping(bytes.as_ptr(), res.as_mut_ptr(), bytes.len()); + } + return Ok(Address(res)); + } + //FIXME: implement for mac addresses + return Err(Error::ParseError("Failed to parse address")) + } +} + + +#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Clone)] +pub struct Range { + pub base: Address, + pub prefix_len: u8 +} + +impl FromStr for Range { + type Err=Error; + + fn from_str(text: &str) -> Result { + let pos = match text.find("/") { + Some(pos) => pos, + None => return Err(Error::ParseError("Invalid range format")) + }; + let prefix_len = try!(u8::from_str(&text[pos+1..]) + .map_err(|_| Error::ParseError("Failed to parse prefix length"))); + let base = try!(Address::from_str(&text[..pos])); + Ok(Range{base: base, prefix_len: prefix_len}) + } +} + + +#[derive(RustcDecodable, Debug)] +pub enum Behavior { + Normal, Hub, Switch, Router +} + +pub trait Table { + fn learn(&mut self, Address, Option, SocketAddr); + fn lookup(&self, &Address) -> Option; + fn housekeep(&mut self); + fn remove_all(&mut self, SocketAddr); +} + +pub trait Protocol: Sized { + fn parse(&[u8]) -> Result<(Address, Address), Error>; +} + +pub trait VirtualInterface: AsRawFd { + fn read(&mut self, &mut [u8]) -> Result; + fn write(&mut self, &[u8]) -> Result<(), Error>; +} + + +#[derive(Debug)] +pub enum Error { + ParseError(&'static str), + WrongNetwork(Option), + SocketError(&'static str), + TunTapDevError(&'static str), +} diff --git a/src/udpmessage.rs b/src/udpmessage.rs index e0a9e41..3cbc234 100644 --- a/src/udpmessage.rs +++ b/src/udpmessage.rs @@ -2,7 +2,7 @@ use std::{mem, ptr, fmt}; use std::net::{SocketAddr, SocketAddrV4, Ipv4Addr}; use std::u16; -use super::cloud::{Error, NetworkId, Range, Address}; +use super::types::{Error, NetworkId, Range, Address}; use super::util::{as_obj, as_bytes, to_vec}; const MAGIC: [u8; 3] = [0x76, 0x70, 0x6e];