Skip to main content

socket9/windows/
sock_opts.rs

1use std::{net::{Ipv4Addr, Ipv6Addr}, os::windows::io::{AsRawSocket, AsSocket}};
2
3use windows_sys::Win32::Networking::WinSock::{IN_ADDR, IN6_ADDR, SOCKET_ERROR};
4
5use crate::{LocalFrom, OptRMarker, OptWMarker};
6
7use super::*;
8
9pub(crate) 
10fn getsockopt<VAL, SOCK>(sock: &SOCK) -> io::Result<VAL> 
11where 
12    VAL: SockOptMarker + OptRMarker, SOCK: AsSocket
13{
14    let mut optval: MaybeUninit<VAL::InputType> = MaybeUninit::zeroed();
15    let mut len = size_of::<VAL::InputType>() as i32;
16
17    let res = 
18        unsafe
19        {
20            windows_sys::Win32::Networking::WinSock
21                ::getsockopt(sock.as_socket().as_raw_socket() as usize,VAL::SO_LEVEL,VAL::SO_OPTNAME,
22                    optval.as_mut_ptr().cast(),&mut len,
23            )
24        };
25
26    // more likely it will not fail
27    if res != SOCKET_ERROR
28    {
29        return Ok(VAL::from( unsafe { optval.assume_init() }));
30    }
31    else
32    {
33        return Err(std::io::Error::last_os_error());
34    }
35}
36
37pub(crate) 
38fn setsockopt<VAL, SOCK>(fd: &SOCK, val: VAL) -> io::Result<()>
39where 
40    VAL: SockOptMarker + OptWMarker, SOCK: AsSocket
41{
42    let optval = ptr::addr_of!(val).cast();
43    let option_len = size_of::<VAL::DataType>() as i32;
44
45    let res = 
46        unsafe
47        {
48            windows_sys::Win32::Networking::WinSock
49                ::setsockopt(fd.as_socket().as_raw_socket() as usize, VAL::SO_LEVEL,VAL::SO_OPTNAME, 
50                    optval, option_len)
51        };
52
53    // more likely it will not fail
54    if res != SOCKET_ERROR
55    {
56        return Ok(());
57    }
58    else
59    {
60        return Err(std::io::Error::last_os_error());
61    }
62}
63
64impl LocalFrom<&Ipv4Addr> for IN_ADDR
65{
66    fn from(addr: &Ipv4Addr) -> Self 
67    {
68        let mut inaddr = IN_ADDR::default();
69
70        inaddr.S_un.S_addr = u32::from_ne_bytes(addr.octets());
71        
72        return inaddr;
73    }
74}
75
76
77impl LocalFrom<&Ipv6Addr> for IN6_ADDR
78{
79    fn from(addr: &Ipv6Addr) -> Self 
80    {
81        let mut inaddr = IN6_ADDR::default();
82
83        inaddr.u.Byte = addr.octets();
84        
85        return inaddr;
86    }
87}
88
89impl LocalFrom<IN_ADDR> for Ipv4Addr
90{
91    fn from(addr: IN_ADDR) -> Self 
92    {
93        return 
94            <Ipv4Addr as From<[u8; 4]>>::from( unsafe{ addr.S_un.S_addr.to_ne_bytes() } )
95    }
96}
97
98impl LocalFrom<IN6_ADDR> for Ipv6Addr
99{
100    fn from(addr: IN6_ADDR) -> Self 
101    {
102        return 
103            <Ipv6Addr as From<[u8; 16]>>::from( unsafe{ addr.u.Byte })
104    }
105}