1 // Copyright (c) 2023 Huawei Device Co., Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 use std::mem; 15 use std::net::SocketAddr; 16 17 use crate::sys::winapi::{ 18 AF_INET, AF_INET6, IN6_ADDR, IN6_ADDR_0, IN_ADDR, IN_ADDR_0, SOCKADDR, SOCKADDR_IN, 19 SOCKADDR_IN6, SOCKADDR_IN6_0, 20 }; 21 22 #[repr(C)] 23 pub(crate) union SocketAddrWin { 24 v4: SOCKADDR_IN, 25 v6: SOCKADDR_IN6, 26 } 27 28 impl SocketAddrWin { 29 pub(crate) fn as_ptr(&self) -> *const SOCKADDR { 30 (self as *const SocketAddrWin).cast::<SOCKADDR>() 31 } 32 } 33 34 pub(crate) fn socket_addr_trans(addr: &SocketAddr) -> (SocketAddrWin, i32) { 35 match addr { 36 SocketAddr::V4(ref addr) => { 37 let sin_addr = unsafe { 38 let mut in_addr_0 = mem::zeroed::<IN_ADDR_0>(); 39 in_addr_0.S_addr = u32::from_ne_bytes(addr.ip().octets()); 40 IN_ADDR { S_un: in_addr_0 } 41 }; 42 43 let sockaddr_in = SOCKADDR_IN { 44 sin_family: AF_INET, 45 sin_port: addr.port().to_be(), 46 sin_addr, 47 sin_zero: [0; 8], 48 }; 49 50 ( 51 SocketAddrWin { v4: sockaddr_in }, 52 mem::size_of::<SOCKADDR_IN>() as i32, 53 ) 54 } 55 56 SocketAddr::V6(ref addr) => { 57 let sin_addr6 = unsafe { 58 let mut u = mem::zeroed::<IN6_ADDR_0>(); 59 u.Byte = addr.ip().octets(); 60 IN6_ADDR { u } 61 }; 62 63 let sockaddr_in6_0 = unsafe { 64 let mut si0 = mem::zeroed::<SOCKADDR_IN6_0>(); 65 si0.sin6_scope_id = addr.scope_id(); 66 si0 67 }; 68 69 let sockaddr_in6 = SOCKADDR_IN6 { 70 sin6_family: AF_INET6, 71 sin6_port: addr.port().to_be(), 72 sin6_flowinfo: addr.flowinfo(), 73 sin6_addr: sin_addr6, 74 Anonymous: sockaddr_in6_0, 75 }; 76 77 ( 78 SocketAddrWin { v6: sockaddr_in6 }, 79 mem::size_of::<SOCKADDR_IN6>() as i32, 80 ) 81 } 82 } 83 } 84