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