vpncloud/src/ethernet.rs

121 lines
3.5 KiB
Rust
Raw Normal View History

2015-11-22 23:49:58 +00:00
use std::ptr;
2015-11-21 15:50:50 +00:00
use std::net::SocketAddr;
use std::collections::HashMap;
2015-11-19 15:34:20 +00:00
2015-11-22 21:00:34 +00:00
use super::cloud::{Error, Table, Protocol, Address};
2015-11-19 15:34:20 +00:00
2015-11-21 15:50:50 +00:00
use time::{Duration, SteadyTime};
2015-11-22 16:28:04 +00:00
2015-11-19 15:34:20 +00:00
#[derive(PartialEq)]
2015-11-22 17:05:15 +00:00
pub struct Frame;
2015-11-21 17:09:13 +00:00
2015-11-22 17:05:15 +00:00
impl Protocol for Frame {
2015-11-22 23:49:58 +00:00
fn parse(data: &[u8]) -> Result<(Address, Address), Error> {
2015-11-22 15:48:01 +00:00
if data.len() < 14 {
return Err(Error::ParseError("Frame is too short"));
}
let mut pos = 0;
2015-11-22 23:49:58 +00:00
let dst_data = &data[pos..pos+6];
pos += 6;
let src_data = &data[pos..pos+6];
pos += 6;
2015-11-22 15:48:01 +00:00
if data[pos] == 0x81 && data[pos+1] == 0x00 {
pos += 2;
if data.len() < pos + 2 {
return Err(Error::ParseError("Vlan frame is too short"));
}
2015-11-22 23:49:58 +00:00
let mut src = Vec::with_capacity(8);
let mut dst = Vec::with_capacity(8);
unsafe {
ptr::copy_nonoverlapping(data.as_ptr(), src.as_mut_ptr(), 2);
ptr::copy_nonoverlapping(src_data.as_ptr(), src[2..].as_mut_ptr(), 6);
src.set_len(8);
ptr::copy_nonoverlapping(data.as_ptr(), dst.as_mut_ptr(), 2);
ptr::copy_nonoverlapping(dst_data.as_ptr(), dst[2..].as_mut_ptr(), 6);
dst.set_len(8);
}
Ok((Address(src), Address(dst)))
} else {
let mut src = Vec::with_capacity(6);
let mut dst = Vec::with_capacity(6);
unsafe {
ptr::copy_nonoverlapping(src_data.as_ptr(), src.as_mut_ptr(), 6);
src.set_len(6);
ptr::copy_nonoverlapping(dst_data.as_ptr(), dst.as_mut_ptr(), 6);
dst.set_len(6);
}
Ok((Address(src), Address(dst)))
2015-11-22 15:48:01 +00:00
}
}
}
2015-11-22 16:28:04 +00:00
2015-11-21 15:50:50 +00:00
struct MacTableValue {
address: SocketAddr,
timeout: SteadyTime
}
2015-11-22 16:28:04 +00:00
2015-11-21 15:50:50 +00:00
pub struct MacTable {
2015-11-22 23:49:58 +00:00
table: HashMap<Address, MacTableValue>,
2015-11-21 15:50:50 +00:00
timeout: Duration
}
impl MacTable {
pub fn new(timeout: Duration) -> MacTable {
MacTable{table: HashMap::new(), timeout: timeout}
}
2015-11-21 17:09:13 +00:00
}
impl Table for MacTable {
fn housekeep(&mut self) {
2015-11-21 15:50:50 +00:00
let now = SteadyTime::now();
2015-11-22 23:49:58 +00:00
let mut del: Vec<Address> = Vec::new();
for (key, val) in &self.table {
2015-11-21 15:50:50 +00:00
if val.timeout < now {
2015-11-22 23:49:58 +00:00
del.push(key.clone());
2015-11-21 15:50:50 +00:00
}
}
for key in del {
2015-11-22 23:49:58 +00:00
info!("Forgot address {:?}", key);
2015-11-21 15:50:50 +00:00
self.table.remove(&key);
}
}
2015-11-22 23:49:58 +00:00
fn learn(&mut self, key: Address, _prefix_len: Option<u8>, addr: SocketAddr) {
2015-11-21 17:09:13 +00:00
let value = MacTableValue{address: addr, timeout: SteadyTime::now()+self.timeout};
2015-11-22 23:49:58 +00:00
if self.table.insert(key.clone(), value).is_none() {
info!("Learned address {:?} => {}", key, addr);
2015-11-21 15:50:50 +00:00
}
}
2015-11-22 23:49:58 +00:00
fn lookup(&self, key: &Address) -> Option<SocketAddr> {
2015-11-22 17:05:15 +00:00
match self.table.get(key) {
2015-11-21 15:50:50 +00:00
Some(value) => Some(value.address),
None => None
}
}
2015-11-22 21:00:34 +00:00
fn remove_all(&mut self, _addr: SocketAddr) {
unimplemented!()
}
2015-11-21 15:50:50 +00:00
}
2015-11-19 15:34:20 +00:00
#[test]
fn without_vlan() {
2015-11-22 17:05:15 +00:00
let data = [6,5,4,3,2,1,1,2,3,4,5,6,1,2,3,4,5,6,7,8];
let (src, dst) = Frame::parse(&data).unwrap();
2015-11-22 23:49:58 +00:00
assert_eq!(src, Address(vec![1,2,3,4,5,6]));
assert_eq!(dst, Address(vec![6,5,4,3,2,1]));
2015-11-19 15:34:20 +00:00
}
#[test]
fn with_vlan() {
2015-11-22 17:05:15 +00:00
let data = [6,5,4,3,2,1,1,2,3,4,5,6,0x81,0,4,210,1,2,3,4,5,6,7,8];
let (src, dst) = Frame::parse(&data).unwrap();
2015-11-22 23:49:58 +00:00
assert_eq!(src, Address(vec![4,210,1,2,3,4,5,6]));
assert_eq!(dst, Address(vec![4,210,6,5,4,3,2,1]));
2015-11-19 15:34:20 +00:00
}