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
use std::convert::TryFrom;
use std::net::IpAddr;
use crate::Message;
use crate::api::IFA;
use crate::err::Invalid;
use crate::ffi::{AF_INET, AF_INET6, ifaddrmsg};
#[derive(Debug)]
pub struct Addr {
pub index: u32,
pub label: String,
pub flags: u8,
pub prefix: u8,
pub scope: u8,
pub addr: IpAddr,
}
pub fn addr(msg: &Message<ifaddrmsg>) -> Result<Addr, Invalid> {
let mut addr = Addr {
index: msg.ifa_index,
label: String::new(),
flags: msg.ifa_flags,
prefix: msg.ifa_prefixlen,
scope: msg.ifa_scope,
addr: IpAddr::V4(0.into()),
};
let ip = |octets| ip(msg.ifa_family, octets);
for attr in msg.attrs() {
match attr? {
IFA::Label(label) => addr.label = label.to_string(),
IFA::Address(octets) => addr.addr = ip(octets)?,
_ => (),
}
}
Ok(addr)
}
pub fn ip(family: u8, octets: &[u8]) -> Result<IpAddr, Invalid> {
Ok(match family {
AF_INET => IpAddr::from(<[u8; 4]>::try_from(octets)?),
AF_INET6 => IpAddr::from(<[u8; 16]>::try_from(octets)?),
family => return Err(Invalid::Family(family)),
})
}