diff --git a/src/unix/bsd/apple/mod.rs b/src/unix/bsd/apple/mod.rs
index 13da82c38323dd92266dffa7443e379191e59565..837efff53d5ce4f32a796d96a1b1accd7c9cd7d4 100644
--- a/src/unix/bsd/apple/mod.rs
+++ b/src/unix/bsd/apple/mod.rs
@@ -1,6 +1,7 @@
 //! Apple (ios/darwin)-specific definitions
 //!
 //! This covers *-apple-* triples currently
+use dox::mem;
 
 pub type c_char = i8;
 pub type clock_t = c_ulong;
@@ -2383,7 +2384,45 @@ pub const SF_IMMUTABLE:     ::c_uint = 0x00020000;
 pub const SF_APPEND:        ::c_uint = 0x00040000;
 pub const UF_HIDDEN:        ::c_uint = 0x00008000;
 
+fn __DARWIN_ALIGN32(p: usize) -> usize {
+    const __DARWIN_ALIGNBYTES32: usize = mem::size_of::<u32>() - 1;
+    p + __DARWIN_ALIGNBYTES32 & !__DARWIN_ALIGNBYTES32
+}
+
 f! {
+    pub fn CMSG_NXTHDR(mhdr: *const ::msghdr,
+                       cmsg: *const ::cmsghdr) -> *mut ::cmsghdr {
+        if cmsg.is_null() {
+            return ::CMSG_FIRSTHDR(mhdr);
+        };
+        let cmsg_len = (*cmsg).cmsg_len as usize;
+        let next = cmsg as usize + __DARWIN_ALIGN32(cmsg_len as usize)
+            + __DARWIN_ALIGN32(mem::size_of::<::cmsghdr>());
+        let max = (*mhdr).msg_control as usize
+                   + (*mhdr).msg_controllen as usize;
+        if next > max {
+            0 as *mut ::cmsghdr
+        } else {
+            next as *mut ::cmsghdr
+        }
+    }
+
+    pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar {
+        (cmsg as *mut ::c_uchar)
+            .offset(__DARWIN_ALIGN32(mem::size_of::<::cmsghdr>()) as isize)
+    }
+
+    pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint {
+        (__DARWIN_ALIGN32(mem::size_of::<::cmsghdr>())
+            + __DARWIN_ALIGN32(length as usize))
+            as ::c_uint
+    }
+
+    pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint {
+        __DARWIN_ALIGN32(mem::size_of::<::cmsghdr>() + length as usize)
+            as ::c_uint
+    }
+
     pub fn WSTOPSIG(status: ::c_int) -> ::c_int {
         status >> 8
     }
diff --git a/src/unix/bsd/freebsdlike/dragonfly/mod.rs b/src/unix/bsd/freebsdlike/dragonfly/mod.rs
index 41b695659ae6bcd0008c6fc63590d2c708e305a0..b7029b01d7145acc65939ac9d8610543a9075765 100644
--- a/src/unix/bsd/freebsdlike/dragonfly/mod.rs
+++ b/src/unix/bsd/freebsdlike/dragonfly/mod.rs
@@ -782,6 +782,39 @@ pub const SF_NOHISTORY: ::c_ulong = 0x00400000;
 pub const SF_CACHE:     ::c_ulong = 0x00800000;
 pub const SF_XLINK:     ::c_ulong = 0x01000000;
 
+fn _CMSG_ALIGN(n: usize) -> usize {
+    (n + 3) & !3
+}
+
+f! {
+    pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar {
+        (cmsg as *mut ::c_uchar)
+            .offset(_CMSG_ALIGN(mem::size_of::<::cmsghdr>()) as isize)
+    }
+
+    pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint {
+        _CMSG_ALIGN(mem::size_of::<::cmsghdr>()) + length as usize
+    }
+
+    pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr)
+        -> *mut ::cmsghdr
+    {
+        let next = cmsg as usize + _CMSG_ALIGN((*cmsg).cmsg_len)
+            + _CMSG_ALIGN(mem::size_of::<::cmsghdr>());
+        let max = (*mhdr).msg_control as usize
+            + (*mhdr).msg_controllen as usize;
+        if next <= max {
+            (cmsg as usize + _CMSG_ALIGN((*cmsg).cmsg_len)) as *mut ::cmsghdr
+        } else {
+            0 as *mut ::cmsghdr
+        }
+    }
+
+    pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint {
+        _CMSG_ALIGN(mem::size_of::<::cmsghdr>()) + _CMSG_ALIGN(length as usize)
+    }
+}
+
 extern {
     pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int)
                     -> ::c_int;
