1use std::convert::From;
2use std::fmt;
3use std::io;
4
5use netlink_rust::{HardwareAddress, Result};
6
7use crate::unpack::LittleUnpack;
8
9#[derive(Debug, PartialEq)]
10pub enum FrameType {
11 Management,
12 Control,
13 Data,
14 Reserved,
15}
16
17#[derive(Debug, PartialEq)]
18pub enum FrameSubtype {
19 Reserved,
20 AssociationRequest,
22 AssociationResponse,
23 ReassociationRequest,
24 ReassociationResponse,
25 ProbeRequest,
26 ProbeResponse,
27 TimingAdvertisment,
28 Beacon,
29 AnnouncementTrafficIndication,
30 Disassociation,
31 Authentication,
32 Deauthentication,
33 Action,
34 ActionNoAcknowledge,
35 ControlWrapper,
37 BlockAcknowledgeRequest,
38 BlockAcknowledge,
39 PowerSavePoll,
40 RequestToSend,
41 ClearToSend,
42 Acknowledge,
43 ContentionFreeEnd,
44 ContentionFreeEndAcknowledge,
45 Data,
47 DataContentionFreeAcknowledge,
48 DataContentionFreePoll,
49 DataContentionFreeAcknowledgePoll,
50 Null,
51 NullContentionFreeAcknowledge,
52 NullContentionFreePoll,
53 NullContentionFreeAcknowledgePoll,
54 QualityOfService,
55 QualityOfServiceContentionFreeAcknowledge,
56 QualityOfServiceContentionFreePoll,
57 QualityOfServiceContentionFreeAcknowledgePoll,
58 NullQualityOfService,
59 NullQualityOfServiceContentionFreeAcknowledge,
60 NullQualityOfServiceContentionFreePoll,
61 NullQualityOfServiceContentionFreeAcknowledgePoll,
62}
63
64#[derive(Debug, PartialEq)]
65pub struct FrameControl {
66 field: u16,
67}
68
69impl From<FrameControl> for u16 {
70 fn from(value: FrameControl) -> Self {
71 value.field
72 }
73}
74
75impl From<u16> for FrameControl {
76 fn from(value: u16) -> Self {
77 FrameControl { field: value }
78 }
79}
80
81impl FrameControl {
82 pub fn get_type(&self) -> FrameType {
83 match (self.field >> 2) & 0x0003 {
84 0 => FrameType::Management,
85 1 => FrameType::Control,
86 2 => FrameType::Data,
87 _ => FrameType::Reserved,
88 }
89 }
90 pub fn get_subtype(&self) -> FrameSubtype {
91 let subtype = (self.field >> 4) & 0x000f;
92 match self.get_type() {
93 FrameType::Management => match subtype {
94 0b0000 => FrameSubtype::AssociationRequest,
95 0b0001 => FrameSubtype::AssociationResponse,
96 0b0010 => FrameSubtype::ReassociationRequest,
97 0b0011 => FrameSubtype::ReassociationResponse,
98 0b0100 => FrameSubtype::ProbeRequest,
99 0b0101 => FrameSubtype::ProbeResponse,
100 0b0110 => FrameSubtype::TimingAdvertisment,
101 0b1000 => FrameSubtype::Beacon,
102 0b1001 => FrameSubtype::AnnouncementTrafficIndication,
103 0b1010 => FrameSubtype::Disassociation,
104 0b1011 => FrameSubtype::Authentication,
105 0b1100 => FrameSubtype::Deauthentication,
106 0b1101 => FrameSubtype::Action,
107 0b1110 => FrameSubtype::ActionNoAcknowledge,
108 _ => FrameSubtype::Reserved,
109 },
110 FrameType::Control => match subtype {
111 0b0111 => FrameSubtype::ControlWrapper,
112 0b1000 => FrameSubtype::BlockAcknowledgeRequest,
113 0b1001 => FrameSubtype::BlockAcknowledge,
114 0b1010 => FrameSubtype::PowerSavePoll,
115 0b1011 => FrameSubtype::RequestToSend,
116 0b1100 => FrameSubtype::ClearToSend,
117 0b1101 => FrameSubtype::Acknowledge,
118 0b1110 => FrameSubtype::ContentionFreeEnd,
119 0b1111 => FrameSubtype::ContentionFreeEndAcknowledge,
120 _ => FrameSubtype::Reserved,
121 },
122 FrameType::Data => match subtype {
123 0b0000 => FrameSubtype::Data,
124 0b0001 => FrameSubtype::DataContentionFreeAcknowledge,
125 0b0010 => FrameSubtype::DataContentionFreePoll,
126 0b0011 => FrameSubtype::DataContentionFreeAcknowledgePoll,
127 0b0100 => FrameSubtype::Null,
128 0b0101 => FrameSubtype::NullContentionFreeAcknowledge,
129 0b0110 => FrameSubtype::NullContentionFreePoll,
130 0b0111 => FrameSubtype::NullContentionFreeAcknowledgePoll,
131 0b1000 => FrameSubtype::QualityOfService,
132 0b1001 => FrameSubtype::QualityOfServiceContentionFreeAcknowledge,
133 0b1010 => FrameSubtype::QualityOfServiceContentionFreePoll,
134 0b1011 => FrameSubtype::QualityOfServiceContentionFreeAcknowledgePoll,
135 0b1100 => FrameSubtype::NullQualityOfService,
136 0b1101 => FrameSubtype::NullQualityOfServiceContentionFreeAcknowledge,
137 0b1110 => FrameSubtype::NullQualityOfServiceContentionFreePoll,
138 0b1111 => FrameSubtype::NullQualityOfServiceContentionFreeAcknowledgePoll,
139 _ => FrameSubtype::Reserved,
140 },
141 FrameType::Reserved => FrameSubtype::Reserved,
142 }
143 }
144 pub fn get_to_ds(&self) -> bool {
145 self.field & 0x0100 == 0x0100
146 }
147 pub fn get_from_ds(&self) -> bool {
148 self.field & 0x0200 == 0x0200
149 }
150 pub fn get_more_fragments(&self) -> bool {
151 self.field & 0x0400 == 0x0400
152 }
153 pub fn get_retry(&self) -> bool {
154 self.field & 0x0800 == 0x0800
155 }
156 pub fn get_power_management(&self) -> bool {
157 self.field & 0x1000 == 0x1000
158 }
159 pub fn get_more_data(&self) -> bool {
160 self.field & 0x2000 == 0x2000
161 }
162 pub fn get_protected(&self) -> bool {
163 self.field & 0x4000 == 0x4000
164 }
165 pub fn get_order(&self) -> bool {
166 self.field & 0x8000 == 0x8000
167 }
168}
169
170impl fmt::Display for FrameControl {
171 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
172 write!(f, "{0:04x} {1:?}", self.field, self.get_subtype())
173 }
174}
175
176#[derive(Debug, PartialEq)]
177pub struct FrameDuration {
178 field: u16,
179}
180
181impl From<FrameDuration> for u16 {
182 fn from(value: FrameDuration) -> Self {
183 value.field
184 }
185}
186
187impl From<u16> for FrameDuration {
188 fn from(value: u16) -> Self {
189 FrameDuration { field: value }
190 }
191}
192
193#[derive(Debug, PartialEq)]
194pub struct FrameSequence {
195 field: u16,
196}
197
198impl From<FrameSequence> for u16 {
199 fn from(value: FrameSequence) -> Self {
200 value.field
201 }
202}
203
204impl From<u16> for FrameSequence {
205 fn from(value: u16) -> Self {
206 FrameSequence { field: value }
207 }
208}
209
210#[derive(Debug, PartialEq)]
211pub struct ManagementFrame {
212 control: FrameControl,
213 duration: FrameDuration,
214 address1: HardwareAddress,
215 address2: HardwareAddress,
216 address3: HardwareAddress,
217 sequence: FrameSequence,
218 high_throughput_control: Option<u32>,
219}
220
221impl ManagementFrame {
222 fn unpack(control: FrameControl, duration: FrameDuration, buffer: &[u8]) -> Result<Self> {
223 let order = control.get_order();
224 let length = if order { 24 } else { 20 };
225 if buffer.len() > length {
226 let a1 = HardwareAddress::unpack_unchecked(&buffer[..]);
227 let a2 = HardwareAddress::unpack_unchecked(&buffer[6..]);
228 let a3 = HardwareAddress::unpack_unchecked(&buffer[12..]);
229 let sequence = FrameSequence::from(u16::unpack_unchecked(&buffer[18..]));
230 let htc = if order {
231 Some(u32::unpack_unchecked(&buffer[20..]))
232 } else {
233 None
234 };
235 return Ok(ManagementFrame {
236 control,
237 duration,
238 address1: a1,
239 address2: a2,
240 address3: a3,
241 sequence,
242 high_throughput_control: htc,
243 });
244 }
245 Err(io::Error::new(io::ErrorKind::InvalidData, "").into())
246 }
247}
248
249impl fmt::Display for ManagementFrame {
250 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
251 write!(
252 f,
253 "{} {} {} {}",
254 self.control, self.address1, self.address2, self.address3
255 )
256 }
257}
258
259#[derive(Debug, PartialEq)]
260pub struct ControlFrame {
261 control: FrameControl,
262 duration: FrameDuration,
263 address1: HardwareAddress,
264}
265
266impl fmt::Display for ControlFrame {
267 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
268 write!(f, "{} {}", self.control, self.address1)
269 }
270}
271
272impl ControlFrame {
273 fn unpack(control: FrameControl, duration: FrameDuration, buffer: &[u8]) -> Result<Self> {
274 if buffer.len() > 6 {
275 let a1 = HardwareAddress::unpack_unchecked(&buffer[..]);
276 return Ok(ControlFrame {
277 control,
278 duration,
279 address1: a1,
280 });
281 }
282 Err(io::Error::new(io::ErrorKind::InvalidData, "").into())
283 }
284}
285
286#[derive(Debug, PartialEq)]
287pub struct DataFrame {
288 control: FrameControl,
289 duration: FrameDuration,
290 address1: HardwareAddress,
291 address2: HardwareAddress,
292 address3: HardwareAddress,
293 sequence: FrameSequence,
294 address4: HardwareAddress,
295 quality_of_service_control: u16,
296 high_throughput_control: u32,
297}
298
299impl fmt::Display for DataFrame {
300 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
301 write!(f, "{} {}", self.control, self.address1)
302 }
303}
304
305impl DataFrame {
306 fn unpack(control: FrameControl, duration: FrameDuration, buffer: &[u8]) -> Result<Self> {
307 if buffer.len() > 32 {
308 let a1 = HardwareAddress::unpack_unchecked(&buffer[..]);
309 let a2 = HardwareAddress::unpack_unchecked(&buffer[6..]);
310 let a3 = HardwareAddress::unpack_unchecked(&buffer[12..]);
311 let sequence = u16::unpack_unchecked(&buffer[18..]);
312 let a4 = HardwareAddress::unpack_unchecked(&buffer[20..]);
313 let qos = u16::unpack_unchecked(&buffer[26..]);
314 let ht = u32::unpack_unchecked(&buffer[28..]);
315 return Ok(DataFrame {
316 control,
317 duration,
318 address1: a1,
319 address2: a2,
320 address3: a3,
321 sequence: FrameSequence::from(sequence),
322 address4: a4,
323 quality_of_service_control: qos,
324 high_throughput_control: ht,
325 });
326 }
327 Err(io::Error::new(io::ErrorKind::InvalidData, "").into())
328 }
329}
330
331#[derive(Debug, PartialEq)]
332pub enum Frame {
333 Management(ManagementFrame),
334 Control(ControlFrame),
335 Data(DataFrame),
336}
337
338impl Frame {
339 pub fn unpack(buffer: &[u8]) -> Result<Frame> {
340 if buffer.len() > 4 {
341 let control = FrameControl::from(u16::unpack_unchecked(&buffer[..]));
342 let duration = FrameDuration::from(u16::unpack_unchecked(&buffer[2..]));
343 match control.get_type() {
344 FrameType::Management => {
345 let management = ManagementFrame::unpack(control, duration, &buffer[4..])?;
346 return Ok(Frame::Management(management));
347 }
348 FrameType::Control => {
349 let control = ControlFrame::unpack(control, duration, &buffer[4..])?;
350 return Ok(Frame::Control(control));
351 }
352 FrameType::Data => {
353 let data = DataFrame::unpack(control, duration, &buffer[4..])?;
354 return Ok(Frame::Data(data));
355 }
356 _ => (),
357 }
358 }
359 Err(io::Error::new(io::ErrorKind::InvalidData, "").into())
360 }
361}
362
363impl fmt::Display for Frame {
364 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
365 match *self {
366 Frame::Management(ref frame) => write!(f, "{}", frame),
367 Frame::Control(ref frame) => write!(f, "{}", frame),
368 Frame::Data(ref frame) => write!(f, "{}", frame),
369 }
370 }
371}