diff --git a/Cargo.toml b/Cargo.toml
index d42592f7ff4f90a51fd3aed80089fc98e2dd9c2e..da451427fa2299cb249a4025cef64a3225e6af49 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -41,7 +41,7 @@ redox_syscall = "0.1"
 spin = "0.4.10"
 
 [features]
-#default = ["trace"]
+default = []
 trace = []
 
 [profile.dev]
diff --git a/src/header/netdb/mod.rs b/src/header/netdb/mod.rs
index f40d128d16f3df12d955ea210d418737c8f8e84f..8ad831ff4b4e1bb49153a7642f28b9fa8503d752 100644
--- a/src/header/netdb/mod.rs
+++ b/src/header/netdb/mod.rs
@@ -5,6 +5,7 @@ mod dns;
 use core::str::FromStr;
 use core::{mem, ptr, slice, str};
 
+use alloc::borrow::ToOwned;
 use alloc::boxed::Box;
 use alloc::str::SplitWhitespace;
 use alloc::vec::Vec;
@@ -13,11 +14,11 @@ use c_str::{CStr, CString};
 use header::arpa_inet::htons;
 use header::errno::*;
 use header::fcntl::O_RDONLY;
-use header::netinet_in::{in_addr, sockaddr_in};
+use header::netinet_in::{in_addr, sockaddr_in, sockaddr_in6};
 use header::stdlib::atoi;
 use header::strings::strcasecmp;
 use header::sys_socket::constants::{AF_UNSPEC, AF_INET};
-use header::sys_socket::{sockaddr, socklen_t};
+use header::sys_socket::{sa_family_t, sockaddr, socklen_t};
 use header::unistd::SEEK_SET;
 use platform;
 use platform::rlb::{Line, RawLineBuffer};
