netlink_packet_route/rtnl/link/nlas/inet6/
mod.rs1use anyhow::Context;
4use byteorder::{ByteOrder, NativeEndian};
5
6use crate::{
7 constants::*,
8 nlas::{DefaultNla, Nla, NlaBuffer},
9 parsers::{parse_ipv6, parse_u32, parse_u8},
10 traits::Parseable,
11 DecodeError,
12};
13
14mod cache;
15pub use self::cache::*;
16mod dev_conf;
17pub use self::dev_conf::*;
18mod icmp6_stats;
19pub use self::icmp6_stats::*;
20mod stats;
21pub use self::stats::*;
22
23#[derive(Clone, Eq, PartialEq, Debug)]
24pub enum Inet6 {
25 Flags(u32),
26 CacheInfo(Vec<u8>),
27 DevConf(Vec<u8>),
28 Unspec(Vec<u8>),
29 Stats(Vec<u8>),
30 IcmpStats(Vec<u8>),
31 Token([u8; 16]),
32 AddrGenMode(u8),
33 Other(DefaultNla),
34}
35
36impl Nla for Inet6 {
37 fn value_len(&self) -> usize {
38 use self::Inet6::*;
39 match *self {
40 Unspec(ref bytes) => bytes.len(),
41 CacheInfo(ref cache_info) => cache_info.len(),
42 DevConf(ref dev_conf) => dev_conf.len(),
43 Stats(ref stats) => stats.len(),
44 IcmpStats(ref icmp_stats) => icmp_stats.len(),
45 Flags(_) => 4,
46 Token(_) => 16,
47 AddrGenMode(_) => 1,
48 Other(ref nla) => nla.value_len(),
49 }
50 }
51
52 fn emit_value(&self, buffer: &mut [u8]) {
53 use self::Inet6::*;
54 match *self {
55 Unspec(ref bytes) => buffer.copy_from_slice(bytes.as_slice()),
56 Flags(ref value) => NativeEndian::write_u32(buffer, *value),
57 CacheInfo(ref cache_info) => buffer.copy_from_slice(cache_info.as_slice()),
58 DevConf(ref bytes) => buffer.copy_from_slice(bytes.as_slice()),
59 Stats(ref inet6_stats) => buffer.copy_from_slice(inet6_stats.as_slice()),
60 IcmpStats(ref icmp6_stats) => buffer.copy_from_slice(icmp6_stats.as_slice()),
61 Token(ref ipv6) => buffer.copy_from_slice(&ipv6[..]),
62 AddrGenMode(value) => buffer[0] = value,
63 Other(ref nla) => nla.emit_value(buffer),
64 }
65 }
66
67 fn kind(&self) -> u16 {
68 use self::Inet6::*;
69 match *self {
70 Unspec(_) => IFLA_INET6_UNSPEC,
71 Flags(_) => IFLA_INET6_FLAGS,
72 CacheInfo(_) => IFLA_INET6_CACHEINFO,
73 DevConf(_) => IFLA_INET6_CONF,
74 Stats(_) => IFLA_INET6_STATS,
75 IcmpStats(_) => IFLA_INET6_ICMP6STATS,
76 Token(_) => IFLA_INET6_TOKEN,
77 AddrGenMode(_) => IFLA_INET6_ADDR_GEN_MODE,
78 Other(ref nla) => nla.kind(),
79 }
80 }
81}
82
83impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for Inet6 {
84 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
85 use self::Inet6::*;
86 let payload = buf.value();
87 Ok(match buf.kind() {
88 IFLA_INET6_UNSPEC => Unspec(payload.to_vec()),
89 IFLA_INET6_FLAGS => {
90 Flags(parse_u32(payload).context("invalid IFLA_INET6_FLAGS value")?)
91 }
92 IFLA_INET6_CACHEINFO => CacheInfo(payload.to_vec()),
93 IFLA_INET6_CONF => DevConf(payload.to_vec()),
94 IFLA_INET6_STATS => Stats(payload.to_vec()),
95 IFLA_INET6_ICMP6STATS => IcmpStats(payload.to_vec()),
96 IFLA_INET6_TOKEN => {
97 Token(parse_ipv6(payload).context("invalid IFLA_INET6_TOKEN value")?)
98 }
99 IFLA_INET6_ADDR_GEN_MODE => {
100 AddrGenMode(parse_u8(payload).context("invalid IFLA_INET6_ADDR_GEN_MODE value")?)
101 }
102 kind => Other(DefaultNla::parse(buf).context(format!("unknown NLA type {}", kind))?),
103 })
104 }
105}