diff --git a/src/unix/bsd/freebsdlike/freebsd/aarch64.rs b/src/unix/bsd/freebsdlike/freebsd/aarch64.rs
index 3d61f889d87e9bc3662390d539985a5f18a1a042..d33b475234a889c2474b40997636b1efbeed6b96 100644
--- a/src/unix/bsd/freebsdlike/freebsd/aarch64.rs
+++ b/src/unix/bsd/freebsdlike/freebsd/aarch64.rs
@@ -1,3 +1,5 @@
+use dox::mem;
+
 pub type c_long = i64;
 pub type c_ulong = u64;
 pub type time_t = i64;
@@ -29,4 +31,7 @@ s! {
     }
 }
 
+// should be pub(crate), but that requires Rust 1.18.0
+#[doc(hidden)]
+pub const _ALIGNBYTES: usize = mem::size_of::<::c_longlong>() - 1;
 pub const MAP_32BIT: ::c_int = 0x00080000;
diff --git a/src/unix/bsd/freebsdlike/freebsd/mod.rs b/src/unix/bsd/freebsdlike/freebsd/mod.rs
index 878deea36071d00dc44b59a671c11695cb7976a4..2bc900d3214cc0589d8a94c8e604af77699d16d7 100644
--- a/src/unix/bsd/freebsdlike/freebsd/mod.rs
+++ b/src/unix/bsd/freebsdlike/freebsd/mod.rs
@@ -1,3 +1,5 @@
+use dox::mem;
+
 pub type fflags_t = u32;
 pub type clock_t = i32;
 pub type ino_t = u32;
@@ -962,7 +964,43 @@ pub const UF_READONLY:  ::c_ulong = 0x00001000;
 pub const UF_HIDDEN:    ::c_ulong = 0x00008000;
 pub const SF_SNAPSHOT:  ::c_ulong = 0x00200000;
 
+fn _ALIGN(p: usize) -> usize {
+    (p + _ALIGNBYTES) & !_ALIGNBYTES
+}
+
 f! {
+    pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar {
+        (cmsg as *mut ::c_uchar)
+            .offset(_ALIGN(mem::size_of::<::cmsghdr>()) as isize)
+    }
+
+    pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint {
+        _ALIGN(mem::size_of::<::cmsghdr>()) as ::c_uint + length
+    }
+
+    pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr)
+        -> *mut ::cmsghdr
+    {
+        if cmsg.is_null() {
+            return ::CMSG_FIRSTHDR(mhdr);
+        };
+        let next = cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize)
+            + _ALIGN(mem::size_of::<::cmsghdr>());
+        let max = (*mhdr).msg_control as usize
+            + (*mhdr).msg_controllen as usize;
+        if next > max {
+            0 as *mut ::cmsghdr
+        } else {
+            (cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize))
+                as *mut ::cmsghdr
+        }
+    }
+
+    pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint {
+        (_ALIGN(mem::size_of::<::cmsghdr>()) + _ALIGN(length as usize))
+            as ::c_uint
+    }
+
     pub fn uname(buf: *mut ::utsname) -> ::c_int {
         __xuname(256, buf as *mut ::c_void)
     }
diff --git a/src/unix/bsd/freebsdlike/freebsd/x86.rs b/src/unix/bsd/freebsdlike/freebsd/x86.rs
index 8a5e5f9fb8d28fb9b624e02af35b244b95a4f7c0..a5495aaaa11a51cfe338478c353f2378a10ab223 100644
--- a/src/unix/bsd/freebsdlike/freebsd/x86.rs
+++ b/src/unix/bsd/freebsdlike/freebsd/x86.rs
@@ -1,3 +1,5 @@
+use dox::mem;
+
 pub type c_long = i32;
 pub type c_ulong = u32;
 pub type time_t = i32;
@@ -29,3 +31,7 @@ s! {
         __unused: [u8; 8],
     }
 }
