tun_sync/platform/posix/
sockaddr.rs1use std::mem;
16use std::net::Ipv4Addr;
17use std::ptr;
18
19#[cfg(any(target_os = "macos", target_os = "ios"))]
20use libc::c_uchar;
21#[cfg(any(target_os = "linux", target_os = "android"))]
22use libc::c_ushort;
23
24use libc::AF_INET as _AF_INET;
25use libc::{in_addr, sockaddr, sockaddr_in};
26
27use crate::error::*;
28
29#[derive(Copy, Clone)]
31pub struct SockAddr(sockaddr_in);
32
33#[cfg(any(target_os = "linux", target_os = "android"))]
34const AF_INET: c_ushort = _AF_INET as c_ushort;
35
36#[cfg(any(target_os = "macos", target_os = "ios"))]
37const AF_INET: c_uchar = _AF_INET as c_uchar;
38
39impl SockAddr {
40 pub fn new(value: &sockaddr) -> Result<Self> {
42 if value.sa_family != AF_INET {
43 return Err(Error::InvalidAddress);
44 }
45
46 unsafe { Self::unchecked(value) }
47 }
48
49 pub unsafe fn unchecked(value: &sockaddr) -> Result<Self> {
52 Ok(SockAddr(ptr::read(value as *const _ as *const _)))
53 }
54
55 pub unsafe fn as_ptr(&self) -> *const sockaddr {
58 &self.0 as *const _ as *const sockaddr
59 }
60}
61
62impl From<Ipv4Addr> for SockAddr {
63 fn from(ip: Ipv4Addr) -> SockAddr {
64 let octets = ip.octets();
65 let mut addr = unsafe { mem::zeroed::<sockaddr_in>() };
66
67 addr.sin_family = AF_INET;
68 addr.sin_port = 0;
69 addr.sin_addr = in_addr {
70 s_addr: u32::from_ne_bytes(octets),
71 };
72
73 SockAddr(addr)
74 }
75}
76
77impl From<SockAddr> for Ipv4Addr {
78 fn from(addr: SockAddr) -> Ipv4Addr {
79 let ip = addr.0.sin_addr.s_addr;
80 let [a, b, c, d] = ip.to_ne_bytes();
81
82 Ipv4Addr::new(a, b, c, d)
83 }
84}
85
86impl From<SockAddr> for sockaddr {
87 fn from(addr: SockAddr) -> sockaddr {
88 unsafe { mem::transmute(addr.0) }
89 }
90}
91
92impl From<SockAddr> for sockaddr_in {
93 fn from(addr: SockAddr) -> sockaddr_in {
94 addr.0
95 }
96}