diff --git a/Cargo.lock b/Cargo.lock index d1ff18f5a67167980cd2d2144392280f0c41e7d0..4951949c666d511ee11e78c546609c28bc8c25f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,6 +6,17 @@ dependencies = [ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "arpainet" +version = "0.1.0" +dependencies = [ + "cbindgen 0.5.2", + "errno 0.1.0", + "netinet 0.1.0", + "platform 0.1.0", + "sys_socket 0.1.0", +] + [[package]] name = "atty" version = "0.2.10" @@ -29,7 +40,7 @@ dependencies = [ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "standalone-syn 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -62,7 +73,7 @@ dependencies = [ [[package]] name = "compiler_builtins" version = "0.1.0" -source = "git+https://github.com/rust-lang-nursery/compiler-builtins.git#8142298fe6827fe957e67de8d272a4ceb2317f45" +source = "git+https://github.com/rust-lang-nursery/compiler-builtins.git#5d370bb352c915225981d89b80227afa4836cb93" [[package]] name = "crt0" @@ -166,7 +177,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lazy_static" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "spin 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -286,6 +297,7 @@ dependencies = [ name = "relibc" version = "0.1.0" dependencies = [ + "arpainet 0.1.0", "cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "compiler_builtins 0.1.0 (git+https://github.com/rust-lang-nursery/compiler-builtins.git)", "ctype 0.1.0", @@ -368,7 +380,7 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.22" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -418,7 +430,7 @@ dependencies = [ "cbindgen 0.5.2", "errno 0.1.0", "fcntl 0.1.0", - "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "platform 0.1.0", "string 0.1.0", "va_list 0.1.0", @@ -683,7 +695,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5adb58558dcd1d786b5f0bd15f3226ee23486e24b7b58304b60f64dc68e62606" -"checksum lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e6412c5e2ad9584b0b8e979393122026cdd6d2a80b933f890dcd694ddbe73739" +"checksum lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fb497c35d362b6a331cfd94956a07fc2c78a4604cdbee844a81170386b996dd3" "checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "61bd98ae7f7b754bc53dca7d44b604f733c6bba044ea6f41bc8d89272d8161d2" @@ -699,7 +711,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)" = "0c3adf19c07af6d186d91dae8927b83b0553d07ca56cbf7f2f32560455c91920" "checksum serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "652bc323d694dc925829725ec6c890156d8e70ae5202919869cb00fe2eff3788" "checksum serde_derive_internals 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "32f1926285523b2db55df263d2aa4eb69ddcfa7a7eade6430323637866b513ab" -"checksum serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)" = "84b8035cabe9b35878adec8ac5fe03d5f6bc97ff6edd7ccb96b44c1276ba390e" +"checksum serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c6908c7b925cd6c590358a4034de93dbddb20c45e1d021931459fd419bf0e2" "checksum spin 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14db77c5b914df6d6173dda9a3b3f5937bd802934fa5edaf934df06a3491e56f" "checksum standalone-quote 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dcedac1d6d98e7e9d1d6e628f5635af9566688ae5f6cea70a3976f495ae8d839" "checksum standalone-syn 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "115808f5187c07c23cb93eee49d542fae54c6e8285d3a24c6ff683fcde9243db" diff --git a/Cargo.toml b/Cargo.toml index db0493f13ff50273f8cfd7871c7671476fd0d8d0..ae570caa2d4dd5ece78be74a8640e371af1092af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ members = ["src/crt0"] cc = "1.0.17" [dependencies] +arpainet = { path = "src/arpainet" } ctype = { path = "src/ctype" } errno = { path = "src/errno" } fcntl = { path = "src/fcntl" } diff --git a/src/arpainet/Cargo.toml b/src/arpainet/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..5a015567516ce115e84e172e2c033b9855dac5d7 --- /dev/null +++ b/src/arpainet/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "arpainet" +version = "0.1.0" +authors = ["Jeremy Soller <jackpot51@gmail.com>"] +build = "build.rs" + +[build-dependencies] +cbindgen = { path = "../../cbindgen" } + +[dependencies] +platform = { path = "../platform" } +errno = { path = "../errno" } +sys_socket = { path = "../sys_socket" } +netinet = { path = "../netinet" } diff --git a/src/arpainet/build.rs b/src/arpainet/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..ad73b43495a11529f63c5466a2c230ca29df8349 --- /dev/null +++ b/src/arpainet/build.rs @@ -0,0 +1,11 @@ +extern crate cbindgen; + +use std::{env, fs}; + +fn main() { + let crate_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set"); + fs::create_dir_all("../../target/include").expect("failed to create include directory"); + cbindgen::generate(crate_dir) + .expect("failed to generate bindings") + .write_to_file("../../target/include/arpa/inet.h"); +} diff --git a/src/arpainet/cbindgen.toml b/src/arpainet/cbindgen.toml new file mode 100644 index 0000000000000000000000000000000000000000..661140fa0bae879d4ab88b71858b9754351b512a --- /dev/null +++ b/src/arpainet/cbindgen.toml @@ -0,0 +1,7 @@ +sys_includes = ["stddef.h", "sys/socket.h", "netinet/in.h"] +include_guard = "_ARPAINET_H" +language = "C" +style = "Tag" + +[enum] +prefix_with_name = true diff --git a/src/arpainet/src/lib.rs b/src/arpainet/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..c18452fd5a4e8a28d7cadbd1d648e00e95a0be87 --- /dev/null +++ b/src/arpainet/src/lib.rs @@ -0,0 +1,132 @@ +//! arpainet implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/arpainet.h.html + +#![no_std] +#![feature(alloc)] + +#[macro_use] +extern crate alloc; + +extern crate errno; +extern crate netinet; +extern crate platform; +extern crate sys_socket; + +use core::str::FromStr; +use core::{mem, ptr, slice, str}; +use errno::*; +pub use netinet::in_h::*; +use platform::types::*; +use platform::{c_str, socklen_t, AF_INET}; + +#[no_mangle] +pub extern "C" fn htonl(hostlong: u32) -> u32 { + hostlong.to_be() +} + +#[no_mangle] +pub extern "C" fn htons(hostshort: u16) -> u16 { + hostshort.to_be() +} + +#[no_mangle] +pub extern "C" fn ntohl(netlong: u32) -> u32 { + u32::from_be(netlong) +} + +#[no_mangle] +pub extern "C" fn ntohs(netshort: u16) -> u16 { + u16::from_be(netshort) +} + +static mut NTOA_ADDR: [c_char; 16] = [0; 16]; + +#[no_mangle] +pub unsafe extern "C" fn inet_aton(cp: *const c_char, inp: *mut in_addr) -> c_int { + // TODO: octal/hex + inet_pton(AF_INET, cp, inp as *mut c_void) +} + +#[no_mangle] +pub unsafe extern "C" fn inet_ntoa(addr: in_addr) -> *const c_char { + inet_ntop( + AF_INET, + &addr as *const in_addr as *const c_void, + NTOA_ADDR.as_mut_ptr(), + 16, + ) +} + +#[no_mangle] +pub unsafe extern "C" fn inet_pton(domain: c_int, src: *const c_char, dest: *mut c_void) -> c_int { + if domain != AF_INET { + platform::errno = EAFNOSUPPORT; + -1 + } else { + let mut s_addr = slice::from_raw_parts_mut( + &mut (*(dest as *mut in_addr)).s_addr as *mut _ as *mut u8, + 4, + ); + let mut octets = str::from_utf8_unchecked(c_str(src)).split('.'); + for i in 0..4 { + if let Some(n) = octets.next().and_then(|x| u8::from_str(x).ok()) { + s_addr[i] = n; + } else { + return 0; + } + } + if octets.next() == None { + 1 // Success + } else { + 0 + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn inet_ntop( + domain: c_int, + src: *const c_void, + dest: *mut c_char, + size: socklen_t, +) -> *const c_char { + if domain != AF_INET { + platform::errno = EAFNOSUPPORT; + ptr::null() + } else if size < 16 { + platform::errno = ENOSPC; + ptr::null() + } else { + let s_addr = slice::from_raw_parts( + &(*(src as *const in_addr)).s_addr as *const _ as *const u8, + 4, + ); + let addr = format!("{}.{}.{}.{}\0", s_addr[0], s_addr[1], s_addr[2], s_addr[3]); + ptr::copy(addr.as_ptr() as *const c_char, dest, addr.len()); + dest + } +} + +#[no_mangle] +pub extern "C" fn inet_addr(cp: *const c_char) -> in_addr_t { + unimplemented!(); +} + +#[no_mangle] +pub extern "C" fn inet_lnaof(_in: in_addr) -> in_addr_t { + unimplemented!(); +} + +#[no_mangle] +pub extern "C" fn inet_makeaddr(net: in_addr_t, lna: in_addr_t) -> in_addr { + unimplemented!(); +} + +#[no_mangle] +pub extern "C" fn inet_netof(_in: in_addr) -> in_addr_t { + unimplemented!(); +} + +#[no_mangle] +pub extern "C" fn inet_network(cp: *const c_char) -> in_addr_t { + unimplemented!(); +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index e1da46a8d62f6094b612ebf32bfb384cab2ad100..050e466eead98dc1f726bbc6aa334d3a4ae2e32d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,7 @@ //extern crate compiler_builtins; extern crate platform; +pub extern crate arpainet; pub extern crate ctype; pub extern crate errno; pub extern crate fcntl; diff --git a/src/netinet/in/cbindgen.toml b/src/netinet/in/cbindgen.toml index 0067295d34e11baab150431dfa4dc8246bb5a541..e6241ead1994f9060d43bede113ec49d9c717ac9 100644 --- a/src/netinet/in/cbindgen.toml +++ b/src/netinet/in/cbindgen.toml @@ -1,6 +1,6 @@ sys_includes = ["sys/types.h", "sys/socket.h"] include_guard = "_NETINET_IN_H" -style = "Tag" +style = "Both" language = "C" [export] diff --git a/src/netinet/src/lib.rs b/src/netinet/src/lib.rs index 40de25ffa28c14860ecd6c0810bc3bdefef45359..86a0d5a0811b8c2c4f90d1a356f1306ef6a7d502 100644 --- a/src/netinet/src/lib.rs +++ b/src/netinet/src/lib.rs @@ -1,3 +1,3 @@ #![no_std] -extern crate in_h; +pub extern crate in_h; diff --git a/tests/.gitignore b/tests/.gitignore index 264c70ee1cc3e9a531958568906de60e32458e74..993638dc67a91577269417e70976eae4b607708b 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -3,6 +3,7 @@ /gen/ alloc args +arpainet asctime assert atof diff --git a/tests/Makefile b/tests/Makefile index de3feb5766a228d98d08cb1c6bbf49b8f78bb973..d47f2c4a624e95b1b757dc2b7899eb64ac513aeb 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,5 +1,6 @@ # Binaries that should generate the same output every time EXPECT_BINS=\ + arpainet \ assert \ atof \ atoi \ diff --git a/tests/arpainet.c b/tests/arpainet.c new file mode 100644 index 0000000000000000000000000000000000000000..c93f3933c223d21fed89e58858e2bf1a1efbc7b2 --- /dev/null +++ b/tests/arpainet.c @@ -0,0 +1,24 @@ +#include <arpa/inet.h> +#include <assert.h> +#include <string.h> +#include <stdlib.h> + +int main(int argc, char** argv) { + uint32_t hl = 0xBADFACED; + uint32_t nl = htonl(hl); + assert(nl == 0xEDACDFBA); + hl = ntohl(nl); + assert(hl == 0xBADFACED); + + uint16_t hs = 0xDEAD; + uint16_t ns = htons(hs); + assert(ns == 0xADDE); + hs = ntohs(ns); + assert(hs == 0xDEAD); + + const char* addr_str = "8.8.4.4"; + struct in_addr* addr = malloc(sizeof addr); + inet_aton(addr_str, addr); + assert(strcmp(inet_ntoa(*addr), addr_str) == 0); + +} diff --git a/tests/expected/arpainet.stderr b/tests/expected/arpainet.stderr new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/expected/arpainet.stdout b/tests/expected/arpainet.stdout new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391