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
use std::convert::TryFrom;
use std::iter;
use crate::err::Invalid;
use crate::ffi::*;
use crate::sys::{Cursor, Bytes, Message};
use super::{IFA, IFLA, NDA, RTA};
#[derive(Debug)]
pub enum Any<'a> {
IFAddr(Message<'a, ifaddrmsg>),
IFInfo(Message<'a, ifinfomsg>),
Peer(Message<'a, ndmsg>),
Route(Message<'a, rtmsg>),
Unsupported(u16, Cursor<'a>),
}
impl<'a> Message<'a, ifaddrmsg> {
pub fn attrs(&self) -> impl Iterator<Item = Result<IFA<'a>, Invalid>> {
let mut tail = self.tail();
iter::from_fn(move || tail.next().map(IFA::try_from))
}
}
impl<'a> Message<'a, ifinfomsg> {
pub fn attrs(&self) -> impl Iterator<Item = Result<IFLA<'a>, Invalid>> {
let mut tail = self.tail();
iter::from_fn(move || tail.next().map(IFLA::try_from))
}
}
impl<'a> Message<'a, ndmsg> {
pub fn attrs(&self) -> impl Iterator<Item = Result<NDA<'a>, Invalid>> {
let mut tail = self.tail();
iter::from_fn(move || tail.next().map(NDA::try_from))
}
}
impl<'a> Message<'a, rtmsg> {
pub fn attrs(&self) -> impl Iterator<Item = Result<RTA<'a>, Invalid>> {
let mut tail = self.tail();
iter::from_fn(move || tail.next().map(RTA::try_from))
}
}
impl<'a> Message<'a, inet_diag_msg> {
pub fn info<T: Bytes>(&self) -> Option<T> {
let mut tail = self.tail();
while let Some((attr, mut tail)) = tail.next::<rtattr>() {
if attr.rta_type == INET_DIAG_INFO {
return Some(tail.next()?.0);
}
}
None
}
}
impl<'a> Message<'a, ()> {
pub fn any(&self) -> Any<'a> {
match self.nlmsg_type() {
RTM_NEWADDR | RTM_DELADDR => Any::IFAddr(self.msg()),
RTM_NEWLINK | RTM_DELLINK => Any::IFInfo(self.msg()),
RTM_NEWNEIGH | RTM_DELNEIGH => Any::Peer(self.msg()),
RTM_NEWROUTE | RTM_DELROUTE => Any::Route(self.msg()),
kind => Any::Unsupported(kind, self.tail()),
}
}
fn msg<T: Bytes + Default>(&self) -> Message<'a, T> {
let (head, _, mut tail) = self.parts();
let (data, tail) = tail.next().unwrap_or_default();
Message::with(head.clone(), data, tail)
}
}