default_net/sys/
unix.rs

1use std::io;
2use std::mem;
3use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
4
5pub type SockAddrIn = libc::sockaddr_in;
6pub type SockAddrIn6 = libc::sockaddr_in6;
7pub type SockAddrStorage = libc::sockaddr_storage;
8pub type InAddr = libc::in_addr;
9
10pub const AF_INET: libc::c_int = libc::AF_INET;
11pub const AF_INET6: libc::c_int = libc::AF_INET6;
12
13pub use libc::{IFF_BROADCAST, IFF_LOOPBACK, IFF_MULTICAST, IFF_POINTOPOINT, IFF_UP};
14
15fn ntohs(u: u16) -> u16 {
16    u16::from_be(u)
17}
18
19pub fn sockaddr_to_addr(storage: &SockAddrStorage, len: usize) -> io::Result<SocketAddr> {
20    match storage.ss_family as libc::c_int {
21        AF_INET => {
22            assert!(len as usize >= mem::size_of::<SockAddrIn>());
23            let storage: &SockAddrIn = unsafe { mem::transmute(storage) };
24            let ip = ipv4_addr_int(storage.sin_addr);
25            // octets
26            let o1 = (ip >> 24) as u8;
27            let o2 = (ip >> 16) as u8;
28            let o3 = (ip >> 8) as u8;
29            let o4 = ip as u8;
30            let sockaddrv4 =
31                SocketAddrV4::new(Ipv4Addr::new(o1, o2, o3, o4), ntohs(storage.sin_port));
32            Ok(SocketAddr::V4(sockaddrv4))
33        }
34        AF_INET6 => {
35            assert!(len as usize >= mem::size_of::<SockAddrIn6>());
36            let storage: &SockAddrIn6 = unsafe { mem::transmute(storage) };
37            let arr: [u16; 8] = unsafe { mem::transmute(storage.sin6_addr.s6_addr) };
38            // hextets
39            let h1 = ntohs(arr[0]);
40            let h2 = ntohs(arr[1]);
41            let h3 = ntohs(arr[2]);
42            let h4 = ntohs(arr[3]);
43            let h5 = ntohs(arr[4]);
44            let h6 = ntohs(arr[5]);
45            let h7 = ntohs(arr[6]);
46            let h8 = ntohs(arr[7]);
47            let ip = Ipv6Addr::new(h1, h2, h3, h4, h5, h6, h7, h8);
48            Ok(SocketAddr::V6(SocketAddrV6::new(
49                ip,
50                ntohs(storage.sin6_port),
51                u32::from_be(storage.sin6_flowinfo),
52                storage.sin6_scope_id,
53            )))
54        }
55        _ => Err(io::Error::new(io::ErrorKind::InvalidData, "Not supported")),
56    }
57}
58
59#[inline(always)]
60pub fn ipv4_addr_int(addr: InAddr) -> u32 {
61    (addr.s_addr as u32).to_be()
62}