1use pnet_macros_support::types::{u1, u16be, u2, u24be, u5, u6};
6
7#[derive(PartialEq)]
8pub struct GENEVEPacket<'p> {
10 packet: pnet_macros_support::packet::PacketData<'p>,
11}
12
13impl<'a> GENEVEPacket<'a> {
14 pub fn new(packet: &[u8]) -> Option<GENEVEPacket> {
17 if packet.len() >= GENEVEPacket::minimum_packet_size() {
18 use ::pnet_macros_support::packet::PacketData;
19 Some(GENEVEPacket {
20 packet: PacketData::Borrowed(packet),
21 })
22 } else {
23 None
24 }
25 }
26
27 pub fn minimum_packet_size() -> usize {
30 8
31 }
32
33 pub fn get_stack_size(&self) -> u2 {
35 (self.packet[0] >> 6) as u2
36 }
37
38 pub fn get_option_length(&self) -> u6 {
40 (self.packet[0] & 0b0011_1111) as u6
41 }
42
43 pub fn get_control(&self) -> u1 {
47 (self.packet[1] >> 7) as u1
48 }
49
50 pub fn get_critical(&self) -> u1 {
52 ((self.packet[1] >> 6) & 0b01) as u1
53 }
54
55 pub fn get_reserved(&self) -> u6 {
57 (self.packet[1] & 0b0011_1111) as u1
58 }
59
60 pub fn get_protocol_type(&self) -> u16be {
62 ((self.packet[2] as u16be) << 8) | (self.packet[3] as u16be)
63 }
64
65 pub fn get_virtual_network_identifier(&self) -> u24be {
67 ((self.packet[4] as u24be) << 16)
68 | ((self.packet[5] as u24be) << 8)
69 | (self.packet[6] as u24be)
70 }
71
72 pub fn get_reserved2(&self) -> u8 {
74 self.packet[7]
75 }
76
77 pub fn get_options_raw(&self) -> &[u8] {
79 use std::cmp::min;
80 let _self = self;
81 let current_offset = 8;
82 let options_len = (self.get_option_length() as usize) * 4;
83 let end = min(current_offset + options_len, _self.packet.len());
84 &_self.packet[current_offset..end]
85 }
86
87 pub fn get_options(&self) -> Vec<GENEVEOption> {
89 use pnet_packet::FromPacket;
90 let buf = self.get_options_raw();
91 GENEVEOptionIterable { buf }
92 .map(|packet| packet.from_packet())
93 .collect::<Vec<_>>()
94 }
95
96 pub fn get_options_iter(&self) -> GENEVEOptionIterable {
98 let buf = self.get_options_raw();
99 GENEVEOptionIterable { buf }
100 }
101}
102
103impl<'a> pnet_macros_support::packet::Packet for GENEVEPacket<'a> {
104 fn packet(&self) -> &[u8] {
105 &self.packet[..]
106 }
107
108 fn payload(&self) -> &[u8] {
109 let _self = self;
110 let options_len = (self.get_option_length() as usize) * 4;
111 let start = std::cmp::min(8 + options_len, self.packet.len());
112 &_self.packet[start..]
113 }
114}
115
116#[derive(Clone, Debug)]
118pub struct GENEVEOption {
119 option_class: u16be,
120 option_type: u8,
121 length: u5,
122 data: Vec<u8>,
123}
124
125impl GENEVEOption {
126 pub fn option_class(&self) -> u16be {
127 self.option_class
128 }
129 pub fn option_type(&self) -> u8 {
130 self.option_type
131 }
132 pub fn option_length(&self) -> u5 {
133 self.length
134 }
135 pub fn option_data(&self) -> &[u8] {
136 &self.data
137 }
138}
139
140#[derive(PartialEq)]
141pub struct GENEVEOptionPacket<'p> {
143 packet: pnet_macros_support::packet::PacketData<'p>,
144}
145
146impl<'a> GENEVEOptionPacket<'a> {
147 pub fn new(packet: &'_ [u8]) -> Option<GENEVEOptionPacket<'_>> {
150 if packet.len() >= GENEVEOptionPacket::minimum_packet_size() {
151 use ::pnet_macros_support::packet::PacketData;
152 Some(GENEVEOptionPacket {
153 packet: PacketData::Borrowed(packet),
154 })
155 } else {
156 None
157 }
158 }
159
160 pub const fn minimum_packet_size() -> usize {
163 4
164 }
165
166 pub fn get_option_class(&self) -> u16be {
168 ((self.packet[0] as u16be) << 8) | (self.packet[1] as u16be)
169 }
170
171 pub fn get_option_type(&self) -> u8 {
173 self.packet[2]
174 }
175
176 pub fn get_option_length(&self) -> u5 {
178 (self.packet[3] & 0b0001_1111) as u5
179 }
180}
181
182impl<'a> pnet_macros_support::packet::Packet for GENEVEOptionPacket<'a> {
183 fn packet(&self) -> &[u8] {
184 &self.packet[..]
185 }
186
187 fn payload(&self) -> &[u8] {
188 let _self = self;
189 let options_len = (self.get_option_length() as usize) * 4;
190 let start = std::cmp::min(4 + options_len, self.packet.len());
191 &_self.packet[start..]
192 }
193}
194
195impl<'a> pnet_macros_support::packet::PacketSize for GENEVEOptionPacket<'a> {
196 fn packet_size(&self) -> usize {
197 4 + 4 * (self.get_option_length() as usize)
198 }
199}
200
201impl<'p> pnet_macros_support::packet::FromPacket for GENEVEOptionPacket<'p> {
202 type T = GENEVEOption;
203
204 fn from_packet(&self) -> GENEVEOption {
205 use pnet_macros_support::packet::Packet;
206 let _self = self;
207 GENEVEOption {
208 option_class: _self.get_option_class(),
209 option_type: _self.get_option_type(),
210 length: _self.get_option_length(),
211 data: {
212 let payload = self.payload();
213 let mut vec = Vec::with_capacity(payload.len());
214 vec.extend_from_slice(payload);
215 vec
216 },
217 }
218 }
219}
220
221pub struct GENEVEOptionIterable<'a> {
222 buf: &'a [u8],
223}
224
225impl<'a> Iterator for GENEVEOptionIterable<'a> {
226 type Item = GENEVEOptionPacket<'a>;
227 fn next(&mut self) -> Option<GENEVEOptionPacket<'a>> {
228 use std::cmp::min;
229
230 use pnet_macros_support::packet::PacketSize;
231 if !self.buf.is_empty() {
232 if let Some(ret) = GENEVEOptionPacket::new(self.buf) {
233 let start = min(ret.packet_size(), self.buf.len());
234 self.buf = &self.buf[start..];
235 return Some(ret);
236 }
237 }
238 None
239 }
240 fn size_hint(&self) -> (usize, Option<usize>) {
241 (0, None)
242 }
243}