Enable arpd, update netutils, remove loop in ethernetd

This commit is contained in:
Jeremy Soller 2016-10-23 15:57:04 -06:00
parent 7f7f5a0078
commit 66bcd0d1ba
6 changed files with 36 additions and 60 deletions

View file

@ -371,7 +371,7 @@ extrautils: \
netutils: \
filesystem/bin/dhcpd \
filesystem/bin/dnsd \
filesystem/bin/dns \
filesystem/bin/irc \
filesystem/bin/nc \
filesystem/bin/wget

View file

@ -1,6 +1,6 @@
initfs:bin/pcid /etc/pcid.toml
ethernetd
#arpd
arpd
ipd
tcpd
udpd

@ -1 +1 @@
Subproject commit 3eb504dfe131c9fcba3e8ee824f382af9c6032cd
Subproject commit 44436af31b2b113c2893f9b909950cb382230bc0

View file

@ -3,4 +3,5 @@ name = "arpd"
version = "0.1.0"
[dependencies]
netutils = { path = "../../programs/netutils/" }
syscall = { path = "../../syscall/" }

View file

@ -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());
}

View file

@ -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<MacAddr>,
/// 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<usize> {
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()) {