diff --git a/src/ethcloud.rs b/src/cloud.rs similarity index 94% rename from src/ethcloud.rs rename to src/cloud.rs index d174b3b..331a09d 100644 --- a/src/ethcloud.rs +++ b/src/cloud.rs @@ -10,9 +10,9 @@ use std::marker::PhantomData; use time::{Duration, SteadyTime, precise_time_ns}; use epoll; -use super::{ethernet, udpmessage}; -use super::udpmessage::{Options, Message}; -use super::ethernet::{TapDevice, MacTable}; +use super::udpmessage::{encode, decode, Options, Message}; +use super::ethernet::{Frame, EthAddr, TapDevice, MacTable}; + pub type NetworkId = u64; @@ -113,7 +113,8 @@ impl PeerList { } } -pub struct EthCloud, M: InterfaceMessage, I: VirtualInterface> { + +pub struct GenericCloud, M: InterfaceMessage, I: VirtualInterface> { peers: PeerList, reconnect_peers: Vec, table: T, @@ -127,13 +128,13 @@ pub struct EthCloud, M: InterfaceMessage, I: V _dummy_m: PhantomData, } -impl, M: InterfaceMessage, I: VirtualInterface> EthCloud { +impl, M: InterfaceMessage, I: VirtualInterface> GenericCloud { pub fn new(device: I, listen: String, network_id: Option, table: T, peer_timeout: Duration) -> Self { let socket = match UdpSocket::bind(&listen as &str) { Ok(socket) => socket, _ => panic!("Failed to open socket") }; - EthCloud{ + GenericCloud{ peers: PeerList::new(peer_timeout), reconnect_peers: Vec::new(), table: table, @@ -152,7 +153,7 @@ impl, M: InterfaceMessage, I: Virt debug!("Sending {:?} to {}", msg, addr); let mut options = Options::default(); options.network_id = self.network_id; - let size = udpmessage::encode(&options, msg, &mut self.buffer_out); + let size = encode(&options, msg, &mut self.buffer_out); match self.socket.send_to(&self.buffer_out[..size], addr) { Ok(written) if written == size => Ok(()), Ok(_) => Err(Error::SocketError("Sent out truncated packet")), @@ -281,7 +282,7 @@ impl, M: InterfaceMessage, I: Virt match &events[i as usize].data { &0 => match self.socket.recv_from(&mut buffer) { Ok((size, src)) => { - match udpmessage::decode(&buffer[..size]).and_then(|(options, msg)| self.handle_net_message(src, options, msg)) { + match decode(&buffer[..size]).and_then(|(options, msg)| self.handle_net_message(src, options, msg)) { Ok(_) => (), Err(e) => error!("Error: {:?}", e) } @@ -310,7 +311,8 @@ impl, M: InterfaceMessage, I: Virt } } -pub type TapCloud = EthCloud; + +pub type TapCloud = GenericCloud; impl TapCloud { pub fn new_tap_cloud(device: &str, listen: String, network_id: Option, mac_timeout: Duration, peer_timeout: Duration) -> Self { diff --git a/src/ethernet.rs b/src/ethernet.rs index c7b1aeb..d0df77d 100644 --- a/src/ethernet.rs +++ b/src/ethernet.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use std::os::unix::io::{AsRawFd, RawFd}; use std::io::{Result as IoResult, Error as IoError, Read, Write}; -use super::ethcloud::{Error, Table, InterfaceMessage, VirtualInterface}; +use super::cloud::{Error, Table, InterfaceMessage, VirtualInterface}; use super::util::{as_bytes, as_obj}; use time::{Duration, SteadyTime}; @@ -13,6 +13,7 @@ extern { fn setup_tap_device(fd: i32, ifname: *mut u8) -> i32; } + #[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Mac(pub [u8; 6]); @@ -31,6 +32,7 @@ pub struct EthAddr { pub vlan: Option } + #[derive(PartialEq)] pub struct Frame { pub src: EthAddr, @@ -101,6 +103,7 @@ impl InterfaceMessage for Frame { } } + pub struct TapDevice { fd: fs::File, ifname: String @@ -151,11 +154,13 @@ impl VirtualInterface for TapDevice { } } + struct MacTableValue { address: SocketAddr, timeout: SteadyTime } + pub struct MacTable { table: HashMap, timeout: Duration diff --git a/src/ip.rs b/src/ip.rs index 82b464e..24b58e9 100644 --- a/src/ip.rs +++ b/src/ip.rs @@ -1,5 +1,59 @@ -use std::net::SocketAddr; +use std::net::{SocketAddr, Ipv4Addr, Ipv6Addr}; use std::collections::{hash_map, HashMap}; +use std::fmt; + +use super::cloud::{InterfaceMessage, Error}; +use super::util::{as_obj, as_bytes}; + + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum IpAddress { + V4(Ipv4Addr), + V6(Ipv6Addr) +} + +#[derive(PartialEq)] +pub enum IpHeader { + V4{src: Ipv4Addr, dst: Ipv4Addr}, + V6{src: Ipv6Addr, dst: Ipv6Addr} +} + +impl fmt::Debug for IpHeader { + fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { + match self { + &IpHeader::V4{src, dst} => write!(formatter, "src: {}, dst: {}", src, dst), + &IpHeader::V6{src, dst} => write!(formatter, "src: {}, dst: {}", src, dst) + } + } +} + +impl InterfaceMessage for IpHeader { + type Address = IpAddress; + + fn src(&self) -> Self::Address { + match self { + &IpHeader::V4{src, dst: _} => IpAddress::V4(src), + &IpHeader::V6{src, dst: _} => IpAddress::V6(src) + } + } + + fn dst(&self) -> Self::Address { + match self { + &IpHeader::V4{src: _, dst} => IpAddress::V4(dst), + &IpHeader::V6{src: _, dst} => IpAddress::V6(dst) + } + } + + fn encode_to(&self, payload: &[u8], data: &mut [u8]) -> usize { + unimplemented!() + } + + fn parse_from(data: &[u8]) -> Result<(Self, &[u8]), Error> { + unimplemented!() + } +} + + struct RoutingEntry { address: SocketAddr, diff --git a/src/main.rs b/src/main.rs index 8de54dc..9c2ede8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,14 +8,14 @@ mod util; mod udpmessage; mod ethernet; mod ip; -mod ethcloud; +mod cloud; use time::Duration; use docopt::Docopt; use std::hash::{Hash, SipHasher, Hasher}; -use ethcloud::{Error, TapCloud}; +use cloud::{Error, TapCloud}; //TODO: Implement IPv6 diff --git a/src/udpmessage.rs b/src/udpmessage.rs index 6c695dc..6c66174 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::ethcloud::{Error, NetworkId, InterfaceMessage}; +use super::cloud::{Error, NetworkId, InterfaceMessage}; use super::ethernet; use super::util::{as_obj, as_bytes};