nex_packet/
gre.rs

1//! GRE Packet abstraction.
2
3use crate::packet::{GenericMutablePacket, Packet};
4use bytes::{Buf, Bytes};
5use nex_core::bitfield::{u1, u3, u5, u16be, u32be};
6
7/// GRE (Generic Routing Encapsulation) Packet.
8///
9/// See RFCs 1701, 2784, 2890, 7676, 2637
10#[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, // 0x800 for IPv4
21    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        // Retrieve optional fields in order
50        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            // Not implemented for this crate
80            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        // Build the flags field
114        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        // Panic if routing_present is set (not supported by this implementation)
149        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        // Build the flags field
163        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        // Panic if routing_present is set (not supported by this implementation)
198        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 // base header: 2 bytes flags + 2 bytes protocol_type
211            + 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
256/// Represents a mutable GRE packet.
257pub 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, /* no flags */
268            0x00, /* no flags, version 0 */
269            0x08, /* protocol 0x0800 */
270            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, /* checksum on */
282            0x00, /* no flags, version 0 */
283            0x00, /* protocol 0x0000 */
284            0x00, 0x00, /* 16 bits of checksum */
285            0x00, 0x00, /* 16 bits of offset */
286            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, // flags
298            0x08, 0x00, // protocol type
299            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; // IPv6 protocol
305        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}