+
+// should be pub(crate), but that requires Rust 1.18.0
+#[doc(hidden)]
+pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
diff --git a/src/unix/bsd/freebsdlike/freebsd/x86_64.rs b/src/unix/bsd/freebsdlike/freebsd/x86_64.rs
index 3d61f889d87e9bc3662390d539985a5f18a1a042..711feb7222ebaf1afc13bc64da417ff4d90bf297 100644
--- a/src/unix/bsd/freebsdlike/freebsd/x86_64.rs
+++ b/src/unix/bsd/freebsdlike/freebsd/x86_64.rs
@@ -1,3 +1,5 @@
+use dox::mem;
+
 pub type c_long = i64;
 pub type c_ulong = u64;
 pub type time_t = i64;
@@ -29,4 +31,7 @@ s! {
     }
 }
 
+// should be pub(crate), but that requires Rust 1.18.0
+#[doc(hidden)]
+pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
 pub const MAP_32BIT: ::c_int = 0x00080000;
diff --git a/src/unix/bsd/mod.rs b/src/unix/bsd/mod.rs
index 23efbe7e2b9a7b14a3e8a7b8db5427f31d42dd43..12f6e14d93c7c63dc8212e8429e702b5034493e6 100644
--- a/src/unix/bsd/mod.rs
+++ b/src/unix/bsd/mod.rs
@@ -342,43 +342,14 @@ pub const POLLRDBAND: ::c_short = 0x080;
 pub const POLLWRBAND: ::c_short = 0x100;
 
 f! {
-    pub fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr {
-        if (*mhdr).msg_controllen as usize >= mem::size_of::<cmsghdr>() {
-            (*mhdr).msg_control as *mut cmsghdr
+    pub fn CMSG_FIRSTHDR(mhdr: *const ::msghdr) -> *mut ::cmsghdr {
+        if (*mhdr).msg_controllen as usize >= mem::size_of::<::cmsghdr>() {
+            (*mhdr).msg_control as *mut ::cmsghdr
         } else {
-            0 as *mut cmsghdr
+            0 as *mut ::cmsghdr
         }
     }
 
-    pub fn CMSG_NXTHDR(mhdr: *const msghdr,
-                       cmsg: *const cmsghdr) -> *mut cmsghdr {
-        if cmsg.is_null() {
-            return CMSG_FIRSTHDR(mhdr);
-        };
-        let pad = mem::align_of::<cmsghdr>() - 1;
-        let next = cmsg as usize + (*cmsg).cmsg_len as usize + pad & !pad;
-        let max = (*mhdr).msg_control as usize
-            + (*mhdr).msg_controllen as usize;
-        if next < max {
-            next as *mut cmsghdr
-        } else {
-            0 as *mut cmsghdr
-        }
-    }
-
-    pub fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut ::c_uchar {
-        cmsg.offset(1) as *mut ::c_uchar
-    }
-
-    pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint {
-        let pad = mem::align_of::<cmsghdr>() as ::c_uint - 1;
-        mem::size_of::<cmsghdr>() as ::c_uint + ((length + pad) & !pad)
-    }
-
-    pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint {
-        mem::size_of::<cmsghdr>() as ::c_uint + length
-    }
-
     pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () {
         let bits = mem::size_of_val(&(*set).fds_bits[0]) * 8;
         let fd = fd as usize;
diff --git a/src/unix/bsd/netbsdlike/mod.rs b/src/unix/bsd/netbsdlike/mod.rs
index 771818b5f16c01f66870bfd32c5c8799211e9c88..291c081b97bc7538a388995e5bb22f092bd7d52c 100644
--- a/src/unix/bsd/netbsdlike/mod.rs
+++ b/src/unix/bsd/netbsdlike/mod.rs
@@ -1,3 +1,5 @@
+use dox::mem;
+
 pub type time_t = i64;
 pub type mode_t = u32;
 pub type nlink_t = ::uint32_t;
@@ -593,7 +595,43 @@ pub const SF_APPEND:        ::c_ulong = 0x00040000;
 
 pub const TIMER_ABSTIME: ::c_int = 1;
 
+fn _ALIGN(p: usize) -> usize {
+    (p + _ALIGNBYTES) & !_ALIGNBYTES
+}
+
 f! {
+    pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar {
+        (cmsg as *mut ::c_uchar)
+            .offset(_ALIGN(mem::size_of::<::cmsghdr>()) as isize)
+    }
+
+    pub fn CMSG_LEN(length: ::c_uint) -> ::c_uint {
+        _ALIGN(mem::size_of::<::cmsghdr>()) as ::c_uint + length
+    }
+
+    pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr)
+        -> *mut ::cmsghdr
+    {
+        if cmsg.is_null() {
+            return ::CMSG_FIRSTHDR(mhdr);
+        };
+        let next = cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize)
+            + _ALIGN(mem::size_of::<::cmsghdr>());
+        let max = (*mhdr).msg_control as usize
+            + (*mhdr).msg_controllen as usize;
+        if next > max {
+            0 as *mut ::cmsghdr
+        } else {
+            (cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize))
+                as *mut ::cmsghdr
+        }
+    }
+
+    pub fn CMSG_SPACE(length: ::c_uint) -> ::c_uint {
+        (_ALIGN(mem::size_of::<::cmsghdr>()) + _ALIGN(length as usize))
+            as ::c_uint
+    }
+
     pub fn WSTOPSIG(status: ::c_int) -> ::c_int {
         status >> 8
     }
diff --git a/src/unix/bsd/netbsdlike/netbsd/aarch64.rs b/src/unix/bsd/netbsdlike/netbsd/aarch64.rs
index 66f33016b14899b8025f2d6b55439eba287b0c54..cda75bc5cdd864b141305ffeec6d49109d568386 100644
--- a/src/unix/bsd/netbsdlike/netbsd/aarch64.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/aarch64.rs
@@ -1,3 +1,5 @@
+use dox::mem;
+
 use PT_FIRSTMACH;
 
 pub type c_long = i64;
@@ -5,6 +7,10 @@ pub type c_ulong = u64;
 pub type c_char = u8;
 pub type __cpu_simple_lock_nv_t = ::c_uchar;
 
+// should be pub(crate), but that requires Rust 1.18.0
+#[doc(hidden)]
+pub const _ALIGNBYTES: usize = mem::size_of::<::c_int>() - 1;
+
 pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 0;
 pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 1;
 pub const PT_GETFPREGS: ::c_int = PT_FIRSTMACH + 2;
diff --git a/src/unix/bsd/netbsdlike/netbsd/arm.rs b/src/unix/bsd/netbsdlike/netbsd/arm.rs
index 9e673166d6a037a547ea7d7a4e066bd80ab6c712..71c2cb7b7909a0ed7612651a595d1076d2f32a59 100644
--- a/src/unix/bsd/netbsdlike/netbsd/arm.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/arm.rs
@@ -1,3 +1,5 @@
+use dox::mem;
+
 use PT_FIRSTMACH;
 
 pub type c_long = i32;
@@ -5,6 +7,10 @@ pub type c_ulong = u32;
 pub type c_char = u8;
 pub type __cpu_simple_lock_nv_t = ::c_int;
 
+// should be pub(crate), but that requires Rust 1.18.0
+#[doc(hidden)]
+pub const _ALIGNBYTES: usize = mem::size_of::<::c_longlong>() - 1;
+
 pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1;
 pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 2;
 pub const PT_GETFPREGS: ::c_int = PT_FIRSTMACH + 3;
diff --git a/src/unix/bsd/netbsdlike/netbsd/powerpc.rs b/src/unix/bsd/netbsdlike/netbsd/powerpc.rs
index 54d069e6071b1b22e6386626fc460173bc8adebb..3c682c35cf4b41afdb9c6eadfbc0dd87792e3956 100644
--- a/src/unix/bsd/netbsdlike/netbsd/powerpc.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/powerpc.rs
@@ -1,3 +1,5 @@
+use dox::mem;
+
 use PT_FIRSTMACH;
 
 pub type c_long = i32;
@@ -5,6 +7,10 @@ pub type c_ulong = u32;
 pub type c_char = u8;
 pub type __cpu_simple_lock_nv_t = ::c_int;
 
+// should be pub(crate), but that requires Rust 1.18.0
+#[doc(hidden)]
+pub const _ALIGNBYTES: usize = mem::size_of::<::c_double>() - 1;
+
 pub const PT_STEP: ::c_int = PT_FIRSTMACH + 0;
 pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1;
 pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 2;
diff --git a/src/unix/bsd/netbsdlike/netbsd/sparc64.rs b/src/unix/bsd/netbsdlike/netbsd/sparc64.rs
index db8f2a94c52973010a3b46b3b57ab4f34dc95c9d..6a86759e07e76955017539c619678f46da29471a 100644
--- a/src/unix/bsd/netbsdlike/netbsd/sparc64.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/sparc64.rs
@@ -2,3 +2,7 @@ pub type c_long = i64;
 pub type c_ulong = u64;
 pub type c_char = i8;
 pub type __cpu_simple_lock_nv_t = ::c_uchar;
+
+// should be pub(crate), but that requires Rust 1.18.0
+#[doc(hidden)]
+pub const _ALIGNBYTES: usize = 0xf;
diff --git a/src/unix/bsd/netbsdlike/netbsd/x86.rs b/src/unix/bsd/netbsdlike/netbsd/x86.rs
index 8bd105841d53b9d6d529cc1885ac133304a1b158..4da99685f93da159129c5b334a5755924c08b12f 100644
--- a/src/unix/bsd/netbsdlike/netbsd/x86.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/x86.rs
@@ -1,4 +1,10 @@
+use dox::mem;
+
 pub type c_long = i32;
 pub type c_ulong = u32;
 pub type c_char = i8;
 pub type __cpu_simple_lock_nv_t = ::c_uchar;
+
+// should be pub(crate), but that requires Rust 1.18.0
+#[doc(hidden)]
+pub const _ALIGNBYTES: usize = mem::size_of::<::c_int>() - 1;
diff --git a/src/unix/bsd/netbsdlike/netbsd/x86_64.rs b/src/unix/bsd/netbsdlike/netbsd/x86_64.rs
index 8d3de8453afc4e6d37757bb560d9e89b77f147a8..af1b8f8000e8d0e6521bc89a06634c764b113fb1 100644
--- a/src/unix/bsd/netbsdlike/netbsd/x86_64.rs
+++ b/src/unix/bsd/netbsdlike/netbsd/x86_64.rs
@@ -1,3 +1,5 @@
+use dox::mem;
+
 use PT_FIRSTMACH;
 
 pub type c_long = i64;
@@ -5,6 +7,10 @@ pub type c_ulong = u64;
 pub type c_char = i8;
 pub type __cpu_simple_lock_nv_t = ::c_uchar;
 
+// should be pub(crate), but that requires Rust 1.18.0
+#[doc(hidden)]
+pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
+
 pub const PT_STEP: ::c_int = PT_FIRSTMACH + 0;
 pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1;
 pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 2;
diff --git a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/aarch64.rs b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/aarch64.rs
index 6aa9950ed1053d17940518e8db2f69f74e8a12a3..2a28c2a88a27bee05e11f152f2be68e9adf6a470 100644
--- a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/aarch64.rs
+++ b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/aarch64.rs
@@ -1,3 +1,9 @@
+use dox::mem;
+
 pub type c_long = i64;
 pub type c_ulong = u64;
 pub type c_char = u8;
+
+// should be pub(crate), but that requires Rust 1.18.0
+#[doc(hidden)]
+pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
diff --git a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86.rs b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86.rs
index a00e3337ef58f2217ad078852b1859ef31be2b6e..b63b69fb63fc83eb8189304a262346cdd28a70ef 100644
--- a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86.rs
+++ b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86.rs
@@ -1,3 +1,9 @@
+use dox::mem;
+
 pub type c_long = i32;
 pub type c_ulong = u32;
 pub type c_char = i8;
+
+// should be pub(crate), but that requires Rust 1.18.0
+#[doc(hidden)]
+pub const _ALIGNBYTES: usize = mem::size_of::<::c_int>() - 1;
diff --git a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86_64.rs b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86_64.rs
index 3bc7f524717b6bbaa010d1b20836b8731a9a013c..581096fdfa4529268edc76a953089b6820814922 100644
--- a/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86_64.rs
+++ b/src/unix/bsd/netbsdlike/openbsdlike/openbsd/x86_64.rs
@@ -1,9 +1,15 @@
+use dox::mem;
+
 use PT_FIRSTMACH;
 
 pub type c_long = i64;
 pub type c_ulong = u64;
 pub type c_char = i8;
 
+// should be pub(crate), but that requires Rust 1.18.0
+#[doc(hidden)]
+pub const _ALIGNBYTES: usize = mem::size_of::<::c_long>() - 1;
+
 pub const PT_STEP: ::c_int = PT_FIRSTMACH + 0;
 pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1;
 pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 2;