-
Notifications
You must be signed in to change notification settings - Fork 0
/
address.rs
85 lines (74 loc) · 2.25 KB
/
address.rs
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
#[repr(C)]
#[derive(Clone, Copy, Debug)]
struct SocketAddressHci {
hci_family: libc::sa_family_t,
hci_dev: u16,
hci_channel: u16,
}
#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct SocketAddressGeneric(libc::sockaddr);
impl SocketAddressGeneric {
pub fn as_raw(&self) -> *const libc::sockaddr {
&**self
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
struct SocketAddressContainer<T: Copy> {
sa_family: libc::sa_family_t,
sa_data: T,
}
#[repr(C)]
pub union SocketAddress<T: Copy> {
generic: SocketAddressGeneric,
container: SocketAddressContainer<T>,
}
impl<T: Copy> SocketAddress<T> {
pub fn new(sa_family: rustix::net::AddressFamily, sa_data: T) -> Self {
// make sure we cannot read uninitialized data by accident by zeroing all
let mut socket_address: SocketAddress<T> = unsafe { std::mem::zeroed() };
socket_address.container = SocketAddressContainer {
sa_family: sa_family.as_raw(),
sa_data,
};
socket_address
}
pub fn len(&self) -> usize {
std::mem::size_of_val(unsafe { &self.container })
}
pub fn generic(&self) -> &SocketAddressGeneric {
unsafe { &self.generic }
}
}
impl core::fmt::Debug for SocketAddressGeneric {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SocketAddressGeneric")
.field("sa_family", &self.0.sa_family)
.field(
"sa_data",
&self
.0
.sa_data
.iter()
// because we are interested in raw bytes, u8 makes more sense than i8
.map(|v| *v as u8)
.collect::<Vec<_>>(),
)
.finish()
}
}
impl<T: core::fmt::Debug + Copy> core::fmt::Debug for SocketAddress<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SocketAddressUnion")
.field("container", unsafe { &self.container })
.field("generic", unsafe { &self.generic })
.finish()
}
}
impl std::ops::Deref for SocketAddressGeneric {
type Target = libc::sockaddr;
fn deref(&self) -> &Self::Target {
&self.0
}
}