1use super::super::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(not(feature = "std"))] 23#[cfg(windows)] 24#[inline] 25pub(crate) const fn in_addr_s_addr(addr: c::in_addr) -> u32 { 26 // This should be `*addr.S_un.S_addr()`, except that isn't a `const fn`. 27 unsafe { core::mem::transmute(addr) } 28} 29 30// TODO: With Rust 1.55, we can use the above `in_addr_s_addr` definition that 31// uses a const-fn transmute. 32#[cfg(feature = "std")] 33#[cfg(windows)] 34#[inline] 35pub(crate) fn in_addr_s_addr(addr: c::in_addr) -> u32 { 36 // This should be `*addr.S_un.S_addr()`, except that isn't a `const fn`. 37 unsafe { core::mem::transmute(addr) } 38} 39 40#[cfg(not(windows))] 41#[inline] 42pub(crate) const fn in_addr_new(s_addr: u32) -> c::in_addr { 43 c::in_addr { s_addr } 44} 45 46#[cfg(not(feature = "std"))] 47#[cfg(windows)] 48#[inline] 49pub(crate) const fn in_addr_new(s_addr: u32) -> c::in_addr { 50 unsafe { core::mem::transmute(s_addr) } 51} 52 53// TODO: With Rust 1.55, we can use the above `in_addr_new` definition that 54// uses a const-fn transmute. 55#[cfg(feature = "std")] 56#[cfg(windows)] 57#[inline] 58pub(crate) fn in_addr_new(s_addr: u32) -> c::in_addr { 59 unsafe { core::mem::transmute(s_addr) } 60} 61 62#[cfg(not(windows))] 63#[inline] 64pub(crate) const fn in6_addr_s6_addr(addr: c::in6_addr) -> [u8; 16] { 65 addr.s6_addr 66} 67 68#[cfg(not(feature = "std"))] 69#[cfg(windows)] 70#[inline] 71pub(crate) const fn in6_addr_s6_addr(addr: c::in6_addr) -> [u8; 16] { 72 unsafe { core::mem::transmute(addr) } 73} 74 75// TODO: With Rust 1.55, we can use the above `in6_addr_s6_addr` definition 76// that uses a const-fn transmute. 77#[cfg(feature = "std")] 78#[cfg(windows)] 79#[inline] 80pub(crate) fn in6_addr_s6_addr(addr: c::in6_addr) -> [u8; 16] { 81 unsafe { core::mem::transmute(addr) } 82} 83 84#[cfg(not(windows))] 85#[inline] 86pub(crate) const fn in6_addr_new(s6_addr: [u8; 16]) -> c::in6_addr { 87 c::in6_addr { s6_addr } 88} 89 90#[cfg(not(feature = "std"))] 91#[cfg(windows)] 92#[inline] 93pub(crate) const fn in6_addr_new(s6_addr: [u8; 16]) -> c::in6_addr { 94 unsafe { core::mem::transmute(s6_addr) } 95} 96 97// TODO: With Rust 1.55, we can use the above `in6_addr_new` definition that 98// uses a const-fn transmute. 99#[cfg(feature = "std")] 100#[cfg(windows)] 101#[inline] 102pub(crate) fn in6_addr_new(s6_addr: [u8; 16]) -> c::in6_addr { 103 unsafe { core::mem::transmute(s6_addr) } 104} 105 106#[cfg(not(windows))] 107#[inline] 108pub(crate) const fn sockaddr_in6_sin6_scope_id(addr: c::sockaddr_in6) -> u32 { 109 addr.sin6_scope_id 110} 111 112#[cfg(not(feature = "std"))] 113#[cfg(windows)] 114#[inline] 115pub(crate) const fn sockaddr_in6_sin6_scope_id(addr: c::sockaddr_in6) -> u32 { 116 let addr: sockaddr_in6 = unsafe { core::mem::transmute(addr) }; 117 addr.sin6_scope_id 118} 119 120// TODO: With Rust 1.55, we can use the above `sockaddr_in6_sin6_scope_id` 121// definition that uses a const-fn transmute. 122#[cfg(feature = "std")] 123#[cfg(windows)] 124#[inline] 125pub(crate) fn sockaddr_in6_sin6_scope_id(addr: c::sockaddr_in6) -> u32 { 126 let addr: sockaddr_in6 = unsafe { core::mem::transmute(addr) }; 127 addr.sin6_scope_id 128} 129 130#[cfg(not(windows))] 131#[inline] 132pub(crate) const fn sockaddr_in6_new( 133 #[cfg(any( 134 target_os = "dragonfly", 135 target_os = "freebsd", 136 target_os = "haiku", 137 target_os = "ios", 138 target_os = "macos", 139 target_os = "netbsd", 140 target_os = "openbsd", 141 ))] 142 sin6_len: u8, 143 sin6_family: c::sa_family_t, 144 sin6_port: u16, 145 sin6_flowinfo: u32, 146 sin6_addr: c::in6_addr, 147 sin6_scope_id: u32, 148) -> c::sockaddr_in6 { 149 c::sockaddr_in6 { 150 #[cfg(any( 151 target_os = "dragonfly", 152 target_os = "freebsd", 153 target_os = "haiku", 154 target_os = "ios", 155 target_os = "macos", 156 target_os = "netbsd", 157 target_os = "openbsd", 158 ))] 159 sin6_len, 160 sin6_family, 161 sin6_port, 162 sin6_flowinfo, 163 sin6_addr, 164 sin6_scope_id, 165 #[cfg(any(target_os = "illumos", target_os = "solaris"))] 166 __sin6_src_id: 0, 167 } 168} 169 170#[cfg(not(feature = "std"))] 171#[cfg(windows)] 172#[inline] 173pub(crate) const fn sockaddr_in6_new( 174 sin6_family: u16, 175 sin6_port: u16, 176 sin6_flowinfo: u32, 177 sin6_addr: c::in6_addr, 178 sin6_scope_id: u32, 179) -> c::sockaddr_in6 { 180 let addr = sockaddr_in6 { 181 sin6_family, 182 sin6_port, 183 sin6_flowinfo, 184 sin6_addr, 185 sin6_scope_id, 186 }; 187 unsafe { core::mem::transmute(addr) } 188} 189 190// TODO: With Rust 1.55, we can use the above `sockaddr_in6_new` definition 191// that uses a const-fn transmute. 192#[cfg(feature = "std")] 193#[cfg(windows)] 194#[inline] 195pub(crate) fn sockaddr_in6_new( 196 sin6_family: u16, 197 sin6_port: u16, 198 sin6_flowinfo: u32, 199 sin6_addr: c::in6_addr, 200 sin6_scope_id: u32, 201) -> c::sockaddr_in6 { 202 let addr = sockaddr_in6 { 203 sin6_family, 204 sin6_port, 205 sin6_flowinfo, 206 sin6_addr, 207 sin6_scope_id, 208 }; 209 unsafe { core::mem::transmute(addr) } 210} 211