@@ -670,15 +671,72 @@ pub unsafe extern "C" fn getaddrinfo(
 
     let hints_opt = if hints.is_null() { None } else { Some(&*hints) };
 
-    eprintln!(
+    trace!(
         "getaddrinfo({:?}, {:?}, {:?})",
         node_opt.map(|c| str::from_utf8_unchecked(c.to_bytes())),
         service_opt.map(|c| str::from_utf8_unchecked(c.to_bytes())),
         hints_opt
     );
 
-    platform::errno = ENOSYS;
-    EAI_SYSTEM
+    //TODO: Use hints
+    let mut ai_flags = hints_opt.map_or(0, |hints| hints.ai_flags);
+    let mut ai_family = hints_opt.map_or(AF_UNSPEC, |hints| hints.ai_family);
+    let mut ai_socktype = hints_opt.map_or(0, |hints| hints.ai_socktype);
+    let mut ai_protocol = hints_opt.map_or(0, |hints| hints.ai_protocol);
+
+    *res = ptr::null_mut();
+
+    //TODO: Check hosts file
+    if let Some(node) = node_opt {
+        let lookuphost = match lookup_host(str::from_utf8_unchecked(node.to_bytes())) {
+            Ok(lookuphost) => lookuphost,
+            Err(e) => {
+                platform::errno = e;
+                return EAI_SYSTEM;
+            }
+        };
+
+        for in_addr in lookuphost {
+            ai_family = AF_INET;
+            ai_socktype = AF_UNSPEC;
+            ai_protocol = 0;
+
+            let ai_addr = Box::into_raw(Box::new(sockaddr_in {
+                sin_family: AF_INET as sa_family_t,
+                sin_port: 0,
+                sin_addr: in_addr,
+                sin_zero: [0; 8]
+            })) as *mut sockaddr;
+
+            let ai_addrlen = mem::size_of::<sockaddr_in>();
+
+            let ai_canonname = if ai_flags & AI_CANONNAME > 0 {
+                ai_flags &= !AI_CANONNAME;
+                node.to_owned().into_raw()
+            } else {
+                ptr::null_mut()
+            };
+
+            let addrinfo = Box::new(addrinfo {
+                ai_flags: 0,
+                ai_family,
+                ai_socktype,
+                ai_protocol,
+                ai_addrlen,
+                ai_canonname,
+                ai_addr,
+                ai_next: ptr::null_mut(),
+            });
+
+            let mut indirect = res;
+            while !(*indirect).is_null() {
+                indirect=&mut (**indirect).ai_next;
+            }
+            *indirect = Box::into_raw(addrinfo);
+        }
+    }
+
+    0
 }
 
 #[no_mangle]
@@ -721,8 +779,19 @@ pub unsafe extern "C" fn freeaddrinfo(res: *mut addrinfo) {
     let mut ai = res;
     while !ai.is_null() {
         let bai = Box::from_raw(ai);
-        ai = (*ai).ai_next;
-        drop(bai);
+        if !bai.ai_canonname.is_null() {
+            CString::from_raw(bai.ai_canonname);
+        }
+        if !bai.ai_addr.is_null() {
+            if bai.ai_addrlen == mem::size_of::<sockaddr_in>() {
+                Box::from_raw(bai.ai_addr as *mut sockaddr_in);
+            } else if bai.ai_addrlen == mem::size_of::<sockaddr_in6>() {
+                Box::from_raw(bai.ai_addr as *mut sockaddr_in6);
+            } else {
+                eprintln!("freeaddrinfo: unknown ai_addrlen {}", bai.ai_addrlen);
+            }
+        }
+        ai = bai.ai_next;
     }
 }
 
diff --git a/src/header/sys_socket/mod.rs b/src/header/sys_socket/mod.rs
index 3a6f187325f71afb4b751396cbdf9a1fe4f8c0a4..b6a50b5907e2d2731c3fc4707c5a5617e3fa932a 100644
--- a/src/header/sys_socket/mod.rs
+++ b/src/header/sys_socket/mod.rs
@@ -14,7 +14,7 @@ pub type socklen_t = u32;
 #[derive(Default)]
 pub struct sockaddr {
     pub sa_family: sa_family_t,
-    pub data: [c_char; 14],
+    pub sa_data: [c_char; 14],
 }
 
 #[no_mangle]
diff --git a/tests/Makefile b/tests/Makefile
index 2c4983fa0911e743182ba55860508f4707007333..669b8001288ebe2c02c5ff26668469a0180928b9 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -15,7 +15,8 @@ EXPECT_BINS=\
 	libgen \
 	locale \
 	math \
-	netdb \
+	netdb/netdb \
+	netdb/getaddrinfo \
 	regex \
 	select \
 	setjmp \
@@ -112,7 +113,6 @@ BINS=\
 .PHONY: all $(BINS) clean run expected verify
 
 all: $(BINS)
-expect: $(EXPECT_BINS)
 
 $(BINS): %: bins/%
 
@@ -126,7 +126,7 @@ run: | ../sysroot all
 		"bins/$${bin}" test args || exit $$?; \
 	done
 
-expected: | ../sysroot expect
+expected: | ../sysroot $(EXPECT_BINS)
 	rm -rf expected
 	mkdir -p expected
 	for bin in $(EXPECT_BINS); \
@@ -136,7 +136,7 @@ expected: | ../sysroot expect
 		"bins/$${bin}" test args > "expected/$${bin}.stdout" 2> "expected/$${bin}.stderr" || exit $$?; \
 	done
 
-verify: | ../sysroot expect
+verify: | ../sysroot $(EXPECT_BINS)
 	rm -rf gen
 	mkdir -p gen
 	for bin in $(EXPECT_BINS); \
@@ -151,6 +151,7 @@ verify: | ../sysroot expect
 CFLAGS=\
 	-fno-builtin \
 	-fno-stack-protector \
+	-static \
 	-Wall \
 	-g \
 	-nostdinc \
diff --git a/tests/expected/netdb.stderr b/tests/expected/netdb/getaddrinfo.stderr
similarity index 100%
rename from tests/expected/netdb.stderr
rename to tests/expected/netdb/getaddrinfo.stderr
diff --git a/tests/expected/netdb/getaddrinfo.stdout b/tests/expected/netdb/getaddrinfo.stdout
new file mode 100644
index 0000000000000000000000000000000000000000..6bc12bb59ba8f7f23d53ec13bf10a6a31a0df2e6
--- /dev/null
+++ b/tests/expected/netdb/getaddrinfo.stdout
@@ -0,0 +1 @@
+IPv4 address: 23.21.162.66 (www.redox-os.org)
diff --git a/tests/expected/netdb/netdb.stderr b/tests/expected/netdb/netdb.stderr
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/tests/expected/netdb.stdout b/tests/expected/netdb/netdb.stdout
similarity index 100%
rename from tests/expected/netdb.stdout
rename to tests/expected/netdb/netdb.stdout
diff --git a/tests/netdb/getaddrinfo.c b/tests/netdb/getaddrinfo.c
new file mode 100644
index 0000000000000000000000000000000000000000..3864d0d9903b788b4c3c49a6d5c440187b2d4b94
--- /dev/null
+++ b/tests/netdb/getaddrinfo.c
@@ -0,0 +1,50 @@
+// Adapted from https://gist.github.com/jirihnidek/bf7a2363e480491da72301b228b35d5d
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+
+int main(void) {
+    struct addrinfo hints, *res;
+    int errcode;
+    char addrstr[INET6_ADDRSTRLEN];
+    void *ptr;
+
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = PF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_flags |= AI_CANONNAME;
+
+    errcode = getaddrinfo("www.redox-os.org", NULL, &hints, &res);
+    if (errcode != 0) {
+        perror("getaddrinfo");
+        return -1;
+    }
+
+    while (res) {
+        switch (res->ai_family) {
+        case AF_INET:
+            ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr;
+            break;
+        case AF_INET6:
+            ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
+            break;
+        }
+        inet_ntop(res->ai_family, ptr, addrstr, INET6_ADDRSTRLEN);
+
+        printf(
+            "IPv%d address: %s (%s)\n",
+            res->ai_family == PF_INET6 ? 6 : 4,
+            addrstr,
+            res->ai_canonname
+        );
+
+        res = res->ai_next;
+    }
+
+    return 0;
+}
diff --git a/tests/netdb.c b/tests/netdb/netdb.c
similarity index 100%
rename from tests/netdb.c
rename to tests/netdb/netdb.c