]>
Commit | Line | Data |
---|---|---|
064997fb FG |
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 | #![allow(unsafe_code)] | |
4 | ||
5 | use super::super::c; | |
6 | use crate::net::{SocketAddrAny, SocketAddrStorage, SocketAddrUnix, SocketAddrV4, SocketAddrV6}; | |
7 | use core::mem::size_of; | |
8 | ||
9 | pub(crate) unsafe fn write_sockaddr( | |
10 | addr: &SocketAddrAny, | |
11 | storage: *mut SocketAddrStorage, | |
12 | ) -> usize { | |
13 | match addr { | |
14 | SocketAddrAny::V4(v4) => write_sockaddr_v4(v4, storage), | |
15 | SocketAddrAny::V6(v6) => write_sockaddr_v6(v6, storage), | |
16 | SocketAddrAny::Unix(unix) => write_sockaddr_unix(unix, storage), | |
17 | } | |
18 | } | |
19 | ||
20 | pub(crate) unsafe fn encode_sockaddr_v4(v4: &SocketAddrV4) -> c::sockaddr_in { | |
21 | c::sockaddr_in { | |
22 | sin_family: c::AF_INET as _, | |
23 | sin_port: u16::to_be(v4.port()), | |
24 | sin_addr: c::in_addr { | |
25 | s_addr: u32::from_ne_bytes(v4.ip().octets()), | |
26 | }, | |
27 | __pad: [0_u8; 8], | |
28 | } | |
29 | } | |
30 | ||
31 | unsafe fn write_sockaddr_v4(v4: &SocketAddrV4, storage: *mut SocketAddrStorage) -> usize { | |
32 | let encoded = encode_sockaddr_v4(v4); | |
33 | core::ptr::write(storage.cast(), encoded); | |
34 | size_of::<c::sockaddr_in>() | |
35 | } | |
36 | ||
37 | pub(crate) unsafe fn encode_sockaddr_v6(v6: &SocketAddrV6) -> c::sockaddr_in6 { | |
38 | c::sockaddr_in6 { | |
39 | sin6_family: c::AF_INET6 as _, | |
40 | sin6_port: u16::to_be(v6.port()), | |
41 | sin6_flowinfo: u32::to_be(v6.flowinfo()), | |
42 | sin6_addr: c::in6_addr { | |
43 | in6_u: linux_raw_sys::general::in6_addr__bindgen_ty_1 { | |
44 | u6_addr8: v6.ip().octets(), | |
45 | }, | |
46 | }, | |
47 | sin6_scope_id: v6.scope_id(), | |
48 | } | |
49 | } | |
50 | ||
51 | unsafe fn write_sockaddr_v6(v6: &SocketAddrV6, storage: *mut SocketAddrStorage) -> usize { | |
52 | let encoded = encode_sockaddr_v6(v6); | |
53 | core::ptr::write(storage.cast(), encoded); | |
54 | size_of::<c::sockaddr_in6>() | |
55 | } | |
56 | ||
57 | unsafe fn write_sockaddr_unix(unix: &SocketAddrUnix, storage: *mut SocketAddrStorage) -> usize { | |
58 | core::ptr::write(storage.cast(), unix.unix); | |
59 | unix.len() | |
60 | } |