use std::{mem::MaybeUninit, net::{Ipv4Addr, Ipv6Addr}};
use crate::
{
LocalFrom, OptRMarker, OptWMarker, SockOptMarker
};
use super::*;
pub(crate)
fn getsockopt<VAL, FD>(fd: &FD) -> io::Result<VAL>
where
VAL: SockOptMarker + OptRMarker, FD: AsFd
{
let mut optval: MaybeUninit<VAL::InputType> = MaybeUninit::zeroed();
let mut len = size_of::<VAL::InputType>() as libc::socklen_t;
let res =
unsafe
{
libc::getsockopt(fd.as_fd().as_raw_fd(),VAL::SO_LEVEL,VAL::SO_OPTNAME,
optval.as_mut_ptr().cast(),&mut len,
)
};
if res == 0
{
return Ok(VAL::from( unsafe { optval.assume_init() }));
}
else
{
return Err(std::io::Error::last_os_error());
}
}
pub(crate)
fn setsockopt<VAL, FD>(fd: &FD, val: VAL) -> io::Result<()>
where
VAL: SockOptMarker + OptWMarker, FD: AsFd
{
let optval = ptr::addr_of!(val).cast();
let option_len: u32 = size_of::<VAL::DataType>() as libc::socklen_t;
let res =
unsafe
{
libc::setsockopt(fd.as_fd().as_raw_fd(), VAL::SO_LEVEL,VAL::SO_OPTNAME,
optval, option_len)
};
if res == 0
{
return Ok(());
}
else
{
return Err(std::io::Error::last_os_error());
}
}
impl LocalFrom<&Ipv4Addr> for libc::in_addr
{
fn from(addr: &Ipv4Addr) -> Self
{
return
libc::in_addr{ s_addr: u32::from_ne_bytes(addr.octets()) };
}
}
impl LocalFrom<&Ipv6Addr> for libc::in6_addr
{
fn from(addr: &Ipv6Addr) -> Self
{
return
libc::in6_addr{ s6_addr: addr.octets() };
}
}
impl LocalFrom<libc::in_addr> for Ipv4Addr
{
fn from(addr: libc::in_addr) -> Self
{
return
<Ipv4Addr as From<[u8; 4]>>::from(addr.s_addr.to_ne_bytes())
}
}
impl LocalFrom<libc::in6_addr> for Ipv6Addr
{
fn from(addr: libc::in6_addr) -> Self
{
return
<Ipv6Addr as From<[u8; 16]>>::from(addr.s6_addr)
}
}