1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
use c_types;
use c_ares_sys;
use types::AddressFamily;
use std::ffi::CStr;
use std::mem;
use std::os::raw::c_int;
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6};
use std::str;
pub fn address_family(family: c_int) -> Option<AddressFamily> {
match family {
c_types::AF_INET => Some(AddressFamily::INET),
c_types::AF_INET6 => Some(AddressFamily::INET6),
c_types::AF_UNSPEC => Some(AddressFamily::UNSPEC),
_ => None,
}
}
#[cfg(unix)]
pub fn ipv4_as_in_addr(ipv4: &Ipv4Addr) -> c_types::in_addr {
c_types::in_addr {
s_addr: u32::from(*ipv4).to_be(),
}
}
#[cfg(windows)]
pub fn ipv4_as_in_addr(ipv4: &Ipv4Addr) -> c_types::in_addr {
let octets = ipv4.octets();
let mut in_addr: c_types::in_addr = unsafe { mem::zeroed() };
{
let bytes = unsafe { in_addr.S_un.S_un_b_mut() };
bytes.s_b1 = octets[0];
bytes.s_b2 = octets[1];
bytes.s_b3 = octets[2];
bytes.s_b4 = octets[3];
}
in_addr
}
#[cfg(unix)]
pub fn ipv4_from_in_addr(in_addr: &c_types::in_addr) -> Ipv4Addr {
Ipv4Addr::from(u32::from_be(in_addr.s_addr))
}
#[cfg(windows)]
pub fn ipv4_from_in_addr(in_addr: &c_types::in_addr) -> Ipv4Addr {
let bytes = unsafe { in_addr.S_un.S_un_b() };
Ipv4Addr::new(bytes.s_b1, bytes.s_b2, bytes.s_b3, bytes.s_b4)
}
#[cfg(unix)]
pub fn ipv6_as_in6_addr(ipv6: &Ipv6Addr) -> c_types::in6_addr {
let octets = ipv6.octets();
let mut in6_addr: c_types::in6_addr = unsafe { mem::zeroed() };
in6_addr.s6_addr.copy_from_slice(&octets);
in6_addr
}
#[cfg(windows)]
pub fn ipv6_as_in6_addr(ipv6: &Ipv6Addr) -> c_types::in6_addr {
let octets = ipv6.octets();
let mut in6_addr: c_types::in6_addr = unsafe { mem::zeroed() };
{
let bytes = unsafe { in6_addr.u.Byte_mut() };
bytes.copy_from_slice(&octets);
}
in6_addr
}
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd",
target_os = "dragonfly", target_os = "openbsd", target_os = "netbsd",
target_os = "bitrig"))]
pub fn socket_addrv4_as_sockaddr_in(sock_v4: &SocketAddrV4) -> c_types::sockaddr_in {
let in_addr = ipv4_as_in_addr(sock_v4.ip());
c_types::sockaddr_in {
sin_len: mem::size_of::<c_types::sockaddr_in>() as u8,
sin_family: c_types::AF_INET as c_types::sa_family_t,
sin_port: sock_v4.port().to_be(),
sin_addr: in_addr,
sin_zero: [0; 8],
}
}
#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "freebsd",
target_os = "dragonfly", target_os = "openbsd", target_os = "netbsd",
target_os = "bitrig")))]
pub fn socket_addrv4_as_sockaddr_in(sock_v4: &SocketAddrV4) -> c_types::sockaddr_in {
let in_addr = ipv4_as_in_addr(sock_v4.ip());
c_types::sockaddr_in {
sin_family: c_types::AF_INET as c_types::sa_family_t,
sin_port: sock_v4.port().to_be(),
sin_addr: in_addr,
sin_zero: [0; 8],
}
}
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "freebsd",
target_os = "dragonfly", target_os = "openbsd", target_os = "netbsd",
target_os = "bitrig"))]
pub fn socket_addrv6_as_sockaddr_in6(sock_v6: &SocketAddrV6) -> c_types::sockaddr_in6 {
let in6_addr = ipv6_as_in6_addr(sock_v6.ip());
c_types::sockaddr_in6 {
sin6_len: mem::size_of::<c_types::sockaddr_in6>() as u8,
sin6_family: c_types::AF_INET6 as c_types::sa_family_t,
sin6_port: sock_v6.port().to_be(),
sin6_addr: in6_addr,
sin6_flowinfo: sock_v6.flowinfo(),
sin6_scope_id: sock_v6.scope_id(),
}
}
#[cfg(all(unix,
not(any(target_os = "macos", target_os = "ios", target_os = "freebsd",
target_os = "dragonfly", target_os = "openbsd", target_os = "netbsd",
target_os = "bitrig"))))]
pub fn socket_addrv6_as_sockaddr_in6(sock_v6: &SocketAddrV6) -> c_types::sockaddr_in6 {
let in6_addr = ipv6_as_in6_addr(sock_v6.ip());
c_types::sockaddr_in6 {
sin6_family: c_types::AF_INET6 as c_types::sa_family_t,
sin6_port: sock_v6.port().to_be(),
sin6_addr: in6_addr,
sin6_flowinfo: sock_v6.flowinfo(),
sin6_scope_id: sock_v6.scope_id(),
}
}
#[cfg(windows)]
pub fn socket_addrv6_as_sockaddr_in6(sock_v6: &SocketAddrV6) -> c_types::sockaddr_in6 {
let mut sockaddr_in6: c_types::sockaddr_in6 = unsafe { mem::zeroed() };
sockaddr_in6.sin6_family = c_types::AF_INET6 as c_types::sa_family_t;
sockaddr_in6.sin6_port = sock_v6.port().to_be();
sockaddr_in6.sin6_addr = ipv6_as_in6_addr(sock_v6.ip());
sockaddr_in6.sin6_flowinfo = sock_v6.flowinfo();
{
let scope_id = unsafe { sockaddr_in6.u.sin6_scope_id_mut() };
*scope_id = sock_v6.scope_id();
}
sockaddr_in6
}
pub fn version() -> (&'static str, u32) {
let mut int_version: c_int = 0;
let str_version = unsafe {
let ptr = c_ares_sys::ares_version(&mut int_version);
let buf = CStr::from_ptr(ptr).to_bytes();
str::from_utf8_unchecked(buf)
};
(str_version, int_version as u32)
}