tun_sync/platform/posix/
sockaddr.rs

1//            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2//                    Version 2, December 2004
3//
4// Copyleft (ↄ) meh. <meh@schizofreni.co> | http://meh.schizofreni.co
5//
6// Everyone is permitted to copy and distribute verbatim or modified
7// copies of this license document, and changing it is allowed as long
8// as the name is changed.
9//
10//            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11//   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12//
13//  0. You just DO WHAT THE FUCK YOU WANT TO.
14
15use 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/// A wrapper for `sockaddr_in`.
30#[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    /// Create a new `SockAddr` from a generic `sockaddr`.
41    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    /// # Safety
50    ///  Create a new `SockAddr` and not check the source.
51    pub unsafe fn unchecked(value: &sockaddr) -> Result<Self> {
52        Ok(SockAddr(ptr::read(value as *const _ as *const _)))
53    }
54
55    /// # Safety
56    /// Get a generic pointer to the `SockAddr`.
57    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}