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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
use super::header::*;
use byteorder::{ByteOrder, NativeEndian};
use {Field, Index, NlaBuffer, NlasIterator, Rest, Result};
const ADDRESS_FAMILY: Index = 0;
const DEST_LENGTH: Index = 1;
const SOURCE_LENGTH: Index = 2;
const TOS: Index = 3;
const TABLE_ID: Index = 4;
const ROUTING_PROTOCOL: Index = 5;
const SCOPE: Index = 6;
const TYPE: Index = 7;
const FLAGS: Field = 8..12;
const ATTRIBUTES: Rest = 12..;
pub const HEADER_LEN: usize = ATTRIBUTES.start;
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct RouteBuffer<T> {
buffer: T,
}
impl<T: AsRef<[u8]>> RouteBuffer<T> {
pub fn new(buffer: T) -> RouteBuffer<T> {
RouteBuffer { buffer }
}
pub fn into_inner(self) -> T {
self.buffer
}
pub fn address_family(&self) -> u8 {
let data = self.buffer.as_ref();
data[ADDRESS_FAMILY]
}
pub fn destination_length(&self) -> u8 {
let data = self.buffer.as_ref();
data[DEST_LENGTH]
}
pub fn source_length(&self) -> u8 {
let data = self.buffer.as_ref();
data[SOURCE_LENGTH]
}
pub fn tos(&self) -> u8 {
let data = self.buffer.as_ref();
data[TOS]
}
pub fn table(&self) -> RouteTable {
let data = self.buffer.as_ref();
data[TABLE_ID].into()
}
pub fn protocol(&self) -> RouteProtocol {
let data = self.buffer.as_ref();
data[ROUTING_PROTOCOL].into()
}
pub fn scope(&self) -> RouteScope {
let data = self.buffer.as_ref();
data[SCOPE].into()
}
pub fn kind(&self) -> RouteKind {
let data = self.buffer.as_ref();
data[TYPE].into()
}
pub fn flags(&self) -> RouteFlags {
let data = self.buffer.as_ref();
NativeEndian::read_u32(&data[FLAGS]).into()
}
}
impl<'a, T: AsRef<[u8]> + ?Sized> RouteBuffer<&'a T> {
pub fn payload(&self) -> &'a [u8] {
let data = self.buffer.as_ref();
&data[ATTRIBUTES]
}
pub fn nlas(&self) -> impl Iterator<Item = Result<NlaBuffer<&'a [u8]>>> {
NlasIterator::new(self.payload())
}
}
impl<'a, T: AsRef<[u8]> + AsMut<[u8]> + ?Sized> RouteBuffer<&'a mut T> {
pub fn payload_mut(&mut self) -> &mut [u8] {
let data = self.buffer.as_mut();
&mut data[ATTRIBUTES]
}
}
impl<T: AsRef<[u8]> + AsMut<[u8]>> RouteBuffer<T> {
pub fn set_address_family(&mut self, value: u8) {
let data = self.buffer.as_mut();
data[ADDRESS_FAMILY] = value
}
pub fn set_destination_length(&mut self, value: u8) {
let data = self.buffer.as_mut();
data[DEST_LENGTH] = value
}
pub fn set_source_length(&mut self, value: u8) {
let data = self.buffer.as_mut();
data[SOURCE_LENGTH] = value
}
pub fn set_tos(&mut self, value: u8) {
let data = self.buffer.as_mut();
data[TOS] = value
}
pub fn set_table(&mut self, value: RouteTable) {
let data = self.buffer.as_mut();
data[TABLE_ID] = value.into()
}
pub fn set_protocol(&mut self, value: RouteProtocol) {
let data = self.buffer.as_mut();
data[ROUTING_PROTOCOL] = value.into()
}
pub fn set_scope(&mut self, value: RouteScope) {
let data = self.buffer.as_mut();
data[SCOPE] = value.into()
}
pub fn set_kind(&mut self, value: RouteKind) {
let data = self.buffer.as_mut();
data[TYPE] = value.into()
}
pub fn set_flags(&mut self, value: RouteFlags) {
let data = self.buffer.as_mut();
NativeEndian::write_u32(&mut data[FLAGS], value.into())
}
}