noq_udp/cmsg/
unix.rs

1use std::ffi::{c_int, c_uchar};
2
3use super::{CMsgHdr, MsgHdr};
4
5#[derive(Copy, Clone)]
6#[repr(align(8))] // Conservative bound for align_of<libc::cmsghdr>
7pub(crate) struct Aligned<T>(pub(crate) T);
8
9/// Helpers for [`libc::msghdr`]
10impl MsgHdr for libc::msghdr {
11    type ControlMessage = libc::cmsghdr;
12
13    fn cmsg_first_hdr(&self) -> *mut Self::ControlMessage {
14        unsafe { libc::CMSG_FIRSTHDR(self) }
15    }
16
17    fn cmsg_nxt_hdr(&self, cmsg: &Self::ControlMessage) -> *mut Self::ControlMessage {
18        unsafe { libc::CMSG_NXTHDR(self, cmsg) }
19    }
20
21    fn set_control_len(&mut self, len: usize) {
22        self.msg_controllen = len as _;
23        if len == 0 {
24            // netbsd is particular about this being a NULL pointer if there are no control
25            // messages.
26            self.msg_control = std::ptr::null_mut();
27        }
28    }
29
30    fn control_len(&self) -> usize {
31        self.msg_controllen as _
32    }
33}
34
35/// Helpers for [`libc::cmsghdr`]
36impl CMsgHdr for libc::cmsghdr {
37    fn cmsg_len(length: usize) -> usize {
38        unsafe { libc::CMSG_LEN(length as _) as usize }
39    }
40
41    fn cmsg_space(length: usize) -> usize {
42        unsafe { libc::CMSG_SPACE(length as _) as usize }
43    }
44
45    fn cmsg_data(&self) -> *mut c_uchar {
46        unsafe { libc::CMSG_DATA(self) }
47    }
48
49    fn set(&mut self, level: c_int, ty: c_int, len: usize) {
50        self.cmsg_level = level as _;
51        self.cmsg_type = ty as _;
52        self.cmsg_len = len as _;
53    }
54
55    fn len(&self) -> usize {
56        self.cmsg_len as _
57    }
58}