rustix/backend/libc/net/
ext.rs

1use crate::backend::c;
2
3/// The windows `sockaddr_in6` type is a union with accessor functions which
4/// are not `const fn`. Define our own layout-compatible version so that we
5/// can transmute in and out of it.
6#[cfg(windows)]
7#[repr(C)]
8struct sockaddr_in6 {
9    sin6_family: u16,
10    sin6_port: u16,
11    sin6_flowinfo: u32,
12    sin6_addr: c::in6_addr,
13    sin6_scope_id: u32,
14}
15
16#[cfg(not(windows))]
17#[inline]
18pub(crate) const fn in_addr_s_addr(addr: c::in_addr) -> u32 {
19    addr.s_addr
20}
21
22#[cfg(windows)]
23#[inline]
24pub(crate) const fn in_addr_s_addr(addr: c::in_addr) -> u32 {
25    // This should be `*addr.S_un.S_addr()`, except that isn't a `const fn`.
26    unsafe { core::mem::transmute(addr) }
27}
28
29#[cfg(not(windows))]
30#[inline]
31pub(crate) const fn in_addr_new(s_addr: u32) -> c::in_addr {
32    c::in_addr { s_addr }
33}
34
35#[cfg(windows)]
36#[inline]
37pub(crate) const fn in_addr_new(s_addr: u32) -> c::in_addr {
38    unsafe { core::mem::transmute(s_addr) }
39}
40
41#[cfg(not(windows))]
42#[inline]
43pub(crate) const fn in6_addr_s6_addr(addr: c::in6_addr) -> [u8; 16] {
44    addr.s6_addr
45}
46
47#[cfg(windows)]
48#[inline]
49pub(crate) const fn in6_addr_s6_addr(addr: c::in6_addr) -> [u8; 16] {
50    unsafe { core::mem::transmute(addr) }
51}
52
53#[cfg(not(windows))]
54#[inline]
55pub(crate) const fn in6_addr_new(s6_addr: [u8; 16]) -> c::in6_addr {
56    c::in6_addr { s6_addr }
57}
58
59#[cfg(windows)]
60#[inline]
61pub(crate) const fn in6_addr_new(s6_addr: [u8; 16]) -> c::in6_addr {
62    unsafe { core::mem::transmute(s6_addr) }
63}
64
65#[cfg(not(windows))]
66#[inline]
67pub(crate) const fn sockaddr_in6_sin6_scope_id(addr: &c::sockaddr_in6) -> u32 {
68    addr.sin6_scope_id
69}
70
71#[cfg(windows)]
72#[inline]
73pub(crate) const fn sockaddr_in6_sin6_scope_id(addr: &c::sockaddr_in6) -> u32 {
74    let addr: &sockaddr_in6 = unsafe { core::mem::transmute(addr) };
75    addr.sin6_scope_id
76}
77
78#[cfg(not(windows))]
79#[inline]
80pub(crate) const fn sockaddr_in6_new(
81    #[cfg(any(
82        bsd,
83        target_os = "aix",
84        target_os = "espidf",
85        target_os = "haiku",
86        target_os = "hurd",
87        target_os = "nto",
88        target_os = "vita"
89    ))]
90    sin6_len: u8,
91    sin6_family: c::sa_family_t,
92    sin6_port: u16,
93    sin6_flowinfo: u32,
94    sin6_addr: c::in6_addr,
95    sin6_scope_id: u32,
96) -> c::sockaddr_in6 {
97    c::sockaddr_in6 {
98        #[cfg(any(
99            bsd,
100            target_os = "aix",
101            target_os = "espidf",
102            target_os = "haiku",
103            target_os = "hurd",
104            target_os = "nto",
105            target_os = "vita"
106        ))]
107        sin6_len,
108        sin6_family,
109        sin6_port,
110        sin6_flowinfo,
111        sin6_addr,
112        sin6_scope_id,
113        #[cfg(solarish)]
114        __sin6_src_id: 0,
115        #[cfg(target_os = "vita")]
116        sin6_vport: 0,
117    }
118}
119
120#[cfg(windows)]
121#[inline]
122pub(crate) const fn sockaddr_in6_new(
123    sin6_family: u16,
124    sin6_port: u16,
125    sin6_flowinfo: u32,
126    sin6_addr: c::in6_addr,
127    sin6_scope_id: u32,
128) -> c::sockaddr_in6 {
129    let addr = sockaddr_in6 {
130        sin6_family,
131        sin6_port,
132        sin6_flowinfo,
133        sin6_addr,
134        sin6_scope_id,
135    };
136    unsafe { core::mem::transmute(addr) }
137}