diff --git a/programs/netutils b/programs/netutils index 25c1366..a45673a 160000 --- a/programs/netutils +++ b/programs/netutils @@ -1 +1 @@ -Subproject commit 25c136612217ade85a0ca64ddfe3f95e5086b593 +Subproject commit a45673aa948fe6d172a0e2b42ade86e0567c3afd diff --git a/schemes/ethernetd/Cargo.toml b/schemes/ethernetd/Cargo.toml index be6bd95..e7f1e03 100644 --- a/schemes/ethernetd/Cargo.toml +++ b/schemes/ethernetd/Cargo.toml @@ -3,5 +3,6 @@ name = "ethernetd" version = "0.1.0" [dependencies] +netutils = { path = "../../programs/netutils/" } resource_scheme = { path = "../../crates/resource_scheme/" } syscall = { path = "../../syscall/" } diff --git a/schemes/ethernetd/src/common.rs b/schemes/ethernetd/src/common.rs deleted file mode 100644 index 12ebd5a..0000000 --- a/schemes/ethernetd/src/common.rs +++ /dev/null @@ -1,105 +0,0 @@ -use std::{mem, slice, u8, u16}; - -#[derive(Copy, Clone)] -#[allow(non_camel_case_types)] -#[repr(packed)] -pub struct n16(u16); - -impl n16 { - pub fn new(value: u16) -> Self { - n16(value.to_be()) - } - - pub fn get(&self) -> u16 { - u16::from_be(self.0) - } - - pub fn set(&mut self, value: u16) { - self.0 = value.to_be(); - } -} - -#[derive(Copy, Clone)] -pub struct MacAddr { - pub bytes: [u8; 6], -} - -impl MacAddr { - pub fn equals(&self, other: Self) -> bool { - for i in 0..6 { - if self.bytes[i] != other.bytes[i] { - return false; - } - } - true - } - - pub fn from_str(string: &str) -> Self { - let mut addr = MacAddr { bytes: [0, 0, 0, 0, 0, 0] }; - - let mut i = 0; - for part in string.split('.') { - let octet = u8::from_str_radix(part, 16).unwrap_or(0); - match i { - 0 => addr.bytes[0] = octet, - 1 => addr.bytes[1] = octet, - 2 => addr.bytes[2] = octet, - 3 => addr.bytes[3] = octet, - 4 => addr.bytes[4] = octet, - 5 => addr.bytes[5] = octet, - _ => break, - } - i += 1; - } - - addr - } - - pub fn to_string(&self) -> String { - let mut string = String::new(); - for i in 0..6 { - if i > 0 { - string.push('.'); - } - string.push_str(&format!("{:X}", self.bytes[i])); - } - string - } -} - -#[derive(Copy, Clone)] -#[repr(packed)] -pub struct EthernetIIHeader { - pub dst: MacAddr, - pub src: MacAddr, - pub ethertype: n16, -} - -pub struct EthernetII { - pub header: EthernetIIHeader, - pub data: Vec, -} - -impl EthernetII { - pub fn from_bytes(bytes: &[u8]) -> Option { - if bytes.len() >= mem::size_of::() { - unsafe { - return Some(EthernetII { - header: *(bytes.as_ptr() as *const EthernetIIHeader), - data: bytes[mem::size_of::() ..].to_vec(), - }); - } - } - None - } - - pub fn to_bytes(&self) -> Vec { - unsafe { - let header_ptr: *const EthernetIIHeader = &self.header; - let mut ret = Vec::from(slice::from_raw_parts(header_ptr as *const u8, - mem::size_of::())); - ret.extend_from_slice(&self.data); - ret - } - } -} diff --git a/schemes/ethernetd/src/main.rs b/schemes/ethernetd/src/main.rs index 23d6c55..861264c 100644 --- a/schemes/ethernetd/src/main.rs +++ b/schemes/ethernetd/src/main.rs @@ -1,3 +1,4 @@ +extern crate netutils; extern crate resource_scheme; extern crate syscall; @@ -10,9 +11,8 @@ use syscall::Packet; use scheme::EthernetScheme; -pub mod common; -pub mod resource; -pub mod scheme; +mod resource; +mod scheme; fn main() { thread::spawn(move || { diff --git a/schemes/ethernetd/src/resource.rs b/schemes/ethernetd/src/resource.rs index d991aa5..6f9b18f 100644 --- a/schemes/ethernetd/src/resource.rs +++ b/schemes/ethernetd/src/resource.rs @@ -1,11 +1,10 @@ use std::{cmp, mem}; +use netutils::{n16, MacAddr, EthernetIIHeader, EthernetII}; use resource_scheme::Resource; use syscall; use syscall::error::*; -use common::{n16, MacAddr, EthernetIIHeader, EthernetII}; - /// A ethernet resource pub struct EthernetResource { /// The network diff --git a/schemes/ethernetd/src/scheme.rs b/schemes/ethernetd/src/scheme.rs index 427dc13..a56924f 100644 --- a/schemes/ethernetd/src/scheme.rs +++ b/schemes/ethernetd/src/scheme.rs @@ -1,11 +1,11 @@ use std::{str, u16}; +use netutils::{MacAddr, EthernetII}; use resource_scheme::ResourceScheme; use syscall; use syscall::error::{Error, Result, EACCES, ENOENT, EINVAL}; use syscall::flag::O_RDWR; -use common::{MacAddr, EthernetII}; use resource::EthernetResource; pub struct EthernetScheme; diff --git a/schemes/ipd/Cargo.toml b/schemes/ipd/Cargo.toml index 26987e8..b7359cb 100644 --- a/schemes/ipd/Cargo.toml +++ b/schemes/ipd/Cargo.toml @@ -3,5 +3,6 @@ name = "ipd" version = "0.1.0" [dependencies] +netutils = { path = "../../programs/netutils/" } resource_scheme = { path = "../../crates/resource_scheme/" } syscall = { path = "../../syscall/" } diff --git a/schemes/ipd/src/common.rs b/schemes/ipd/src/common.rs deleted file mode 100644 index 403bcdc..0000000 --- a/schemes/ipd/src/common.rs +++ /dev/null @@ -1,275 +0,0 @@ -use std::{mem, slice, u8, u16}; - -pub static mut MAC_ADDR: MacAddr = MacAddr { bytes: [0x50, 0x51, 0x52, 0x53, 0x54, 0x55] }; -pub static BROADCAST_MAC_ADDR: MacAddr = MacAddr { bytes: [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] }; - -pub static mut IP_ADDR: Ipv4Addr = Ipv4Addr { bytes: [10, 0, 2, 15] }; -pub static mut IP_ROUTER_ADDR: Ipv4Addr = Ipv4Addr { bytes: [10, 0, 2, 2] }; -pub static mut IP_SUBNET: Ipv4Addr = Ipv4Addr { bytes: [255, 255, 255, 0] }; -pub static BROADCAST_IP_ADDR: Ipv4Addr = Ipv4Addr { bytes: [255, 255, 255, 255] }; - -#[derive(Copy, Clone)] -#[allow(non_camel_case_types)] -#[repr(packed)] -pub struct n16(u16); - -impl n16 { - pub fn new(value: u16) -> Self { - n16(value.to_be()) - } - - pub fn get(&self) -> u16 { - u16::from_be(self.0) - } - - pub fn set(&mut self, value: u16) { - self.0 = value.to_be(); - } -} - -#[derive(Copy, Clone)] -pub struct MacAddr { - pub bytes: [u8; 6], -} - -impl MacAddr { - pub fn equals(&self, other: Self) -> bool { - for i in 0..6 { - if self.bytes[i] != other.bytes[i] { - return false; - } - } - true - } - - pub fn from_str(string: &str) -> Self { - let mut addr = MacAddr { bytes: [0, 0, 0, 0, 0, 0] }; - - let mut i = 0; - for part in string.split('.') { - let octet = u8::from_str_radix(part, 16).unwrap_or(0); - match i { - 0 => addr.bytes[0] = octet, - 1 => addr.bytes[1] = octet, - 2 => addr.bytes[2] = octet, - 3 => addr.bytes[3] = octet, - 4 => addr.bytes[4] = octet, - 5 => addr.bytes[5] = octet, - _ => break, - } - i += 1; - } - - addr - } - - pub fn to_string(&self) -> String { - let mut string = String::new(); - for i in 0..6 { - if i > 0 { - string.push('.'); - } - string.push_str(&format!("{:X}", self.bytes[i])); - } - string - } -} - -#[derive(Copy, Clone)] -pub struct Ipv4Addr { - pub bytes: [u8; 4], -} - -impl Ipv4Addr { - pub fn equals(&self, other: Self) -> bool { - for i in 0..4 { - if self.bytes[i] != other.bytes[i] { - return false; - } - } - true - } - - pub fn from_str(string: &str) -> Self { - let mut addr = Ipv4Addr { bytes: [0, 0, 0, 0] }; - - let mut i = 0; - for part in string.split('.') { - let octet = part.parse::().unwrap_or(0); - match i { - 0 => addr.bytes[0] = octet, - 1 => addr.bytes[1] = octet, - 2 => addr.bytes[2] = octet, - 3 => addr.bytes[3] = octet, - _ => break, - } - i += 1; - } - - addr - } - - pub fn to_string(&self) -> String { - let mut string = String::new(); - - for i in 0..4 { - if i > 0 { - string = string + "."; - } - string = string + &format!("{}", self.bytes[i]); - } - - string - } -} - -#[derive(Copy, Clone)] -pub struct Checksum { - pub data: u16, -} - -impl Checksum { - pub unsafe fn check(&self, mut ptr: usize, mut len: usize) -> bool { - let mut sum: usize = 0; - while len > 1 { - sum += *(ptr as *const u16) as usize; - len -= 2; - ptr += 2; - } - - if len > 0 { - sum += *(ptr as *const u8) as usize; - } - - while (sum >> 16) > 0 { - sum = (sum & 0xFFFF) + (sum >> 16); - } - - sum == 0xFFFF - } - - pub unsafe fn calculate(&mut self, ptr: usize, len: usize) { - self.data = 0; - - let sum = Checksum::sum(ptr, len); - - self.data = Checksum::compile(sum); - } - - pub unsafe fn sum(mut ptr: usize, mut len: usize) -> usize { - let mut sum = 0; - - while len > 1 { - sum += *(ptr as *const u16) as usize; - len -= 2; - ptr += 2; - } - - if len > 0 { - sum += *(ptr as *const u8) as usize; - } - - sum - } - - pub fn compile(mut sum: usize) -> u16 { - while (sum >> 16) > 0 { - sum = (sum & 0xFFFF) + (sum >> 16); - } - - 0xFFFF - (sum as u16) - } -} - -#[derive(Copy, Clone)] -#[repr(packed)] -pub struct ArpHeader { - pub htype: n16, - pub ptype: n16, - pub hlen: u8, - pub plen: u8, - pub oper: n16, - pub src_mac: MacAddr, - pub src_ip: Ipv4Addr, - pub dst_mac: MacAddr, - pub dst_ip: Ipv4Addr, -} - -pub struct Arp { - pub header: ArpHeader, - pub data: Vec, -} - -impl Arp { - pub fn from_bytes(bytes: &[u8]) -> Option { - if bytes.len() >= mem::size_of::() { - unsafe { - return Some(Arp { - header: *(bytes.as_ptr() as *const ArpHeader), - data: bytes[mem::size_of::() ..].to_vec(), - }); - } - } - None - } - - pub fn to_bytes(&self) -> Vec { - unsafe { - let header_ptr: *const ArpHeader = &self.header; - let mut ret = Vec::from(slice::from_raw_parts(header_ptr as *const u8, - mem::size_of::())); - ret.extend_from_slice(&self.data); - ret - } - } -} - -#[derive(Copy, Clone)] -#[repr(packed)] -pub struct Ipv4Header { - pub ver_hlen: u8, - pub services: u8, - pub len: n16, - pub id: n16, - pub flags_fragment: n16, - pub ttl: u8, - pub proto: u8, - pub checksum: Checksum, - pub src: Ipv4Addr, - pub dst: Ipv4Addr, -} - -pub struct Ipv4 { - pub header: Ipv4Header, - pub options: Vec, - pub data: Vec, -} - -impl Ipv4 { - pub fn from_bytes(bytes: &[u8]) -> Option { - if bytes.len() >= mem::size_of::() { - unsafe { - let header = *(bytes.as_ptr() as *const Ipv4Header); - let header_len = ((header.ver_hlen & 0xF) << 2) as usize; - - return Some(Ipv4 { - header: header, - options: bytes[mem::size_of::() .. header_len].to_vec(), - data: bytes[header_len .. header.len.get() as usize].to_vec(), - }); - } - } - None - } - - pub fn to_bytes(&self) -> Vec { - unsafe { - let header_ptr: *const Ipv4Header = &self.header; - let mut ret = Vec::::from(slice::from_raw_parts(header_ptr as *const u8, - mem::size_of::())); - ret.extend_from_slice(&self.options); - ret.extend_from_slice(&self.data); - ret - } - } -} diff --git a/schemes/ipd/src/main.rs b/schemes/ipd/src/main.rs index 4ebb15f..f3bb7d3 100644 --- a/schemes/ipd/src/main.rs +++ b/schemes/ipd/src/main.rs @@ -1,5 +1,6 @@ #![feature(rand)] +extern crate netutils; extern crate resource_scheme; extern crate syscall; @@ -12,9 +13,8 @@ use syscall::Packet; use scheme::IpScheme; -pub mod common; -pub mod resource; -pub mod scheme; +mod resource; +mod scheme; fn main() { thread::spawn(move || { diff --git a/schemes/ipd/src/resource.rs b/schemes/ipd/src/resource.rs index d1c4a8d..2e0b1ac 100644 --- a/schemes/ipd/src/resource.rs +++ b/schemes/ipd/src/resource.rs @@ -1,15 +1,15 @@ use std::{cmp, mem}; +use netutils::{n16, Ipv4Addr, Checksum, Ipv4Header, Ipv4}; use resource_scheme::Resource; use syscall; use syscall::error::*; -use common::{n16, Ipv4Addr, Checksum, Ipv4Header, Ipv4, IP_ADDR, BROADCAST_IP_ADDR}; - /// A IP (internet protocole) resource pub struct IpResource { pub link: usize, pub data: Vec, + pub host_addr: Ipv4Addr, pub peer_addr: Ipv4Addr, pub proto: u8, pub id: u16, @@ -21,6 +21,7 @@ impl Resource for IpResource { Ok(Box::new(IpResource { link: link, data: self.data.clone(), + host_addr: self.host_addr, peer_addr: self.peer_addr, proto: self.proto, id: self.id, @@ -55,8 +56,8 @@ impl Resource for IpResource { if let Some(packet) = Ipv4::from_bytes(&bytes[..count]) { if packet.header.proto == self.proto && - (packet.header.dst.equals(unsafe { IP_ADDR }) || packet.header.dst.equals(BROADCAST_IP_ADDR)) && - (packet.header.src.equals(self.peer_addr) || self.peer_addr.equals(BROADCAST_IP_ADDR)) { + (packet.header.dst.equals(self.host_addr) || packet.header.dst.equals(Ipv4Addr::BROADCAST)) && + (packet.header.src.equals(self.peer_addr) || self.peer_addr.equals(Ipv4Addr::BROADCAST)) { for (b, d) in buf.iter_mut().zip(packet.data.iter()) { *b = *d; } @@ -82,7 +83,7 @@ impl Resource for IpResource { ttl: 128, proto: self.proto, checksum: Checksum { data: 0 }, - src: unsafe { IP_ADDR }, + src: self.host_addr, dst: self.peer_addr, }, options: Vec::new(), diff --git a/schemes/ipd/src/scheme.rs b/schemes/ipd/src/scheme.rs index 6aa8034..47808dc 100644 --- a/schemes/ipd/src/scheme.rs +++ b/schemes/ipd/src/scheme.rs @@ -2,12 +2,12 @@ use std::cell::RefCell; use std::rand; use std::{str, u16}; +use netutils::{getcfg, n16, MacAddr, Ipv4Addr, ArpHeader, Arp, Ipv4}; use resource_scheme::ResourceScheme; use syscall; use syscall::error::{Error, Result, EACCES, ENOENT, EINVAL}; use syscall::flag::O_RDWR; -use common::{n16, MacAddr, Ipv4Addr, ArpHeader, Arp, Ipv4, MAC_ADDR, BROADCAST_MAC_ADDR, BROADCAST_IP_ADDR, IP_ADDR, IP_ROUTER_ADDR, IP_SUBNET}; use resource::IpResource; /// A ARP entry (MAC + IP) @@ -32,6 +32,11 @@ impl IpScheme { impl ResourceScheme for IpScheme { fn open_resource(&self, url: &[u8], _flags: usize, uid: u32, _gid: u32) -> Result> { if uid == 0 { + let mac_addr = MacAddr::from_str(&getcfg("mac").map_err(|err| err.into_sys())?); + let ip_addr = Ipv4Addr::from_str(&getcfg("ip").map_err(|err| err.into_sys())?); + let ip_subnet = Ipv4Addr::from_str(&getcfg("ip_subnet").map_err(|err| err.into_sys())?); + let ip_router = Ipv4Addr::from_str(&getcfg("ip_router").map_err(|err| err.into_sys())?); + let path = try!(str::from_utf8(url).or(Err(Error::new(EINVAL)))); let mut parts = path.split('/'); if let Some(host_string) = parts.next() { @@ -40,14 +45,14 @@ impl ResourceScheme for IpScheme { if ! host_string.is_empty() { let peer_addr = Ipv4Addr::from_str(host_string); - let mut route_mac = BROADCAST_MAC_ADDR; + let mut route_mac = MacAddr::BROADCAST; - if ! peer_addr.equals(BROADCAST_IP_ADDR) { + if ! peer_addr.equals(Ipv4Addr::BROADCAST) { let mut needs_routing = false; for octet in 0..4 { - let me = unsafe { IP_ADDR.bytes[octet] }; - let mask = unsafe { IP_SUBNET.bytes[octet] }; + let me = ip_addr.bytes[octet]; + let mask = ip_subnet.bytes[octet]; let them = peer_addr.bytes[octet]; if me & mask != them & mask { needs_routing = true; @@ -56,7 +61,7 @@ impl ResourceScheme for IpScheme { } let route_addr = if needs_routing { - unsafe { IP_ROUTER_ADDR } + ip_router } else { peer_addr }; @@ -68,7 +73,7 @@ impl ResourceScheme for IpScheme { } } - if route_mac.equals(BROADCAST_MAC_ADDR) { + if route_mac.equals(MacAddr::BROADCAST) { if let Ok(link) = syscall::open(&format!("ethernet:{}/806", &route_mac.to_string()), O_RDWR) { let arp = Arp { header: ArpHeader { @@ -77,8 +82,8 @@ impl ResourceScheme for IpScheme { hlen: 6, plen: 4, oper: n16::new(1), - src_mac: unsafe { MAC_ADDR }, - src_ip: unsafe { IP_ADDR }, + src_mac: mac_addr, + src_ip: ip_addr, dst_mac: route_mac, dst_ip: route_addr, }, @@ -113,6 +118,7 @@ impl ResourceScheme for IpScheme { return Ok(Box::new(IpResource { link: link, data: Vec::new(), + host_addr: ip_addr, peer_addr: peer_addr, proto: proto, id: (rand() % 65536) as u16, @@ -125,10 +131,11 @@ impl ResourceScheme for IpScheme { Ok(count) => { if let Some(packet) = Ipv4::from_bytes(&bytes[..count]) { if packet.header.proto == proto && - (packet.header.dst.equals(unsafe { IP_ADDR }) || packet.header.dst.equals(BROADCAST_IP_ADDR)) { + (packet.header.dst.equals(ip_addr) || packet.header.dst.equals(Ipv4Addr::BROADCAST)) { return Ok(Box::new(IpResource { link: link, data: packet.data, + host_addr: ip_addr, peer_addr: packet.header.src, proto: proto, id: (rand() % 65536) as u16, diff --git a/schemes/tcpd/Cargo.toml b/schemes/tcpd/Cargo.toml index 5b8c2c7..4fdf599 100644 --- a/schemes/tcpd/Cargo.toml +++ b/schemes/tcpd/Cargo.toml @@ -3,5 +3,6 @@ name = "tcpd" version = "0.1.0" [dependencies] +netutils = { path = "../../programs/netutils/" } resource_scheme = { path = "../../crates/resource_scheme/" } syscall = { path = "../../syscall/" } diff --git a/schemes/tcpd/src/common.rs b/schemes/tcpd/src/common.rs deleted file mode 100644 index 76b5633..0000000 --- a/schemes/tcpd/src/common.rs +++ /dev/null @@ -1,217 +0,0 @@ -use std::{mem, slice, u8, u16, u32}; - -pub static mut IP_ADDR: Ipv4Addr = Ipv4Addr { bytes: [10, 0, 2, 15] }; - -#[derive(Copy, Clone)] -#[allow(non_camel_case_types)] -#[repr(packed)] -pub struct n16(u16); - -impl n16 { - pub fn new(value: u16) -> Self { - n16(value.to_be()) - } - - pub fn get(&self) -> u16 { - u16::from_be(self.0) - } - - pub fn set(&mut self, value: u16) { - self.0 = value.to_be(); - } -} - -#[derive(Copy, Clone)] -#[allow(non_camel_case_types)] -#[repr(packed)] -pub struct n32(u32); - -impl n32 { - pub fn new(value: u32) -> Self { - n32(value.to_be()) - } - - pub fn get(&self) -> u32 { - u32::from_be(self.0) - } - - pub fn set(&mut self, value: u32) { - self.0 = value.to_be(); - } -} - -#[derive(Copy, Clone)] -pub struct Ipv4Addr { - pub bytes: [u8; 4], -} - -impl Ipv4Addr { - pub fn equals(&self, other: Self) -> bool { - for i in 0..4 { - if self.bytes[i] != other.bytes[i] { - return false; - } - } - true - } - - pub fn from_str(string: &str) -> Self { - let mut addr = Ipv4Addr { bytes: [0, 0, 0, 0] }; - - let mut i = 0; - for part in string.split('.') { - let octet = part.parse::().unwrap_or(0); - match i { - 0 => addr.bytes[0] = octet, - 1 => addr.bytes[1] = octet, - 2 => addr.bytes[2] = octet, - 3 => addr.bytes[3] = octet, - _ => break, - } - i += 1; - } - - addr - } - - pub fn to_string(&self) -> String { - let mut string = String::new(); - - for i in 0..4 { - if i > 0 { - string = string + "."; - } - string = string + &format!("{}", self.bytes[i]); - } - - string - } -} - -#[derive(Copy, Clone)] -pub struct Checksum { - pub data: u16, -} - -impl Checksum { - pub unsafe fn check(&self, mut ptr: usize, mut len: usize) -> bool { - let mut sum: usize = 0; - while len > 1 { - sum += *(ptr as *const u16) as usize; - len -= 2; - ptr += 2; - } - - if len > 0 { - sum += *(ptr as *const u8) as usize; - } - - while (sum >> 16) > 0 { - sum = (sum & 0xFFFF) + (sum >> 16); - } - - sum == 0xFFFF - } - - pub unsafe fn calculate(&mut self, ptr: usize, len: usize) { - self.data = 0; - - let sum = Checksum::sum(ptr, len); - - self.data = Checksum::compile(sum); - } - - pub unsafe fn sum(mut ptr: usize, mut len: usize) -> usize { - let mut sum = 0; - - while len > 1 { - sum += *(ptr as *const u16) as usize; - len -= 2; - ptr += 2; - } - - if len > 0 { - sum += *(ptr as *const u8) as usize; - } - - sum - } - - pub fn compile(mut sum: usize) -> u16 { - while (sum >> 16) > 0 { - sum = (sum & 0xFFFF) + (sum >> 16); - } - - 0xFFFF - (sum as u16) - } -} - -pub const TCP_FIN: u16 = 1; -pub const TCP_SYN: u16 = 1 << 1; -pub const TCP_RST: u16 = 1 << 2; -pub const TCP_PSH: u16 = 1 << 3; -pub const TCP_ACK: u16 = 1 << 4; - -#[derive(Copy, Clone)] -#[repr(packed)] -pub struct TcpHeader { - pub src: n16, - pub dst: n16, - pub sequence: n32, - pub ack_num: n32, - pub flags: n16, - pub window_size: n16, - pub checksum: Checksum, - pub urgent_pointer: n16, -} - -pub struct Tcp { - pub header: TcpHeader, - pub options: Vec, - pub data: Vec, -} - -impl Tcp { - pub fn checksum(&mut self, src_addr: &Ipv4Addr, dst_addr: &Ipv4Addr) { - self.header.checksum.data = 0; - - let proto = n16::new(0x06); - let segment_len = n16::new((mem::size_of::() + self.options.len() + self.data.len()) as u16); - self.header.checksum.data = Checksum::compile(unsafe { - Checksum::sum(src_addr.bytes.as_ptr() as usize, src_addr.bytes.len()) + - Checksum::sum(dst_addr.bytes.as_ptr() as usize, dst_addr.bytes.len()) + - Checksum::sum((&proto as *const n16) as usize, mem::size_of::()) + - Checksum::sum((&segment_len as *const n16) as usize, mem::size_of::()) + - Checksum::sum((&self.header as *const TcpHeader) as usize, mem::size_of::()) + - Checksum::sum(self.options.as_ptr() as usize, self.options.len()) + - Checksum::sum(self.data.as_ptr() as usize, self.data.len()) - }); - } - - pub fn from_bytes(bytes: &[u8]) -> Option { - if bytes.len() >= mem::size_of::() { - unsafe { - let header = *(bytes.as_ptr() as *const TcpHeader); - let header_len = ((header.flags.get() & 0xF000) >> 10) as usize; - - return Some(Tcp { - header: header, - options: bytes[mem::size_of::()..header_len].to_vec(), - data: bytes[header_len..bytes.len()].to_vec(), - }); - } - } - None - } - - pub fn to_bytes(&self) -> Vec { - unsafe { - let header_ptr: *const TcpHeader = &self.header; - let mut ret = Vec::from(slice::from_raw_parts(header_ptr as *const u8, - mem::size_of::())); - ret.extend_from_slice(&self.options); - ret.extend_from_slice(&self.data); - ret - } - } -} diff --git a/schemes/tcpd/src/main.rs b/schemes/tcpd/src/main.rs index cea3920..d830a5c 100644 --- a/schemes/tcpd/src/main.rs +++ b/schemes/tcpd/src/main.rs @@ -1,5 +1,6 @@ #![feature(rand)] +extern crate netutils; extern crate resource_scheme; extern crate syscall; @@ -12,9 +13,8 @@ use syscall::Packet; use scheme::TcpScheme; -pub mod common; -pub mod resource; -pub mod scheme; +mod resource; +mod scheme; fn main() { thread::spawn(move || { diff --git a/schemes/tcpd/src/resource.rs b/schemes/tcpd/src/resource.rs index ea71882..2729682 100644 --- a/schemes/tcpd/src/resource.rs +++ b/schemes/tcpd/src/resource.rs @@ -2,14 +2,14 @@ use std::{cmp, mem}; use std::cell::UnsafeCell; use std::sync::Arc; +use netutils::{n16, n32, Ipv4Addr, Checksum, Tcp, TcpHeader, TCP_SYN, TCP_PSH, TCP_FIN, TCP_ACK}; use resource_scheme::Resource; use syscall; use syscall::error::*; -use common::{n16, n32, Ipv4Addr, Checksum, IP_ADDR, Tcp, TcpHeader, TCP_SYN, TCP_PSH, TCP_FIN, TCP_ACK}; - pub struct TcpStream { pub ip: usize, + pub host_addr: Ipv4Addr, pub peer_addr: Ipv4Addr, pub peer_port: u16, pub host_port: u16, @@ -74,7 +74,7 @@ impl TcpStream { data: Vec::new() }; - tcp.checksum(& unsafe { IP_ADDR }, &self.peer_addr); + tcp.checksum(&self.host_addr, &self.peer_addr); //println!("Sending read ack: {} {} {:X}", tcp.header.sequence.get(), tcp.header.ack_num.get(), tcp.header.flags.get()); @@ -117,7 +117,7 @@ impl TcpStream { data: tcp_data, }; - tcp.checksum(& unsafe { IP_ADDR }, &self.peer_addr); + tcp.checksum(&self.host_addr, &self.peer_addr); match syscall::write(self.ip, &tcp.to_bytes()) { Ok(size) => { @@ -169,7 +169,7 @@ impl TcpStream { data: Vec::new(), }; - tcp.checksum(& unsafe { IP_ADDR }, &self.peer_addr); + tcp.checksum(&self.host_addr, &self.peer_addr); match syscall::write(self.ip, &tcp.to_bytes()) { Ok(_) => { @@ -203,7 +203,7 @@ impl TcpStream { data: Vec::new() }; - tcp.checksum(& unsafe { IP_ADDR }, &self.peer_addr); + tcp.checksum(&self.host_addr, &self.peer_addr); let _ = syscall::write(self.ip, &tcp.to_bytes()); @@ -242,7 +242,7 @@ impl TcpStream { data: Vec::new(), }; - tcp.checksum(& unsafe { IP_ADDR }, &self.peer_addr); + tcp.checksum(&self.host_addr, &self.peer_addr); match syscall::write(self.ip, &tcp.to_bytes()) { Ok(_) => { @@ -291,7 +291,7 @@ impl Drop for TcpStream { data: Vec::new(), }; - tcp.checksum(& unsafe { IP_ADDR }, &self.peer_addr); + tcp.checksum(&self.host_addr, &self.peer_addr); let _ = syscall::write(self.ip, &tcp.to_bytes()); let _ = syscall::close(self.ip); diff --git a/schemes/tcpd/src/scheme.rs b/schemes/tcpd/src/scheme.rs index 302b048..b1f3de2 100644 --- a/schemes/tcpd/src/scheme.rs +++ b/schemes/tcpd/src/scheme.rs @@ -3,12 +3,12 @@ use std::rand; use std::sync::Arc; use std::{str, u16}; +use netutils::{getcfg, Ipv4Addr, Tcp, TCP_SYN, TCP_ACK}; use resource_scheme::ResourceScheme; use syscall; use syscall::error::{Error, Result, ENOENT, EINVAL}; use syscall::flag::O_RDWR; -use common::{Ipv4Addr, Tcp, TCP_SYN, TCP_ACK}; use resource::{TcpResource, TcpStream}; /// A TCP scheme @@ -16,6 +16,8 @@ pub struct TcpScheme; impl ResourceScheme for TcpScheme { fn open_resource(&self, url: &[u8], _flags: usize, _uid: u32, _gid: u32) -> Result> { + let ip_addr = Ipv4Addr::from_str(&getcfg("ip").map_err(|err| err.into_sys())?); + let path = try!(str::from_utf8(url).or(Err(Error::new(EINVAL)))); let mut parts = path.split('/'); let remote = parts.next().unwrap_or(""); @@ -34,6 +36,7 @@ impl ResourceScheme for TcpScheme { Ok(ip) => { let mut stream = TcpStream { ip: ip, + host_addr: ip_addr, peer_addr: peer_addr, peer_port: peer_port, host_port: host_port, @@ -67,6 +70,7 @@ impl ResourceScheme for TcpScheme { let mut stream = TcpStream { ip: ip, + host_addr: ip_addr, peer_addr: Ipv4Addr::from_str(peer_addr), peer_port: segment.header.src.get(), host_port: host_port, diff --git a/schemes/udpd/Cargo.toml b/schemes/udpd/Cargo.toml index 9a2ae6a..6ea76ca 100644 --- a/schemes/udpd/Cargo.toml +++ b/schemes/udpd/Cargo.toml @@ -3,5 +3,6 @@ name = "udpd" version = "0.1.0" [dependencies] +netutils = { path = "../../programs/netutils/" } resource_scheme = { path = "../../crates/resource_scheme/" } syscall = { path = "../../syscall/" } diff --git a/schemes/udpd/src/common.rs b/schemes/udpd/src/common.rs deleted file mode 100644 index 3ffdb4c..0000000 --- a/schemes/udpd/src/common.rs +++ /dev/null @@ -1,167 +0,0 @@ -use std::{mem, slice, u8, u16}; - -pub static mut IP_ADDR: Ipv4Addr = Ipv4Addr { bytes: [10, 0, 2, 15] }; - -#[derive(Copy, Clone)] -#[allow(non_camel_case_types)] -#[repr(packed)] -pub struct n16(u16); - -impl n16 { - pub fn new(value: u16) -> Self { - n16(value.to_be()) - } - - pub fn get(&self) -> u16 { - u16::from_be(self.0) - } - - pub fn set(&mut self, value: u16) { - self.0 = value.to_be(); - } -} - -#[derive(Copy, Clone)] -pub struct Ipv4Addr { - pub bytes: [u8; 4], -} - -impl Ipv4Addr { - pub fn equals(&self, other: Self) -> bool { - for i in 0..4 { - if self.bytes[i] != other.bytes[i] { - return false; - } - } - true - } - - pub fn from_str(string: &str) -> Self { - let mut addr = Ipv4Addr { bytes: [0, 0, 0, 0] }; - - let mut i = 0; - for part in string.split('.') { - let octet = part.parse::().unwrap_or(0); - match i { - 0 => addr.bytes[0] = octet, - 1 => addr.bytes[1] = octet, - 2 => addr.bytes[2] = octet, - 3 => addr.bytes[3] = octet, - _ => break, - } - i += 1; - } - - addr - } - - pub fn to_string(&self) -> String { - let mut string = String::new(); - - for i in 0..4 { - if i > 0 { - string = string + "."; - } - string = string + &format!("{}", self.bytes[i]); - } - - string - } -} - -#[derive(Copy, Clone)] -pub struct Checksum { - pub data: u16, -} - -impl Checksum { - pub unsafe fn check(&self, mut ptr: usize, mut len: usize) -> bool { - let mut sum: usize = 0; - while len > 1 { - sum += *(ptr as *const u16) as usize; - len -= 2; - ptr += 2; - } - - if len > 0 { - sum += *(ptr as *const u8) as usize; - } - - while (sum >> 16) > 0 { - sum = (sum & 0xFFFF) + (sum >> 16); - } - - sum == 0xFFFF - } - - pub unsafe fn calculate(&mut self, ptr: usize, len: usize) { - self.data = 0; - - let sum = Checksum::sum(ptr, len); - - self.data = Checksum::compile(sum); - } - - pub unsafe fn sum(mut ptr: usize, mut len: usize) -> usize { - let mut sum = 0; - - while len > 1 { - sum += *(ptr as *const u16) as usize; - len -= 2; - ptr += 2; - } - - if len > 0 { - sum += *(ptr as *const u8) as usize; - } - - sum - } - - pub fn compile(mut sum: usize) -> u16 { - while (sum >> 16) > 0 { - sum = (sum & 0xFFFF) + (sum >> 16); - } - - 0xFFFF - (sum as u16) - } -} - -#[derive(Copy, Clone)] -#[repr(packed)] -pub struct UdpHeader { - pub src: n16, - pub dst: n16, - pub len: n16, - pub checksum: Checksum, -} - -pub struct Udp { - pub header: UdpHeader, - pub data: Vec, -} - -impl Udp { - pub fn from_bytes(bytes: &[u8]) -> Option { - if bytes.len() >= mem::size_of::() { - unsafe { - Option::Some(Udp { - header: *(bytes.as_ptr() as *const UdpHeader), - data: bytes[mem::size_of::()..bytes.len()].to_vec(), - }) - } - } else { - Option::None - } - } - - pub fn to_bytes(&self) -> Vec { - unsafe { - let header_ptr: *const UdpHeader = &self.header; - let mut ret = Vec::from(slice::from_raw_parts(header_ptr as *const u8, - mem::size_of::())); - ret.extend_from_slice(&self.data); - ret - } - } -} diff --git a/schemes/udpd/src/main.rs b/schemes/udpd/src/main.rs index e6eccaa..282a170 100644 --- a/schemes/udpd/src/main.rs +++ b/schemes/udpd/src/main.rs @@ -1,5 +1,6 @@ #![feature(rand)] +extern crate netutils; extern crate resource_scheme; extern crate syscall; @@ -12,9 +13,8 @@ use syscall::Packet; use scheme::UdpScheme; -pub mod common; -pub mod resource; -pub mod scheme; +mod resource; +mod scheme; fn main() { thread::spawn(move || { diff --git a/schemes/udpd/src/resource.rs b/schemes/udpd/src/resource.rs index a11dcd5..7119fb5 100644 --- a/schemes/udpd/src/resource.rs +++ b/schemes/udpd/src/resource.rs @@ -1,15 +1,15 @@ use std::{cmp, mem}; +use netutils::{n16, Ipv4Addr, Checksum, Udp, UdpHeader}; use resource_scheme::Resource; use syscall; use syscall::error::*; -use common::{n16, Ipv4Addr, Checksum, IP_ADDR, Udp, UdpHeader}; - /// UDP resource pub struct UdpResource { pub ip: usize, pub data: Vec, + pub host_addr: Ipv4Addr, pub peer_addr: Ipv4Addr, pub peer_port: u16, pub host_port: u16, @@ -22,6 +22,7 @@ impl Resource for UdpResource { Ok(Box::new(UdpResource { ip: ip, data: self.data.clone(), + host_addr: self.host_addr, peer_addr: self.peer_addr, peer_port: self.peer_port, host_port: self.host_port, @@ -92,7 +93,7 @@ impl Resource for UdpResource { let proto = n16::new(0x11); let datagram_len = n16::new((mem::size_of::() + udp.data.len()) as u16); udp.header.checksum.data = - Checksum::compile(Checksum::sum((&IP_ADDR as *const Ipv4Addr) as usize, + Checksum::compile(Checksum::sum((&self.host_addr as *const Ipv4Addr) as usize, mem::size_of::()) + Checksum::sum((&self.peer_addr as *const Ipv4Addr) as usize, mem::size_of::()) + diff --git a/schemes/udpd/src/scheme.rs b/schemes/udpd/src/scheme.rs index 91d9f62..aad5dee 100644 --- a/schemes/udpd/src/scheme.rs +++ b/schemes/udpd/src/scheme.rs @@ -1,12 +1,12 @@ use std::rand; use std::{str, u16}; +use netutils::{getcfg, Ipv4Addr, Udp}; use resource_scheme::ResourceScheme; use syscall; use syscall::error::{Error, Result, ENOENT, EINVAL}; use syscall::flag::O_RDWR; -use common::{Ipv4Addr, Udp}; use resource::UdpResource; /// UDP UdpScheme @@ -14,6 +14,8 @@ pub struct UdpScheme; impl ResourceScheme for UdpScheme { fn open_resource(&self, url: &[u8], _flags: usize, _uid: u32, _gid: u32) -> Result> { + let ip_addr = Ipv4Addr::from_str(&getcfg("ip").map_err(|err| err.into_sys())?); + let path = try!(str::from_utf8(url).or(Err(Error::new(EINVAL)))); let mut parts = path.split('/'); let remote = parts.next().unwrap_or(""); @@ -36,6 +38,7 @@ impl ResourceScheme for UdpScheme { return Ok(Box::new(UdpResource { ip: ip, data: datagram.data, + host_addr: ip_addr, peer_addr: Ipv4Addr::from_str(peer_addr), peer_port: datagram.header.src.get(), host_port: host_port, @@ -56,6 +59,7 @@ impl ResourceScheme for UdpScheme { return Ok(Box::new(UdpResource { ip: ip, data: Vec::new(), + host_addr: ip_addr, peer_addr: Ipv4Addr::from_str(peer_addr), peer_port: peer_port as u16, host_port: host_port,