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

use std::convert::TryFrom;
use crate::err::Invalid;
use crate::ffi::addr::*;
use crate::ffi::route::*;
use crate::sys::Cursor;

#[derive(Debug, Eq, PartialEq)]
pub enum IFA<'a> {
    Address(&'a [u8]),
    Local(&'a [u8]),
    Label(&'a str),
    Broadcast(&'a [u8]),
    Anycast(&'a [u8]),
    Multicast(&'a [u8]),
    Flags(u32),
    Unsupported(rtattr, Cursor<'a>),
}

impl<'a> TryFrom<(rtattr, Cursor<'a>)> for IFA<'a> {
    type Error = Invalid;

    fn try_from((attr, tail): (rtattr, Cursor<'a>)) -> Result<IFA<'a>, Self::Error> {
        Ok(match attr.rta_type {
            IFA_ADDRESS   => IFA::Address(tail.bytes()),
            IFA_LOCAL     => IFA::Local(tail.bytes()),
            IFA_LABEL     => IFA::Label(tail.asciiz()?),
            IFA_BROADCAST => IFA::Broadcast(tail.bytes()),
            IFA_ANYCAST   => IFA::Anycast(tail.bytes()),
            IFA_MULTICAST => IFA::Multicast(tail.bytes()),
            IFA_FLAGS     => IFA::Flags(tail.copy()),
            _             => IFA::Unsupported(attr, tail),
        })
    }
}