linux_io/socket.rs
1/// Address types for the IPv4 and IPv6 protocol families.
2pub mod ip;
3
4use core::mem::size_of;
5
6pub use linux_unsafe::sock_type;
7
8use crate::fd::ioctl::{ioctl_read, IoctlReqRead, _IOR};
9
10/// A trait implemented by all socket address types.
11///
12/// **Safety:**
13/// - Implementers must ensure that the two raw methods always return
14/// valid pointers and lengths for the kernel to refer to. The pointers should
15/// always be to a sockaddr-shaped structure, which always starts with
16/// an `sa_family_t` field describing the protocol family that the address
17/// belongs to.
18/// - Both methods must return a pointer to the same memory so that writes
19/// through the mut pointer will be visible to reads through the const pointer.
20pub unsafe trait SockAddr {
21 /// Returns a raw const pointer and the length of what it points to for
22 /// use when sending a socket address to the kernel.
23 ///
24 /// **Safety:** Caller must ensure that `self` remains valid throughout
25 /// all use of the returned pointer and that use of it is consistent
26 /// with a shared borrow.
27 unsafe fn sockaddr_raw_const(&self)
28 -> (*const linux_unsafe::sockaddr, linux_unsafe::socklen_t);
29
30 /// Returns a raw mut pointer and the length of what it points to for
31 /// use when retrieving a socket address from the kernel.
32 ///
33 /// **Safety:** Caller must ensure that `self` remains valid throughout
34 /// all use of the returned pointer and that use of it is consistent
35 /// with a mutable borrow.
36 unsafe fn sockaddr_raw_mut(&mut self)
37 -> (*mut linux_unsafe::sockaddr, linux_unsafe::socklen_t);
38}
39
40/// Represents a socket protocol that is compatible with sockets belonging to
41/// the domain/family `FAMILY`.
42///
43/// This trait allows [`super::File::socket`] to return a file of the
44/// appropriate device type for the selected protocol so that the relevant
45/// socket `ioctl` requests will be supported on its result.
46pub trait SocketProtocol {
47 type Device: crate::fd::ioctl::IoDevice;
48
49 fn raw_protocol_num(&self) -> linux_unsafe::int;
50}
51
52/// Builds a reasonable default implementation of [`SocketProtocol`] with
53/// a fixed protocol number and device type.
54///
55/// **Safety:** Caller must ensure that the specified device marker type
56/// is suitable for the type of socket the kernel will return when requesting
57/// this protocol. This works in conjunction with the safety rules for
58/// implementing ioctl requests on device types; the designated device should
59/// only have ioctl request constants that can be called against a file
60/// descriptor of this protocol without the risk of memory corruption caused
61/// by an incorrect argument type.
62#[inline(always)]
63pub const unsafe fn socket_protocol<Device: crate::fd::ioctl::IoDevice>(
64 num: linux_unsafe::int,
65) -> SocketProtocolFixed<Device> {
66 SocketProtocolFixed::numbered(num)
67}
68
69/// A reasonable default implementation of [`SocketProtocol`] with a fixed
70/// protocol number and device type.
71///
72/// This is the return type of [`socket_protocol`].
73#[repr(transparent)]
74pub struct SocketProtocolFixed<Device: crate::fd::ioctl::IoDevice> {
75 num: linux_unsafe::int,
76 _phantom: core::marker::PhantomData<Device>,
77}
78
79/// A convenience implementation of [`SocketProtocol`] for simple protocols
80/// that belong to only a single family and have a fixed protocol number.
81impl<Device: crate::fd::ioctl::IoDevice> SocketProtocolFixed<Device> {
82 #[inline(always)]
83 pub(crate) const unsafe fn numbered(num: linux_unsafe::int) -> Self {
84 // The value of a `SocketProtocolFixed` is always just its protocol
85 // number directly, making it have identical layout to the raw
86 // protocol argument on the `socket` system call.
87 Self {
88 num,
89 _phantom: core::marker::PhantomData,
90 }
91 }
92}
93
94impl<Device: crate::fd::ioctl::IoDevice> SocketProtocol for SocketProtocolFixed<Device> {
95 type Device = Device;
96
97 #[inline(always)]
98 fn raw_protocol_num(&self) -> linux_unsafe::int {
99 self.num
100 }
101}
102
103/// Device type marker for [`crate::File`] instances that represent sockets.
104///
105/// In practice there should not typically be a `File<SocketDevice>` directly,
106/// but instead should use a protocol-specific device type that also has a
107/// blanket impl to make all of the `SocketDevice` ioctl requests available
108/// too.
109pub struct SocketDevice;
110
111impl crate::fd::ioctl::IoDevice for SocketDevice {}
112
113const SOCK_IOC_TYPE: linux_unsafe::ulong = 0x89;
114
115/// `ioctl` request to retrieve a `struct timeval` with the receive timestamp
116/// of the last packet passed to the user.
117pub const SIOCGSTAMP: IoctlReqRead<SocketDevice, linux_unsafe::timeval> = unsafe {
118 ioctl_read(_IOR(
119 SOCK_IOC_TYPE,
120 0x06,
121 // This size is expressed in the kernel as sizeof(long long[2]), rather
122 // than as "struct timeval".
123 (size_of::<core::ffi::c_longlong>() * 2) as linux_unsafe::ulong,
124 ))
125};