• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! The BSD sockets API requires us to read the `ss_family` field before
2 //! we can interpret the rest of a `sockaddr` produced by the kernel.
3 
4 use super::super::c;
5 use super::addr::SocketAddrStorage;
6 #[cfg(unix)]
7 use super::addr::SocketAddrUnix;
8 use super::ext::{in6_addr_new, in_addr_new, sockaddr_in6_new};
9 use crate::net::{SocketAddrAny, SocketAddrV4, SocketAddrV6};
10 use core::mem::size_of;
11 
write_sockaddr( addr: &SocketAddrAny, storage: *mut SocketAddrStorage, ) -> usize12 pub(crate) unsafe fn write_sockaddr(
13     addr: &SocketAddrAny,
14     storage: *mut SocketAddrStorage,
15 ) -> usize {
16     match addr {
17         SocketAddrAny::V4(v4) => write_sockaddr_v4(v4, storage),
18         SocketAddrAny::V6(v6) => write_sockaddr_v6(v6, storage),
19         #[cfg(unix)]
20         SocketAddrAny::Unix(unix) => write_sockaddr_unix(unix, storage),
21     }
22 }
23 
encode_sockaddr_v4(v4: &SocketAddrV4) -> c::sockaddr_in24 pub(crate) unsafe fn encode_sockaddr_v4(v4: &SocketAddrV4) -> c::sockaddr_in {
25     c::sockaddr_in {
26         #[cfg(any(
27             target_os = "dragonfly",
28             target_os = "freebsd",
29             target_os = "haiku",
30             target_os = "ios",
31             target_os = "macos",
32             target_os = "netbsd",
33             target_os = "openbsd",
34         ))]
35         sin_len: size_of::<c::sockaddr_in>() as _,
36         sin_family: c::AF_INET as _,
37         sin_port: u16::to_be(v4.port()),
38         sin_addr: in_addr_new(u32::from_ne_bytes(v4.ip().octets())),
39         #[cfg(not(target_os = "haiku"))]
40         sin_zero: [0; 8_usize],
41         #[cfg(target_os = "haiku")]
42         sin_zero: [0; 24_usize],
43     }
44 }
45 
write_sockaddr_v4(v4: &SocketAddrV4, storage: *mut SocketAddrStorage) -> usize46 unsafe fn write_sockaddr_v4(v4: &SocketAddrV4, storage: *mut SocketAddrStorage) -> usize {
47     let encoded = encode_sockaddr_v4(v4);
48     core::ptr::write(storage.cast(), encoded);
49     size_of::<c::sockaddr_in>()
50 }
51 
encode_sockaddr_v6(v6: &SocketAddrV6) -> c::sockaddr_in652 pub(crate) unsafe fn encode_sockaddr_v6(v6: &SocketAddrV6) -> c::sockaddr_in6 {
53     #[cfg(any(
54         target_os = "dragonfly",
55         target_os = "freebsd",
56         target_os = "haiku",
57         target_os = "ios",
58         target_os = "macos",
59         target_os = "netbsd",
60         target_os = "openbsd",
61     ))]
62     {
63         sockaddr_in6_new(
64             size_of::<c::sockaddr_in6>() as _,
65             c::AF_INET6 as _,
66             u16::to_be(v6.port()),
67             u32::to_be(v6.flowinfo()),
68             in6_addr_new(v6.ip().octets()),
69             v6.scope_id(),
70         )
71     }
72     #[cfg(not(any(
73         target_os = "dragonfly",
74         target_os = "freebsd",
75         target_os = "haiku",
76         target_os = "ios",
77         target_os = "macos",
78         target_os = "netbsd",
79         target_os = "openbsd",
80     )))]
81     {
82         sockaddr_in6_new(
83             c::AF_INET6 as _,
84             u16::to_be(v6.port()),
85             u32::to_be(v6.flowinfo()),
86             in6_addr_new(v6.ip().octets()),
87             v6.scope_id(),
88         )
89     }
90 }
91 
write_sockaddr_v6(v6: &SocketAddrV6, storage: *mut SocketAddrStorage) -> usize92 unsafe fn write_sockaddr_v6(v6: &SocketAddrV6, storage: *mut SocketAddrStorage) -> usize {
93     let encoded = encode_sockaddr_v6(v6);
94     core::ptr::write(storage.cast(), encoded);
95     size_of::<c::sockaddr_in6>()
96 }
97 
98 #[cfg(unix)]
write_sockaddr_unix(unix: &SocketAddrUnix, storage: *mut SocketAddrStorage) -> usize99 unsafe fn write_sockaddr_unix(unix: &SocketAddrUnix, storage: *mut SocketAddrStorage) -> usize {
100     core::ptr::write(storage.cast(), unix.unix);
101     unix.len()
102 }
103