diff --git a/src/header/mod.rs b/src/header/mod.rs
index 42b8d270f4fcfbae25c94d9753a4d6c95f4a76a1..12d20f96c4779ba35e72343ab432f8dc125ec910 100644
--- a/src/header/mod.rs
+++ b/src/header/mod.rs
@@ -22,6 +22,7 @@ pub mod inttypes;
 pub mod libgen;
 pub mod limits;
 pub mod locale;
+pub mod net_if;
 pub mod netdb;
 pub mod netinet_in;
 pub mod netinet_ip;
diff --git a/src/header/net_if/cbindgen.toml b/src/header/net_if/cbindgen.toml
new file mode 100644
index 0000000000000000000000000000000000000000..af56fa8a4edcdbdb6467fa8a6dd2c2fffc479783
--- /dev/null
+++ b/src/header/net_if/cbindgen.toml
@@ -0,0 +1,9 @@
+sys_includes = []
+include_guard = "_NET_IF_H"
+language = "C"
+style = "Tag"
+no_includes = true
+cpp_compat = true
+
+[enum]
+prefix_with_name = true
diff --git a/src/header/net_if/mod.rs b/src/header/net_if/mod.rs
new file mode 100644
index 0000000000000000000000000000000000000000..2b4daf8c0c56434453d0914827e648557a9bd206
--- /dev/null
+++ b/src/header/net_if/mod.rs
@@ -0,0 +1,72 @@
+use core::ptr::null;
+
+use alloc::ffi::CString;
+
+use crate::{
+    c_str::CStr,
+    platform::{types::*, ERRNO},
+};
+
+use super::errno::ENXIO;
+
+#[repr(C)]
+pub struct if_nameindex {
+    if_index: c_uint,
+    if_name: *const c_char,
+}
+
+pub const IF_NAMESIZE: usize = 16;
+
+const IF_STUB_INTERFACE: *const c_char = (c"stub").as_ptr();
+
+const INTERFACES: &[if_nameindex] = &[
+    if_nameindex {
+        if_index: 1,
+        if_name: IF_STUB_INTERFACE,
+    },
+    if_nameindex {
+        if_index: 0,
+        if_name: null::<c_char>(),
+    },
+];
+
+/// # Safety
+/// Returns a constant pointer to a pre defined const stub list
+/// The end of the list is determined by an if_nameindex struct having if_index 0 and if_name NULL
+#[no_mangle]
+pub unsafe extern "C" fn if_nameindex() -> *const if_nameindex {
+    &INTERFACES[0] as *const if_nameindex
+}
+
+/// # Safety
+/// this is a no-op: the list returned by if_nameindex() is a ref to a constant
+#[no_mangle]
+pub unsafe extern "C" fn if_freenameindex(s: *mut if_nameindex) {}
+
+/// # Safety
+/// Compares the name to a constant string and only returns an int as a result.
+/// An invalid name string will return an index of 0
+#[no_mangle]
+pub unsafe extern "C" fn if_nametoindex(name: *const c_char) -> c_uint {
+    if name == null::<c_char>() {
+        return 0;
+    }
+    let name = CStr::from_ptr(name).to_str().unwrap_or("");
+    if name.eq("stub") {
+        return 1;
+    }
+    0
+}
+
+/// # Safety
+/// Returns only static lifetime references to const names, does not reuse the buf pointer.
+/// Returns NULL in case of not found + ERRNO being set to ENXIO.
+/// Currently only checks against inteface index 1.
+#[no_mangle]
+pub unsafe extern "C" fn if_indextoname(idx: c_uint, buf: *mut c_char) -> *const c_char {
+    if idx == 1 {
+        return IF_STUB_INTERFACE;
+    }
+    ERRNO.set(ENXIO);
+    null::<c_char>()
+}
diff --git a/tests/Makefile b/tests/Makefile
index 73bb54dc20cd46b48e48957e34f274b166875a8a..91d251ac71ff504e6cab9a6c9d450b72b7d0f43e 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -158,6 +158,7 @@ DYNAMIC_ONLY_NAMES=\
 NAMES=\
 	$(EXPECT_NAMES) \
 	dirent/main \
+	net/if \
 	pty/forkpty \
 	psignal \
 	pwd \
diff --git a/tests/net/if.c b/tests/net/if.c
new file mode 100644
index 0000000000000000000000000000000000000000..5cce1465f4f9d8ec830219be855139d9ec0bbf68
--- /dev/null
+++ b/tests/net/if.c
@@ -0,0 +1,43 @@
+#include <net/if.h>
+#include <string.h>
+
+#include "../test_helpers.h"
+
+#define assert_eq(value, expected)                                             \
+  {                                                                            \
+    if (value != expected) {                                                   \
+      fprintf(stderr, "%s:%d: failed\n", __FILE__, __LINE__);                  \
+      exit(EXIT_FAILURE);                                                      \
+    }                                                                          \
+  }
+
+int main(void) {
+  const struct if_nameindex *list = if_nameindex();
+
+  // Currently always returning a stub
+  const struct if_nameindex *first = &(list[0]);
+  assert_eq(first->if_index, 1);
+  assert_eq(strcmp(first->if_name, "stub"), 0);
+
+  // Last item with 0 values determines the end of the list
+  const struct if_nameindex *second = &(list[1]);
+  assert_eq(second->if_index, 0);
+  assert_eq(second->if_name, 0);
+
+  unsigned idx;
+  idx = if_nametoindex(0);
+  assert_eq(idx, 0);
+  idx = if_nametoindex("any");
+  assert_eq(idx, 0);
+  idx = if_nametoindex("stub");
+  assert_eq(idx, 1);
+
+  const char *name;
+  name = if_indextoname(0, 0);
+  assert_eq(name, 0);
+
+  name = if_indextoname(1, 0);
+  assert_eq(strcmp(name, "stub"), 0);
+
+  printf("OK\n");
+}