From 66bcd0d1ba7a61421f79d80e20140bc784d6754c Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sun, 23 Oct 2016 15:57:04 -0600 Subject: [PATCH] Enable arpd, update netutils, remove loop in ethernetd --- Makefile | 2 +- filesystem/etc/init.rc | 2 +- programs/netutils | 2 +- schemes/arpd/Cargo.toml | 1 + schemes/arpd/src/main.rs | 16 ++++---- schemes/ethernetd/src/scheme.rs | 73 +++++++++++---------------------- 6 files changed, 36 insertions(+), 60 deletions(-) diff --git a/Makefile b/Makefile index 474eece..8317d11 100644 --- a/Makefile +++ b/Makefile @@ -371,7 +371,7 @@ extrautils: \ netutils: \ filesystem/bin/dhcpd \ - filesystem/bin/dnsd \ + filesystem/bin/dns \ filesystem/bin/irc \ filesystem/bin/nc \ filesystem/bin/wget diff --git a/filesystem/etc/init.rc b/filesystem/etc/init.rc index ed78e17..20e88d3 100644 --- a/filesystem/etc/init.rc +++ b/filesystem/etc/init.rc @@ -1,6 +1,6 @@ initfs:bin/pcid /etc/pcid.toml ethernetd -#arpd +arpd ipd tcpd udpd diff --git a/programs/netutils b/programs/netutils index 3eb504d..44436af 160000 --- a/programs/netutils +++ b/programs/netutils @@ -1 +1 @@ -Subproject commit 3eb504dfe131c9fcba3e8ee824f382af9c6032cd +Subproject commit 44436af31b2b113c2893f9b909950cb382230bc0 diff --git a/schemes/arpd/Cargo.toml b/schemes/arpd/Cargo.toml index d49d243..dfeff5f 100644 --- a/schemes/arpd/Cargo.toml +++ b/schemes/arpd/Cargo.toml @@ -3,4 +3,5 @@ name = "arpd" version = "0.1.0" [dependencies] +netutils = { path = "../../programs/netutils/" } syscall = { path = "../../syscall/" } diff --git a/schemes/arpd/src/main.rs b/schemes/arpd/src/main.rs index 634a31d..ab2f6f1 100644 --- a/schemes/arpd/src/main.rs +++ b/schemes/arpd/src/main.rs @@ -1,11 +1,10 @@ +extern crate netutils; extern crate syscall; +use netutils::{getcfg, Ipv4Addr, MacAddr, Arp}; + use std::thread; -use common::{MAC_ADDR, IP_ADDR, Arp}; - -pub mod common; - fn main() { thread::spawn(move || { while let Ok(link) = syscall::open("ethernet:/806", syscall::O_RDWR) { @@ -13,7 +12,10 @@ fn main() { let mut bytes = [0; 65536]; if let Ok(count) = syscall::read(link, &mut bytes) { if let Some(packet) = Arp::from_bytes(&bytes[..count]) { - if packet.header.oper.get() == 1 && packet.header.dst_ip.equals(unsafe { IP_ADDR }) { + let mac_addr = MacAddr::from_str(&getcfg("mac").expect("arpd: failed to get mac address")); + let ip_addr = Ipv4Addr::from_str(&getcfg("ip").expect("arpd: failed to get ip address")); + + if packet.header.oper.get() == 1 && packet.header.dst_ip.equals(ip_addr) { let mut response = Arp { header: packet.header, data: packet.data.clone(), @@ -21,8 +23,8 @@ fn main() { response.header.oper.set(2); response.header.dst_mac = packet.header.src_mac; response.header.dst_ip = packet.header.src_ip; - response.header.src_mac = unsafe { MAC_ADDR }; - response.header.src_ip = unsafe { IP_ADDR }; + response.header.src_mac = mac_addr; + response.header.src_ip = ip_addr; let _ = syscall::write(link, &response.to_bytes()); } diff --git a/schemes/ethernetd/src/scheme.rs b/schemes/ethernetd/src/scheme.rs index 4eef6f4..88b3f66 100644 --- a/schemes/ethernetd/src/scheme.rs +++ b/schemes/ethernetd/src/scheme.rs @@ -7,7 +7,6 @@ use std::{cmp, str, u16}; use netutils::{getcfg, n16, MacAddr, EthernetII, EthernetIIHeader}; use syscall; use syscall::error::{Error, Result, EACCES, EBADF, ENOENT, EINVAL, EWOULDBLOCK}; -use syscall::flag::O_RDWR; use syscall::scheme::SchemeMut; #[derive(Clone)] @@ -15,7 +14,7 @@ pub struct Handle { /// The Host's MAC address pub host_addr: MacAddr, /// The Peer's MAC address - pub peer_addr: MacAddr, + pub peer_addr: Option, /// The ethernet type pub ethertype: u16, /// The data @@ -45,6 +44,9 @@ impl EthernetScheme { if let Some(frame) = EthernetII::from_bytes(&bytes[.. count]) { for (_id, handle) in self.handles.iter_mut() { if frame.header.ethertype.get() == handle.ethertype { + if handle.peer_addr.is_none() { + handle.peer_addr = Some(frame.header.src); + } handle.frames.push_back(frame.clone()); } } @@ -63,54 +65,25 @@ impl SchemeMut for EthernetScheme { let mut parts = path.split("/"); if let Some(host_string) = parts.next() { if let Some(ethertype_string) = parts.next() { - if let Ok(network) = syscall::open("network:", O_RDWR) { - let ethertype = u16::from_str_radix(ethertype_string, 16).unwrap_or(0) as u16; + let ethertype = u16::from_str_radix(ethertype_string, 16).unwrap_or(0); - if ! host_string.is_empty() { - let next_id = self.next_id; - self.next_id += 1; - - self.handles.insert(next_id, Handle { - host_addr: mac_addr, - peer_addr: MacAddr::from_str(host_string), - ethertype: ethertype, - frames: VecDeque::new() - }); - - return Ok(next_id); - } else { - loop { - let mut bytes = [0; 65536]; - match syscall::read(network, &mut bytes) { - Ok(count) => { - if let Some(frame) = EthernetII::from_bytes(&bytes[..count]) { - if frame.header.ethertype.get() == ethertype { - let next_id = self.next_id; - self.next_id += 1; - - let peer_addr = frame.header.src; - - let mut frames = VecDeque::new(); - frames.push_back(frame); - - self.handles.insert(next_id, Handle { - host_addr: mac_addr, - peer_addr: peer_addr, - ethertype: ethertype, - frames: frames - }); - - return Ok(next_id); - } - } - } - Err(_) => break, - } - } - } + let peer_addr = if ! host_string.is_empty() { + Some(MacAddr::from_str(host_string)) } else { - println!("Ethernet: Failed to open network:"); - } + None + }; + + let next_id = self.next_id; + self.next_id += 1; + + self.handles.insert(next_id, Handle { + host_addr: mac_addr, + peer_addr: peer_addr, + ethertype: ethertype, + frames: VecDeque::new() + }); + + return Ok(next_id); } else { println!("Ethernet: No ethertype provided"); } @@ -158,7 +131,7 @@ impl SchemeMut for EthernetScheme { match syscall::write(self.network.as_raw_fd(), &EthernetII { header: EthernetIIHeader { src: handle.host_addr, - dst: handle.peer_addr, + dst: handle.peer_addr.unwrap_or(MacAddr::BROADCAST), ethertype: n16::new(handle.ethertype), }, data: Vec::from(buf), @@ -178,7 +151,7 @@ impl SchemeMut for EthernetScheme { fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result { let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?; - let path_string = format!("ethernet:{}/{:X}", handle.peer_addr.to_string(), handle.ethertype); + let path_string = format!("ethernet:{}/{:X}", handle.peer_addr.map_or(String::new(), |mac| mac.to_string()), handle.ethertype); let path = path_string.as_bytes(); for (b, p) in buf.iter_mut().zip(path.iter()) {