Orbital (#16)
* Port previous ethernet scheme
* Add ipd
* Fix initfs rebuilds, use QEMU user networking addresses in ipd
* Add tcp/udp, netutils, dns, and network config
* Add fsync to network driver
* Add dns, router, subnet by default
* Fix e1000 driver. Make ethernet and IP non-blocking to avoid deadlocks
* Add orbital server, WIP
* Add futex
* Add orbutils and orbital
* Update libstd, orbutils, and orbital
Move ANSI key encoding to vesad
* Add orbital assets
* Update orbital
* Update to add login manager
* Add blocking primitives, block for most things except waitpid, update orbital
* Wait in waitpid and IRQ, improvements for other waits
* Fevent in root scheme
* WIP: Switch to using fevent
* Reorganize
* Event based e1000d driver
* Superuser-only access to some network schemes, display, and disk
* Superuser root and irq schemes
* Fix orbital
2016-10-14 01:21:42 +02:00
|
|
|
use std::{str, u16};
|
|
|
|
|
2016-10-21 01:49:54 +02:00
|
|
|
use netutils::{MacAddr, EthernetII};
|
Orbital (#16)
* Port previous ethernet scheme
* Add ipd
* Fix initfs rebuilds, use QEMU user networking addresses in ipd
* Add tcp/udp, netutils, dns, and network config
* Add fsync to network driver
* Add dns, router, subnet by default
* Fix e1000 driver. Make ethernet and IP non-blocking to avoid deadlocks
* Add orbital server, WIP
* Add futex
* Add orbutils and orbital
* Update libstd, orbutils, and orbital
Move ANSI key encoding to vesad
* Add orbital assets
* Update orbital
* Update to add login manager
* Add blocking primitives, block for most things except waitpid, update orbital
* Wait in waitpid and IRQ, improvements for other waits
* Fevent in root scheme
* WIP: Switch to using fevent
* Reorganize
* Event based e1000d driver
* Superuser-only access to some network schemes, display, and disk
* Superuser root and irq schemes
* Fix orbital
2016-10-14 01:21:42 +02:00
|
|
|
use resource_scheme::ResourceScheme;
|
|
|
|
use syscall;
|
|
|
|
use syscall::error::{Error, Result, EACCES, ENOENT, EINVAL};
|
|
|
|
use syscall::flag::O_RDWR;
|
|
|
|
|
|
|
|
use resource::EthernetResource;
|
|
|
|
|
|
|
|
pub struct EthernetScheme;
|
|
|
|
|
|
|
|
impl ResourceScheme<EthernetResource> for EthernetScheme {
|
|
|
|
fn open_resource(&self, url: &[u8], _flags: usize, uid: u32, _gid: u32) -> Result<Box<EthernetResource>> {
|
|
|
|
if uid == 0 {
|
|
|
|
let path = try!(str::from_utf8(url).or(Err(Error::new(EINVAL))));
|
|
|
|
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;
|
|
|
|
|
|
|
|
if !host_string.is_empty() {
|
|
|
|
return Ok(Box::new(EthernetResource {
|
|
|
|
network: network,
|
|
|
|
data: Vec::new(),
|
|
|
|
peer_addr: MacAddr::from_str(host_string),
|
|
|
|
ethertype: ethertype,
|
|
|
|
}));
|
|
|
|
} 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 {
|
|
|
|
return Ok(Box::new(EthernetResource {
|
|
|
|
network: network,
|
|
|
|
data: frame.data,
|
|
|
|
peer_addr: frame.header.src,
|
|
|
|
ethertype: ethertype,
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(_) => break,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
println!("Ethernet: Failed to open network:");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
println!("Ethernet: No ethertype provided");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
println!("Ethernet: No host provided");
|
|
|
|
}
|
|
|
|
|
|
|
|
Err(Error::new(ENOENT))
|
|
|
|
} else {
|
|
|
|
Err(Error::new(EACCES))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|