use std::{net::{Ipv4Addr, Ipv6Addr}, os::windows::io::{AsRawSocket, AsSocket}};
use windows_sys::Win32::Networking::WinSock::{IN_ADDR, IN6_ADDR, SOCKET_ERROR};
use crate::{LocalFrom, OptRMarker, OptWMarker};
use super::*;
pub(crate)
fn getsockopt<VAL, SOCK>(sock: &SOCK) -> io::Result<VAL>
where
VAL: SockOptMarker + OptRMarker, SOCK: AsSocket
{
let mut optval: MaybeUninit<VAL::InputType> = MaybeUninit::zeroed();
let mut len = size_of::<VAL::InputType>() as i32;
let res =
unsafe
{
windows_sys::Win32::Networking::WinSock
::getsockopt(sock.as_socket().as_raw_socket() as usize,VAL::SO_LEVEL,VAL::SO_OPTNAME,
optval.as_mut_ptr().cast(),&mut len,
)
};
if res != SOCKET_ERROR
{
return Ok(VAL::from( unsafe { optval.assume_init() }));
}
else
{
return Err(std::io::Error::last_os_error());
}
}
pub(crate)
fn setsockopt<VAL, SOCK>(fd: &SOCK, val: VAL) -> io::Result<()>
where
VAL: SockOptMarker + OptWMarker, SOCK: AsSocket
{
let optval = ptr::addr_of!(val).cast();
let option_len = size_of::<VAL::DataType>() as i32;
let res =
unsafe
{
windows_sys::Win32::Networking::WinSock
::setsockopt(fd.as_socket().as_raw_socket() as usize, VAL::SO_LEVEL,VAL::SO_OPTNAME,
optval, option_len)
};
if res != SOCKET_ERROR
{
return Ok(());
}
else
{
return Err(std::io::Error::last_os_error());
}
}
impl LocalFrom<&Ipv4Addr> for IN_ADDR
{
fn from(addr: &Ipv4Addr) -> Self
{
let mut inaddr = IN_ADDR::default();
inaddr.S_un.S_addr = u32::from_ne_bytes(addr.octets());
return inaddr;
}
}
impl LocalFrom<&Ipv6Addr> for IN6_ADDR
{
fn from(addr: &Ipv6Addr) -> Self
{
let mut inaddr = IN6_ADDR::default();
inaddr.u.Byte = addr.octets();
return inaddr;
}
}
impl LocalFrom<IN_ADDR> for Ipv4Addr
{
fn from(addr: IN_ADDR) -> Self
{
return
<Ipv4Addr as From<[u8; 4]>>::from( unsafe{ addr.S_un.S_addr.to_ne_bytes() } )
}
}
impl LocalFrom<IN6_ADDR> for Ipv6Addr
{
fn from(addr: IN6_ADDR) -> Self
{
return
<Ipv6Addr as From<[u8; 16]>>::from( unsafe{ addr.u.Byte })
}
}