diff --git a/libc-test/Cargo.toml b/libc-test/Cargo.toml
index 8d2d9033308b7fb0ff42b0fec5b81e92877f0791..0b6866d49c0bba21acb3c97a097612e77574a51f 100644
--- a/libc-test/Cargo.toml
+++ b/libc-test/Cargo.toml
@@ -52,3 +52,8 @@ harness = false
 name = "cmsg"
 path = "test/cmsg.rs"
 harness = true
+
+[[test]]
+name = "errqueue"
+path = "test/errqueue.rs"
+harness = true
diff --git a/libc-test/build.rs b/libc-test/build.rs
index 9001000b26389cf065ae328e9fc59af7684c48a0..8ab5d89592d56835c43a00704631f9307e41fd5e 100644
--- a/libc-test/build.rs
+++ b/libc-test/build.rs
@@ -10,6 +10,9 @@ fn do_cc() {
     if cfg!(unix) && !target.contains("wasi") {
         cc::Build::new().file("src/cmsg.c").compile("cmsg");
     }
+    if target.contains("android") || target.contains("linux") {
+        cc::Build::new().file("src/errqueue.c").compile("errqueue");
+    }
 }
 
 fn do_ctest() {
@@ -1239,7 +1242,6 @@ fn test_android(target: &str) {
 
     headers! { cfg:
                "arpa/inet.h",
-               "asm/mman.h",
                "ctype.h",
                "dirent.h",
                "dlfcn.h",
@@ -1248,27 +1250,6 @@ fn test_android(target: &str) {
                "grp.h",
                "ifaddrs.h",
                "limits.h",
-               "linux/dccp.h",
-               "linux/futex.h",
-               "linux/fs.h",
-               "linux/genetlink.h",
-               "linux/if_alg.h",
-               "linux/if_ether.h",
-               "linux/if_tun.h",
-               "linux/magic.h",
-               "linux/memfd.h",
-               "linux/module.h",
-               "linux/net_tstamp.h",
-               "linux/netfilter/nfnetlink.h",
-               "linux/netfilter/nfnetlink_log.h",
-               "linux/netfilter/nf_tables.h",
-               "linux/netfilter_ipv4.h",
-               "linux/netfilter_ipv6.h",
-               "linux/netlink.h",
-               "linux/quota.h",
-               "linux/reboot.h",
-               "linux/seccomp.h",
-               "linux/sockios.h",
                "locale.h",
                "malloc.h",
                "net/ethernet.h",
@@ -1339,6 +1320,34 @@ fn test_android(target: &str) {
                [x86]: "sys/reg.h",
     }
 
+    // Include linux headers at the end:
+    headers! { cfg:
+                "asm/mman.h",
+                "linux/dccp.h",
+                "linux/errqueue.h",
+                "linux/futex.h",
+                "linux/fs.h",
+                "linux/genetlink.h",
+                "linux/if_alg.h",
+                "linux/if_ether.h",
+                "linux/if_tun.h",
+                "linux/magic.h",
+                "linux/memfd.h",
+                "linux/module.h",
+                "linux/net_tstamp.h",
+                "linux/netfilter/nfnetlink.h",
+                "linux/netfilter/nfnetlink_log.h",
+                "linux/netfilter/nf_tables.h",
+                "linux/netfilter_ipv4.h",
+                "linux/netfilter_ipv6.h",
+                "linux/netlink.h",
+                "linux/quota.h",
+                "linux/reboot.h",
+                "linux/seccomp.h",
+                "linux/sockios.h",
+
+    }
+
     cfg.type_name(move |ty, is_struct, is_union| {
         match ty {
             // Just pass all these through, no need for a "struct" prefix
@@ -2188,6 +2197,7 @@ fn test_linux(target: &str) {
         cfg:
         "asm/mman.h",
         "linux/dccp.h",
+        "linux/errqueue.h",
         "linux/falloc.h",
         "linux/fs.h",
         "linux/futex.h",
diff --git a/libc-test/src/errqueue.c b/libc-test/src/errqueue.c
new file mode 100644
index 0000000000000000000000000000000000000000..931ca91bbf8c834e666ca482d609ee59c4064d1f
--- /dev/null
+++ b/libc-test/src/errqueue.c
@@ -0,0 +1,10 @@
+#include <time.h>
+#include <linux/errqueue.h>
+
+// SO_EE_OFFENDER is defined as a macro in linux/errqueue.h.  This file wraps
+// that macro in a function so we can test the reimplementation in this package
+// is equivalent.
+
+struct sockaddr *so_ee_offender(struct sock_extended_err *ee) {
+  return SO_EE_OFFENDER(ee);
+}
diff --git a/libc-test/test/errqueue.rs b/libc-test/test/errqueue.rs
new file mode 100644
index 0000000000000000000000000000000000000000..8d0c7bb7416761604f8abe30fb087b62c6d5b5fb
--- /dev/null
+++ b/libc-test/test/errqueue.rs
@@ -0,0 +1,22 @@
+//! Compare libc's SO_EE_OFFENDER function against the actual C macro
+
+extern crate libc;
+
+#[cfg(any(target_os = "linux", target_os = "android"))]
+mod t {
+    use libc::{self, sock_extended_err, sockaddr};
+
+    extern "C" {
+        pub fn so_ee_offender(ee: *const sock_extended_err) -> *mut sockaddr;
+    }
+
+    #[test]
+    fn test_cmsg_data() {
+        for l in 0..128 {
+            let ee = l as *const sock_extended_err;
+            unsafe {
+                assert_eq!(libc::SO_EE_OFFENDER(ee), so_ee_offender(ee));
+            }
+        }
+    }
+}
diff --git a/src/unix/linux_like/mod.rs b/src/unix/linux_like/mod.rs
index 792548f981b69073fde5832e05705b96d08297bd..5b2fb11c33258538323bc0e6f0fedb87e1af4236 100644
--- a/src/unix/linux_like/mod.rs
+++ b/src/unix/linux_like/mod.rs
@@ -199,6 +199,16 @@ s! {
         pub msg_hdr: ::msghdr,
         pub msg_len: ::c_uint,
     }
+
+    pub struct sock_extended_err {
+        pub ee_errno: u32,
+        pub ee_origin: u8,
+        pub ee_type: u8,
+        pub ee_code: u8,
+        pub ee_pad: u8,
+        pub ee_info: u32,
+        pub ee_data: u32
+    }
 }
 
 s_no_extra_traits! {
@@ -1189,6 +1199,13 @@ pub const ARPHRD_IEEE802154: u16 = 804;
 pub const ARPHRD_VOID: u16 = 0xFFFF;
 pub const ARPHRD_NONE: u16 = 0xFFFE;
 
+pub const SO_EE_ORIGIN_NONE: u8 = 0;
+pub const SO_EE_ORIGIN_LOCAL: u8 = 1;
+pub const SO_EE_ORIGIN_ICMP: u8 = 2;
+pub const SO_EE_ORIGIN_ICMP6: u8 = 3;
+pub const SO_EE_ORIGIN_TXSTATUS: u8 = 4;
+pub const SO_EE_ORIGIN_TIMESTAMPING: u8 = SO_EE_ORIGIN_TXSTATUS;
+
 const_fn! {
     {const} fn CMSG_ALIGN(len: usize) -> usize {
         len + ::mem::size_of::<usize>() - 1 & !(::mem::size_of::<usize>() - 1)
@@ -1294,6 +1311,10 @@ f! {
     pub fn IPTOS_ECN(x: u8) -> u8 {
         x & ::IPTOS_ECN_MASK
     }
+
+    pub fn SO_EE_OFFENDER(ee: *const ::sock_extended_err) -> *mut ::sockaddr {
+        ee.offset(1) as *mut ::sockaddr
+    }
 }
 
 extern "C" {