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
// Copyright (C) 2018 - Will Glozer. All rights reserved.

use std::convert::TryFrom;
use std::net::IpAddr;
use crate::{MacAddress, Message};
use crate::api::NDA;
use crate::err::Invalid;
use crate::ffi::*;
use super::ip;

#[derive(Debug)]
pub struct Peer {
    pub addr:  IpAddr,
    pub mac:   MacAddress,
    pub index: u32,
    pub state: u16,
    pub flags: u8,
    pub kind:  u8,
}

pub fn peer(msg: &Message<ndmsg>) -> Result<Peer, Invalid> {
    let mut peer = Peer {
        addr:  IpAddr::V4(0.into()),
        mac:   MacAddress::default(),
        index: msg.ndm_ifindex,
        state: msg.ndm_state,
        flags: msg.ndm_flags,
        kind:  msg.ndm_type,
    };

    let ip = |octets| ip(msg.ndm_family, octets);

    for attr in msg.attrs() {
        match attr? {
            NDA::LLAddr(octets) => peer.mac  = MacAddress::try_from(octets)?,
            NDA::Dst(octets)    => peer.addr = ip(octets)?,
            _                   => (),
        }
    }

    Ok(peer)
}