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
use errno::Errno;
use crate::{Error, Netlink, Result};
use crate::ffi::*;
use super::{Bytes, Cursor, Message};
pub fn next<'a, T: Bytes>(c: &mut Cursor<'a>) -> Option<Result<Netlink<Message<'a, T>>>> {
let (head, tail) = c.next::<nlmsghdr>()?;
Some(match head.nlmsg_type {
NLMSG_NOOP => Ok(Netlink::Noop),
NLMSG_OVERRUN => Ok(Netlink::Overrun),
NLMSG_ERROR => error(tail)?,
_ => Ok(message(head, tail)?),
})
}
fn message<T: Bytes>(head: nlmsghdr, mut tail: Cursor<'_>) -> Option<Netlink<Message<'_, T>>> {
let done = head.nlmsg_type == NLMSG_DONE;
match tail.next().map(|(data, tail)| Message::with(head, data, tail)) {
Some(msg) => Some(Netlink::Msg(msg)),
None if done => Some(Netlink::Done),
None => None,
}
}
fn error<T: Bytes>(mut tail: Cursor<'_>) -> Option<Result<Netlink<Message<'_, T>>>> {
tail.next::<nlmsgerr>().and_then(|(err, _)| {
Some(match err.error.checked_neg()? {
0 => Ok(Netlink::Ack),
n => Err(Error::Netlink(Errno(n))),
})
})
}