netlink_packet_route/neighbour_discovery_user_option/
header.rs
1use netlink_packet_utils::Parseable;
4
5use crate::AddressFamily;
6
7use super::buffer::NeighbourDiscoveryUserOptionMessageBuffer;
8
9#[derive(Debug, PartialEq, Eq, Clone, Copy)]
10#[non_exhaustive]
11pub enum NeighbourDiscoveryIcmpV6Type {
12 RouterSolicitation,
13 RouterAdvertisement,
14 NeighbourSolicitation,
15 NeighbourAdvertisement,
16 Redirect,
17 Other { type_: u8, code: u8 },
18}
19
20#[derive(Debug, PartialEq, Eq, Clone, Copy)]
21#[non_exhaustive]
22pub enum NeighbourDiscoveryIcmpV4Type {
23 Other { type_: u8, code: u8 },
24}
25
26impl NeighbourDiscoveryIcmpV4Type {
27 pub fn into_type_and_code(self) -> (u8, u8) {
28 match self {
29 NeighbourDiscoveryIcmpV4Type::Other { type_, code } => (type_, code),
30 }
31 }
32}
33
34#[derive(Debug, PartialEq, Eq, Clone, Copy)]
35#[non_exhaustive]
36pub enum NeighbourDiscoveryIcmpType {
37 Inet(NeighbourDiscoveryIcmpV4Type),
38 Inet6(NeighbourDiscoveryIcmpV6Type),
39 Other { family: AddressFamily, type_: u8, code: u8 },
40}
41
42impl NeighbourDiscoveryIcmpType {
43 pub fn family(&self) -> AddressFamily {
44 match self {
45 NeighbourDiscoveryIcmpType::Inet(_) => AddressFamily::Inet,
46 NeighbourDiscoveryIcmpType::Inet6(_) => AddressFamily::Inet6,
47 NeighbourDiscoveryIcmpType::Other { family, type_: _, code: _ } => *family,
48 }
49 }
50
51 pub fn into_type_and_code(self) -> (u8, u8) {
52 match self {
53 NeighbourDiscoveryIcmpType::Inet(type_) => type_.into_type_and_code(),
54 NeighbourDiscoveryIcmpType::Inet6(type_) => type_.into_type_and_code(),
55 NeighbourDiscoveryIcmpType::Other { family: _, type_, code } => (type_, code),
56 }
57 }
58}
59
60impl NeighbourDiscoveryIcmpV6Type {
61 pub fn new(type_: u8, code: u8) -> Self {
64 match (type_, code) {
65 (133, 0) => NeighbourDiscoveryIcmpV6Type::RouterSolicitation,
66 (134, 0) => NeighbourDiscoveryIcmpV6Type::RouterAdvertisement,
67 (135, 0) => NeighbourDiscoveryIcmpV6Type::NeighbourSolicitation,
68 (136, 0) => NeighbourDiscoveryIcmpV6Type::NeighbourAdvertisement,
69 (137, 0) => NeighbourDiscoveryIcmpV6Type::Redirect,
70 _ => NeighbourDiscoveryIcmpV6Type::Other { type_, code },
71 }
72 }
73
74 pub fn into_type_and_code(self) -> (u8, u8) {
76 match self {
77 NeighbourDiscoveryIcmpV6Type::RouterSolicitation => (133, 0),
78 NeighbourDiscoveryIcmpV6Type::RouterAdvertisement => (134, 0),
79 NeighbourDiscoveryIcmpV6Type::NeighbourSolicitation => (135, 0),
80 NeighbourDiscoveryIcmpV6Type::NeighbourAdvertisement => (136, 0),
81 NeighbourDiscoveryIcmpV6Type::Redirect => (137, 0),
82 NeighbourDiscoveryIcmpV6Type::Other { type_, code } => (type_, code),
83 }
84 }
85}
86
87impl<T: AsRef<[u8]>> Parseable<NeighbourDiscoveryUserOptionMessageBuffer<T>>
88 for NeighbourDiscoveryUserOptionHeader
89{
90 type Error = netlink_packet_utils::DecodeError;
91
92 fn parse(
93 buf: &NeighbourDiscoveryUserOptionMessageBuffer<T>,
94 ) -> Result<Self, netlink_packet_utils::DecodeError> {
95 let icmp_type = match AddressFamily::from(buf.address_family()) {
96 AddressFamily::Inet => {
97 NeighbourDiscoveryIcmpType::Inet(NeighbourDiscoveryIcmpV4Type::Other {
98 type_: buf.icmp_type(),
99 code: buf.icmp_code(),
100 })
101 }
102 AddressFamily::Inet6 => NeighbourDiscoveryIcmpType::Inet6(
103 NeighbourDiscoveryIcmpV6Type::new(buf.icmp_type(), buf.icmp_code()),
104 ),
105 family => NeighbourDiscoveryIcmpType::Other {
106 family,
107 type_: buf.icmp_type(),
108 code: buf.icmp_code(),
109 },
110 };
111 Ok(Self { interface_index: buf.interface_index(), icmp_type })
112 }
113}
114
115#[derive(Debug, PartialEq, Eq, Clone)]
116#[non_exhaustive]
117pub struct NeighbourDiscoveryUserOptionHeader {
118 pub interface_index: u32,
120 pub icmp_type: NeighbourDiscoveryIcmpType,
123}
124
125impl NeighbourDiscoveryUserOptionHeader {
126 pub fn new(interface_index: u32, icmp_type: NeighbourDiscoveryIcmpType) -> Self {
127 Self { interface_index, icmp_type }
128 }
129}