Files
vnt/switch/rust-tun/src/platform/posix/sockaddr.rs
T

97 lines
2.5 KiB
Rust

// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
// Version 2, December 2004
//
// Copyleft (ↄ) meh. <[email protected]> | http://meh.schizofreni.co
//
// Everyone is permitted to copy and distribute verbatim or modified
// copies of this license document, and changing it is allowed as long
// as the name is changed.
//
// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
//
// 0. You just DO WHAT THE FUCK YOU WANT TO.
use std::mem;
use std::net::Ipv4Addr;
use std::ptr;
#[cfg(any(target_os = "macos", target_os = "ios"))]
use libc::c_uchar;
#[cfg(any(target_os = "linux", target_os = "android"))]
use libc::c_ushort;
use libc::AF_INET as _AF_INET;
use libc::{in_addr, sockaddr, sockaddr_in};
use crate::error::*;
/// A wrapper for `sockaddr_in`.
#[derive(Copy, Clone)]
pub struct SockAddr(sockaddr_in);
#[cfg(any(target_os = "linux", target_os = "android"))]
const AF_INET: c_ushort = _AF_INET as c_ushort;
#[cfg(any(target_os = "macos", target_os = "ios"))]
const AF_INET: c_uchar = _AF_INET as c_uchar;
impl SockAddr {
/// Create a new `SockAddr` from a generic `sockaddr`.
pub fn new(value: &sockaddr) -> Result<Self> {
if value.sa_family != AF_INET {
return Err(Error::InvalidAddress);
}
unsafe { Self::unchecked(value) }
}
/// # Safety
/// Create a new `SockAddr` and not check the source.
pub unsafe fn unchecked(value: &sockaddr) -> Result<Self> {
Ok(SockAddr(ptr::read(value as *const _ as *const _)))
}
/// # Safety
/// Get a generic pointer to the `SockAddr`.
pub unsafe fn as_ptr(&self) -> *const sockaddr {
&self.0 as *const _ as *const sockaddr
}
}
impl From<Ipv4Addr> for SockAddr {
fn from(ip: Ipv4Addr) -> SockAddr {
let octets = ip.octets();
let mut addr = unsafe { mem::zeroed::<sockaddr_in>() };
addr.sin_family = AF_INET;
addr.sin_port = 0;
addr.sin_addr = in_addr {
s_addr: u32::from_ne_bytes(octets),
};
SockAddr(addr)
}
}
impl From<SockAddr> for Ipv4Addr {
fn from(addr: SockAddr) -> Ipv4Addr {
let ip = addr.0.sin_addr.s_addr;
let [a, b, c, d] = ip.to_ne_bytes();
Ipv4Addr::new(a, b, c, d)
}
}
impl From<SockAddr> for sockaddr {
fn from(addr: SockAddr) -> sockaddr {
unsafe { mem::transmute(addr.0) }
}
}
impl From<SockAddr> for sockaddr_in {
fn from(addr: SockAddr) -> sockaddr_in {
addr.0
}
}