1use crate::packet::{GenericMutablePacket, Packet};
4use bytes::{Buf, Bytes};
5use nex_core::bitfield::{u1, u3, u5, u16be, u32be};
6
7#[derive(Clone, Debug, PartialEq, Eq)]
11pub struct GrePacket {
12 pub checksum_present: u1,
13 pub routing_present: u1,
14 pub key_present: u1,
15 pub sequence_present: u1,
16 pub strict_source_route: u1,
17 pub recursion_control: u3,
18 pub zero_flags: u5,
19 pub version: u3,
20 pub protocol_type: u16be, pub checksum: Vec<u16be>,
22 pub offset: Vec<u16be>,
23 pub key: Vec<u32be>,
24 pub sequence: Vec<u32be>,
25 pub routing: Vec<u8>,
26 pub payload: Bytes,
27}
28
29impl Packet for GrePacket {
30 type Header = ();
31
32 fn from_buf(mut bytes: &[u8]) -> Option<Self> {
33 if bytes.remaining() < 4 {
34 return None;
35 }
36
37 let flags = bytes.get_u16();
38 let protocol_type = bytes.get_u16();
39
40 let checksum_present = ((flags >> 15) & 0x1) as u1;
41 let routing_present = ((flags >> 14) & 0x1) as u1;
42 let key_present = ((flags >> 13) & 0x1) as u1;
43 let sequence_present = ((flags >> 12) & 0x1) as u1;
44 let strict_source_route = ((flags >> 11) & 0x1) as u1;
45 let recursion_control = ((flags >> 8) & 0x7) as u3;
46 let zero_flags = ((flags >> 3) & 0x1f) as u5;
47 let version = (flags & 0x7) as u3;
48
49 let mut checksum = Vec::new();
51 let mut offset = Vec::new();
52 let mut key = Vec::new();
53 let mut sequence = Vec::new();
54 let routing = Vec::new();
55
56 if checksum_present != 0 || routing_present != 0 {
57 if bytes.remaining() < 4 {
58 return None;
59 }
60 checksum.push(bytes.get_u16());
61 offset.push(bytes.get_u16());
62 }
63
64 if key_present != 0 {
65 if bytes.remaining() < 4 {
66 return None;
67 }
68 key.push(bytes.get_u32());
69 }
70
71 if sequence_present != 0 {
72 if bytes.remaining() < 4 {
73 return None;
74 }
75 sequence.push(bytes.get_u32());
76 }
77
78 if routing_present != 0 {
79 panic!("Source routed GRE packets not supported");
81 }
82
83 let payload = Bytes::copy_from_slice(bytes);
84
85 Some(Self {
86 checksum_present,
87 routing_present,
88 key_present,
89 sequence_present,
90 strict_source_route,
91 recursion_control,
92 zero_flags,
93 version,
94 protocol_type: protocol_type.into(),
95 checksum,
96 offset,
97 key,
98 sequence,
99 routing,
100 payload,
101 })
102 }
103
104 fn from_bytes(bytes: Bytes) -> Option<Self> {
105 Self::from_buf(&bytes)
106 }
107
108 fn to_bytes(&self) -> Bytes {
109 use bytes::{BufMut, BytesMut};
110
111 let mut buf = BytesMut::with_capacity(self.header_len());
112
113 let mut flags: u16 = 0;
115 flags |= (self.checksum_present as u16) << 15;
116 flags |= (self.routing_present as u16) << 14;
117 flags |= (self.key_present as u16) << 13;
118 flags |= (self.sequence_present as u16) << 12;
119 flags |= (self.strict_source_route as u16) << 11;
120 flags |= (self.recursion_control as u16) << 8;
121 flags |= (self.zero_flags as u16) << 3;
122 flags |= self.version as u16;
123
124 buf.put_u16(flags);
125 buf.put_u16(self.protocol_type.into());
126
127 if self.checksum_present != 0 || self.routing_present != 0 {
128 for c in &self.checksum {
129 buf.put_u16(*c);
130 }
131 for o in &self.offset {
132 buf.put_u16(*o);
133 }
134 }
135
136 if self.key_present != 0 {
137 for k in &self.key {
138 buf.put_u32(*k);
139 }
140 }
141
142 if self.sequence_present != 0 {
143 for s in &self.sequence {
144 buf.put_u32(*s);
145 }
146 }
147
148 if self.routing_present != 0 {
150 panic!("to_bytes does not support source routed GRE packets");
151 }
152
153 buf.put_slice(&self.payload);
154
155 buf.freeze()
156 }
157 fn header(&self) -> Bytes {
158 use bytes::{BufMut, BytesMut};
159
160 let mut buf = BytesMut::with_capacity(self.header_len());
161
162 let mut flags: u16 = 0;
164 flags |= (self.checksum_present as u16) << 15;
165 flags |= (self.routing_present as u16) << 14;
166 flags |= (self.key_present as u16) << 13;
167 flags |= (self.sequence_present as u16) << 12;
168 flags |= (self.strict_source_route as u16) << 11;
169 flags |= (self.recursion_control as u16) << 8;
170 flags |= (self.zero_flags as u16) << 3;
171 flags |= self.version as u16;
172
173 buf.put_u16(flags);
174 buf.put_u16(self.protocol_type.into());
175
176 if self.checksum_present != 0 || self.routing_present != 0 {
177 for c in &self.checksum {
178 buf.put_u16(*c);
179 }
180 for o in &self.offset {
181 buf.put_u16(*o);
182 }
183 }
184
185 if self.key_present != 0 {
186 for k in &self.key {
187 buf.put_u32(*k);
188 }
189 }
190
191 if self.sequence_present != 0 {
192 for s in &self.sequence {
193 buf.put_u32(*s);
194 }
195 }
196
197 if self.routing_present != 0 {
199 panic!("header does not support source routed GRE packets");
200 }
201
202 buf.freeze()
203 }
204
205 fn payload(&self) -> Bytes {
206 self.payload.clone()
207 }
208
209 fn header_len(&self) -> usize {
210 4 + self.checksum_length()
212 + self.offset_length()
213 + self.key_length()
214 + self.sequence_length()
215 }
216
217 fn payload_len(&self) -> usize {
218 self.payload.len()
219 }
220
221 fn total_len(&self) -> usize {
222 self.header_len() + self.payload_len()
223 }
224
225 fn into_parts(self) -> (Self::Header, Bytes) {
226 ((), self.to_bytes())
227 }
228}
229
230impl GrePacket {
231 pub fn checksum_length(&self) -> usize {
232 (self.checksum_present | self.routing_present) as usize * 2
233 }
234
235 pub fn offset_length(&self) -> usize {
236 (self.checksum_present | self.routing_present) as usize * 2
237 }
238
239 pub fn key_length(&self) -> usize {
240 self.key_present as usize * 4
241 }
242
243 pub fn sequence_length(&self) -> usize {
244 self.sequence_present as usize * 4
245 }
246
247 pub fn routing_length(&self) -> usize {
248 if 0 == self.routing_present {
249 0
250 } else {
251 panic!("Source routed GRE packets not supported")
252 }
253 }
254}
255
256pub type MutableGrePacket<'a> = GenericMutablePacket<'a, GrePacket>;
258
259#[cfg(test)]
260mod tests {
261 use super::*;
262 use crate::packet::MutablePacket;
263
264 #[test]
265 fn gre_packet_test() {
266 let packet = Bytes::from_static(&[
267 0x00, 0x00, 0x08, 0x00,
271 ]);
272
273 let gre_packet = GrePacket::from_buf(&mut packet.clone()).unwrap();
274
275 assert_eq!(&gre_packet.to_bytes(), &packet);
276 }
277
278 #[test]
279 fn gre_checksum_test() {
280 let packet = Bytes::from_static(&[
281 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
287 ]);
288
289 let gre_packet = GrePacket::from_buf(&mut packet.clone()).unwrap();
290
291 assert_eq!(&gre_packet.to_bytes(), &packet);
292 }
293
294 #[test]
295 fn test_mutable_gre_packet_alias() {
296 let mut raw = [
297 0x00, 0x00, 0x08, 0x00, 0xaa, 0xbb,
300 ];
301
302 let mut packet = <MutableGrePacket as MutablePacket>::new(&mut raw).expect("mutable gre");
303 packet.header_mut()[2] = 0x86;
304 packet.header_mut()[3] = 0xdd; packet.payload_mut()[0] = 0xff;
306
307 let frozen = packet.freeze().expect("freeze");
308 assert_eq!(frozen.protocol_type, 0x86dd);
309 assert_eq!(frozen.payload[0], 0xff);
310 }
311}