socket9 0.1.0-alpha.1

Extended untilities for the networking/unix sockets and raw network sockets
Documentation
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,
            )
        };

    // more likely it will not fail
    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)
        };

    // more likely it will not fail
    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 })
    }
}