1pub mod builder;
14pub mod control;
15pub mod data;
16pub mod ie;
17pub mod management;
18pub mod radiotap;
19pub mod security;
20pub mod types;
21
22pub use builder::Dot11Builder;
23pub use control::{
24 Dot11Ack, Dot11BlockAck, Dot11BlockAckReq, Dot11CFEnd, Dot11CTS, Dot11PSPoll, Dot11RTS,
25};
26pub use data::Dot11QoS;
27pub use ie::{Dot11Elt, Dot11EltRSN, Dot11EltRates};
28pub use management::{
29 Dot11Action, Dot11AssocReq, Dot11AssocResp, Dot11Auth, Dot11Beacon, Dot11Deauth, Dot11Disas,
30 Dot11ProbeReq, Dot11ProbeResp, Dot11ReassocReq, Dot11ReassocResp,
31};
32pub use radiotap::{RadioTapBuilder, RadioTapLayer};
33pub use security::{Dot11CCMP, Dot11TKIP, Dot11WEP};
34
35use crate::layer::field::{Field, FieldError, FieldValue, MacAddress};
36use crate::layer::{Layer, LayerIndex, LayerKind};
37
38pub const DOT11_MIN_HEADER_LEN: usize = 10;
41
42pub const DOT11_MGMT_HEADER_LEN: usize = 24;
44
45pub const DOT11_WDS_HEADER_LEN: usize = 30;
47
48pub const DOT11_FCS_LEN: usize = 4;
50
51pub mod offsets {
54 pub const FRAME_CONTROL: usize = 0;
56 pub const DURATION: usize = 2;
58 pub const ADDR1: usize = 4;
60 pub const ADDR2: usize = 10;
62 pub const ADDR3: usize = 16;
64 pub const SEQ_CTRL: usize = 22;
66 pub const ADDR4: usize = 24;
68}
69
70#[derive(Debug, Clone)]
81pub struct Dot11Layer {
82 pub index: LayerIndex,
83}
84
85impl Dot11Layer {
86 pub fn new(start: usize, end: usize) -> Self {
88 Self {
89 index: LayerIndex::new(LayerKind::Dot11, start, end),
90 }
91 }
92
93 pub fn validate(buf: &[u8], offset: usize) -> Result<(), FieldError> {
95 if buf.len() < offset + DOT11_MIN_HEADER_LEN {
96 return Err(FieldError::BufferTooShort {
97 offset,
98 need: DOT11_MIN_HEADER_LEN,
99 have: buf.len().saturating_sub(offset),
100 });
101 }
102 Ok(())
103 }
104
105 #[inline]
111 pub fn frame_control_raw(&self, buf: &[u8]) -> Result<u16, FieldError> {
112 let off = self.index.start + offsets::FRAME_CONTROL;
113 if buf.len() < off + 2 {
114 return Err(FieldError::BufferTooShort {
115 offset: off,
116 need: 2,
117 have: buf.len(),
118 });
119 }
120 Ok(u16::from_le_bytes([buf[off], buf[off + 1]]))
121 }
122
123 #[inline]
125 pub fn protocol_version(&self, buf: &[u8]) -> Result<u8, FieldError> {
126 let fc = self.frame_control_raw(buf)?;
127 Ok((fc & 0x0003) as u8)
128 }
129
130 #[inline]
132 pub fn frame_type(&self, buf: &[u8]) -> Result<u8, FieldError> {
133 let fc = self.frame_control_raw(buf)?;
134 Ok(((fc >> 2) & 0x0003) as u8)
135 }
136
137 #[inline]
139 pub fn subtype(&self, buf: &[u8]) -> Result<u8, FieldError> {
140 let fc = self.frame_control_raw(buf)?;
141 Ok(((fc >> 4) & 0x000F) as u8)
142 }
143
144 #[inline]
146 pub fn flags(&self, buf: &[u8]) -> Result<u8, FieldError> {
147 let fc = self.frame_control_raw(buf)?;
148 Ok((fc >> 8) as u8)
149 }
150
151 #[inline]
153 pub fn to_ds(&self, buf: &[u8]) -> Result<bool, FieldError> {
154 Ok(self.flags(buf)? & types::fc_flags::TO_DS != 0)
155 }
156
157 #[inline]
159 pub fn from_ds(&self, buf: &[u8]) -> Result<bool, FieldError> {
160 Ok(self.flags(buf)? & types::fc_flags::FROM_DS != 0)
161 }
162
163 #[inline]
165 pub fn more_frag(&self, buf: &[u8]) -> Result<bool, FieldError> {
166 Ok(self.flags(buf)? & types::fc_flags::MORE_FRAG != 0)
167 }
168
169 #[inline]
171 pub fn retry(&self, buf: &[u8]) -> Result<bool, FieldError> {
172 Ok(self.flags(buf)? & types::fc_flags::RETRY != 0)
173 }
174
175 #[inline]
177 pub fn pwr_mgt(&self, buf: &[u8]) -> Result<bool, FieldError> {
178 Ok(self.flags(buf)? & types::fc_flags::PWR_MGT != 0)
179 }
180
181 #[inline]
183 pub fn more_data(&self, buf: &[u8]) -> Result<bool, FieldError> {
184 Ok(self.flags(buf)? & types::fc_flags::MORE_DATA != 0)
185 }
186
187 #[inline]
189 pub fn protected(&self, buf: &[u8]) -> Result<bool, FieldError> {
190 Ok(self.flags(buf)? & types::fc_flags::PROTECTED != 0)
191 }
192
193 #[inline]
195 pub fn htc_order(&self, buf: &[u8]) -> Result<bool, FieldError> {
196 Ok(self.flags(buf)? & types::fc_flags::HTC_ORDER != 0)
197 }
198
199 #[inline]
205 pub fn duration(&self, buf: &[u8]) -> Result<u16, FieldError> {
206 let off = self.index.start + offsets::DURATION;
207 if buf.len() < off + 2 {
208 return Err(FieldError::BufferTooShort {
209 offset: off,
210 need: 2,
211 have: buf.len(),
212 });
213 }
214 Ok(u16::from_le_bytes([buf[off], buf[off + 1]]))
215 }
216
217 #[inline]
223 pub fn addr1(&self, buf: &[u8]) -> Result<MacAddress, FieldError> {
224 MacAddress::read(buf, self.index.start + offsets::ADDR1)
225 }
226
227 #[inline]
229 pub fn addr2(&self, buf: &[u8]) -> Result<MacAddress, FieldError> {
230 MacAddress::read(buf, self.index.start + offsets::ADDR2)
231 }
232
233 #[inline]
235 pub fn addr3(&self, buf: &[u8]) -> Result<MacAddress, FieldError> {
236 MacAddress::read(buf, self.index.start + offsets::ADDR3)
237 }
238
239 #[inline]
241 pub fn addr4(&self, buf: &[u8]) -> Result<MacAddress, FieldError> {
242 MacAddress::read(buf, self.index.start + offsets::ADDR4)
243 }
244
245 #[inline]
247 pub fn has_addr4(&self, buf: &[u8]) -> bool {
248 if let Ok(ft) = self.frame_type(buf) {
249 if ft == types::frame_type::DATA {
250 if let Ok(flags) = self.flags(buf) {
251 return (flags & 0x03) == 0x03; }
253 }
254 }
255 false
256 }
257
258 #[inline]
260 pub fn is_control(&self, buf: &[u8]) -> bool {
261 matches!(self.frame_type(buf), Ok(types::frame_type::CONTROL))
262 }
263
264 #[inline]
270 pub fn seq_ctrl_raw(&self, buf: &[u8]) -> Result<u16, FieldError> {
271 let off = self.index.start + offsets::SEQ_CTRL;
272 if buf.len() < off + 2 {
273 return Err(FieldError::BufferTooShort {
274 offset: off,
275 need: 2,
276 have: buf.len(),
277 });
278 }
279 Ok(u16::from_le_bytes([buf[off], buf[off + 1]]))
280 }
281
282 #[inline]
284 pub fn fragment_num(&self, buf: &[u8]) -> Result<u8, FieldError> {
285 Ok((self.seq_ctrl_raw(buf)? & 0x000F) as u8)
286 }
287
288 #[inline]
290 pub fn sequence_num(&self, buf: &[u8]) -> Result<u16, FieldError> {
291 Ok(self.seq_ctrl_raw(buf)? >> 4)
292 }
293
294 pub fn compute_header_len(&self, buf: &[u8]) -> usize {
300 let ft = self.frame_type(buf).unwrap_or(0);
301 let st = self.subtype(buf).unwrap_or(0);
302
303 match ft {
304 types::frame_type::MANAGEMENT => DOT11_MGMT_HEADER_LEN,
305 types::frame_type::CONTROL => {
306 match st {
307 types::ctrl_subtype::ACK | types::ctrl_subtype::CTS => {
308 10
310 }
311 _ => {
312 16
314 }
315 }
316 }
317 types::frame_type::DATA => {
318 if self.has_addr4(buf) {
319 DOT11_WDS_HEADER_LEN
320 } else {
321 DOT11_MGMT_HEADER_LEN
322 }
323 }
324 types::frame_type::EXTENSION => 10,
325 _ => DOT11_MIN_HEADER_LEN,
326 }
327 }
328
329 pub fn set_frame_control(&self, buf: &mut [u8], fc: u16) -> Result<(), FieldError> {
335 let off = self.index.start + offsets::FRAME_CONTROL;
336 if buf.len() < off + 2 {
337 return Err(FieldError::BufferTooShort {
338 offset: off,
339 need: 2,
340 have: buf.len(),
341 });
342 }
343 let bytes = fc.to_le_bytes();
344 buf[off] = bytes[0];
345 buf[off + 1] = bytes[1];
346 Ok(())
347 }
348
349 pub fn set_duration(&self, buf: &mut [u8], dur: u16) -> Result<(), FieldError> {
351 let off = self.index.start + offsets::DURATION;
352 if buf.len() < off + 2 {
353 return Err(FieldError::BufferTooShort {
354 offset: off,
355 need: 2,
356 have: buf.len(),
357 });
358 }
359 let bytes = dur.to_le_bytes();
360 buf[off] = bytes[0];
361 buf[off + 1] = bytes[1];
362 Ok(())
363 }
364
365 pub fn set_addr1(&self, buf: &mut [u8], mac: MacAddress) -> Result<(), FieldError> {
367 mac.write(buf, self.index.start + offsets::ADDR1)
368 }
369
370 pub fn set_addr2(&self, buf: &mut [u8], mac: MacAddress) -> Result<(), FieldError> {
372 mac.write(buf, self.index.start + offsets::ADDR2)
373 }
374
375 pub fn set_addr3(&self, buf: &mut [u8], mac: MacAddress) -> Result<(), FieldError> {
377 mac.write(buf, self.index.start + offsets::ADDR3)
378 }
379
380 pub fn set_addr4(&self, buf: &mut [u8], mac: MacAddress) -> Result<(), FieldError> {
382 mac.write(buf, self.index.start + offsets::ADDR4)
383 }
384
385 pub fn set_seq_ctrl(&self, buf: &mut [u8], sc: u16) -> Result<(), FieldError> {
387 let off = self.index.start + offsets::SEQ_CTRL;
388 if buf.len() < off + 2 {
389 return Err(FieldError::BufferTooShort {
390 offset: off,
391 need: 2,
392 have: buf.len(),
393 });
394 }
395 let bytes = sc.to_le_bytes();
396 buf[off] = bytes[0];
397 buf[off + 1] = bytes[1];
398 Ok(())
399 }
400
401 pub fn field_names() -> &'static [&'static str] {
407 &[
408 "type", "subtype", "proto", "FCfield", "ID", "addr1", "addr2", "addr3", "SC", "addr4",
409 ]
410 }
411
412 pub fn get_field(&self, buf: &[u8], name: &str) -> Option<Result<FieldValue, FieldError>> {
414 match name {
415 "type" => Some(self.frame_type(buf).map(FieldValue::U8)),
416 "subtype" => Some(self.subtype(buf).map(FieldValue::U8)),
417 "proto" => Some(self.protocol_version(buf).map(FieldValue::U8)),
418 "FCfield" => Some(self.flags(buf).map(FieldValue::U8)),
419 "ID" => Some(self.duration(buf).map(FieldValue::U16)),
420 "addr1" => Some(self.addr1(buf).map(FieldValue::Mac)),
421 "addr2" => Some(self.addr2(buf).map(FieldValue::Mac)),
422 "addr3" => Some(self.addr3(buf).map(FieldValue::Mac)),
423 "SC" => Some(self.seq_ctrl_raw(buf).map(FieldValue::U16)),
424 "addr4" => {
425 if self.has_addr4(buf) {
426 Some(self.addr4(buf).map(FieldValue::Mac))
427 } else {
428 None
429 }
430 }
431 _ => None,
432 }
433 }
434
435 pub fn set_field(
437 &self,
438 buf: &mut [u8],
439 name: &str,
440 value: FieldValue,
441 ) -> Option<Result<(), FieldError>> {
442 match name {
443 "ID" => match value {
444 FieldValue::U16(v) => Some(self.set_duration(buf, v)),
445 _ => Some(Err(FieldError::TypeMismatch {
446 expected: "u16",
447 got: "other",
448 })),
449 },
450 "addr1" => match value {
451 FieldValue::Mac(m) => Some(self.set_addr1(buf, m)),
452 _ => Some(Err(FieldError::TypeMismatch {
453 expected: "mac",
454 got: "other",
455 })),
456 },
457 "addr2" => match value {
458 FieldValue::Mac(m) => Some(self.set_addr2(buf, m)),
459 _ => Some(Err(FieldError::TypeMismatch {
460 expected: "mac",
461 got: "other",
462 })),
463 },
464 "addr3" => match value {
465 FieldValue::Mac(m) => Some(self.set_addr3(buf, m)),
466 _ => Some(Err(FieldError::TypeMismatch {
467 expected: "mac",
468 got: "other",
469 })),
470 },
471 "addr4" => match value {
472 FieldValue::Mac(m) => Some(self.set_addr4(buf, m)),
473 _ => Some(Err(FieldError::TypeMismatch {
474 expected: "mac",
475 got: "other",
476 })),
477 },
478 "SC" => match value {
479 FieldValue::U16(v) => Some(self.set_seq_ctrl(buf, v)),
480 _ => Some(Err(FieldError::TypeMismatch {
481 expected: "u16",
482 got: "other",
483 })),
484 },
485 _ => None,
486 }
487 }
488
489 pub fn hashret(&self, buf: &[u8]) -> Vec<u8> {
491 let mut hash = Vec::new();
492 if let Ok(addr1) = self.addr1(buf) {
493 hash.extend_from_slice(addr1.as_bytes());
494 }
495 if let Ok(addr2) = self.addr2(buf) {
496 hash.extend_from_slice(addr2.as_bytes());
497 }
498 hash
499 }
500
501 pub fn answers(&self, buf: &[u8], other: &Dot11Layer, other_buf: &[u8]) -> bool {
503 let self_type = self.frame_type(buf).unwrap_or(255);
504 let other_type = other.frame_type(other_buf).unwrap_or(255);
505
506 if self_type != other_type {
507 return false;
508 }
509
510 match self_type {
511 types::frame_type::MANAGEMENT => {
512 let self_addr1 = self.addr1(buf).unwrap_or(MacAddress::ZERO);
513 let other_addr2 = other.addr2(other_buf).unwrap_or(MacAddress::ZERO);
514 if self_addr1 != other_addr2 {
515 return false;
516 }
517 let self_sub = self.subtype(buf).unwrap_or(255);
518 let other_sub = other.subtype(other_buf).unwrap_or(255);
519 matches!((other_sub, self_sub), (0, 1) | (2, 3) | (4, 5) | (11, 11))
520 }
521 types::frame_type::CONTROL => false,
522 types::frame_type::DATA => true,
523 _ => false,
524 }
525 }
526}
527
528impl Layer for Dot11Layer {
529 fn kind(&self) -> LayerKind {
530 LayerKind::Dot11
531 }
532
533 fn summary(&self, buf: &[u8]) -> String {
534 let ft = self.frame_type(buf).unwrap_or(0);
535 let st = self.subtype(buf).unwrap_or(0);
536 let type_name = types::frame_type::name(ft);
537 let subtype_name = types::subtype_name(ft, st);
538 let addr2_str = self
539 .addr2(buf)
540 .map(|a| a.to_string())
541 .unwrap_or_else(|_| "?".to_string());
542 let addr1_str = self
543 .addr1(buf)
544 .map(|a| a.to_string())
545 .unwrap_or_else(|_| "?".to_string());
546 format!(
547 "802.11 {} {} {} > {}",
548 type_name, subtype_name, addr2_str, addr1_str
549 )
550 }
551
552 fn header_len(&self, buf: &[u8]) -> usize {
553 self.compute_header_len(buf)
554 }
555
556 fn hashret(&self, data: &[u8]) -> Vec<u8> {
557 self.hashret(data)
558 }
559
560 fn field_names(&self) -> &'static [&'static str] {
561 Dot11Layer::field_names()
562 }
563}
564
565#[derive(Debug, Clone)]
567pub struct Dot11FcsLayer {
568 pub index: LayerIndex,
569}
570
571impl Dot11FcsLayer {
572 pub fn new(start: usize, end: usize) -> Self {
574 Self {
575 index: LayerIndex::new(LayerKind::Dot11, start, end),
576 }
577 }
578
579 pub fn dot11(&self) -> Dot11Layer {
581 Dot11Layer::new(
582 self.index.start,
583 self.index.end.saturating_sub(DOT11_FCS_LEN),
584 )
585 }
586
587 pub fn fcs(&self, buf: &[u8]) -> Result<u32, FieldError> {
589 let off = self.index.end.saturating_sub(DOT11_FCS_LEN);
590 if buf.len() < off + 4 {
591 return Err(FieldError::BufferTooShort {
592 offset: off,
593 need: 4,
594 have: buf.len(),
595 });
596 }
597 Ok(u32::from_le_bytes([
598 buf[off],
599 buf[off + 1],
600 buf[off + 2],
601 buf[off + 3],
602 ]))
603 }
604
605 pub fn compute_fcs(data: &[u8]) -> u32 {
607 crc32_ieee(data)
608 }
609
610 pub fn verify_fcs(&self, buf: &[u8]) -> Result<bool, FieldError> {
612 let fcs_val = self.fcs(buf)?;
613 let data_end = self.index.end.saturating_sub(DOT11_FCS_LEN);
614 let data = &buf[self.index.start..data_end];
615 let computed = Self::compute_fcs(data);
616 Ok(fcs_val == computed)
617 }
618
619 pub fn frame_type(&self, buf: &[u8]) -> Result<u8, FieldError> {
621 self.dot11().frame_type(buf)
622 }
623
624 pub fn subtype(&self, buf: &[u8]) -> Result<u8, FieldError> {
625 self.dot11().subtype(buf)
626 }
627
628 pub fn flags(&self, buf: &[u8]) -> Result<u8, FieldError> {
629 self.dot11().flags(buf)
630 }
631
632 pub fn addr1(&self, buf: &[u8]) -> Result<MacAddress, FieldError> {
633 self.dot11().addr1(buf)
634 }
635
636 pub fn addr2(&self, buf: &[u8]) -> Result<MacAddress, FieldError> {
637 self.dot11().addr2(buf)
638 }
639
640 pub fn addr3(&self, buf: &[u8]) -> Result<MacAddress, FieldError> {
641 self.dot11().addr3(buf)
642 }
643
644 pub fn duration(&self, buf: &[u8]) -> Result<u16, FieldError> {
645 self.dot11().duration(buf)
646 }
647}
648
649impl Layer for Dot11FcsLayer {
650 fn kind(&self) -> LayerKind {
651 LayerKind::Dot11
652 }
653
654 fn summary(&self, buf: &[u8]) -> String {
655 let inner = self.dot11();
656 let base = inner.summary(buf);
657 let fcs_str = self
658 .fcs(buf)
659 .map(|f| format!(" [FCS={:#010x}]", f))
660 .unwrap_or_default();
661 format!("{}{}", base, fcs_str)
662 }
663
664 fn header_len(&self, buf: &[u8]) -> usize {
665 self.dot11().compute_header_len(buf)
666 }
667
668 fn field_names(&self) -> &'static [&'static str] {
669 Dot11Layer::field_names()
670 }
671}
672
673pub fn build_frame_control(proto: u8, frame_type: u8, subtype: u8, flags: u8) -> u16 {
681 let byte0 = (proto & 0x03) | ((frame_type & 0x03) << 2) | ((subtype & 0x0F) << 4);
682 u16::from_le_bytes([byte0, flags])
683}
684
685pub fn crc32_ieee(data: &[u8]) -> u32 {
687 let mut crc: u32 = 0xFFFFFFFF;
688 for &byte in data {
689 crc ^= byte as u32;
690 for _ in 0..8 {
691 if crc & 1 != 0 {
692 crc = (crc >> 1) ^ 0xEDB88320;
693 } else {
694 crc >>= 1;
695 }
696 }
697 }
698 crc ^ 0xFFFFFFFF
699}
700
701#[cfg(test)]
702mod tests {
703 use super::*;
704
705 fn make_beacon_frame() -> Vec<u8> {
707 let mut buf = vec![0u8; 24];
708 buf[0] = 0x80;
712 buf[1] = 0x00;
713 buf[2] = 0x00;
715 buf[3] = 0x00;
716 buf[4..10].copy_from_slice(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
718 buf[10..16].copy_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]);
720 buf[16..22].copy_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]);
722 buf[22] = 0x10;
724 buf[23] = 0x00;
725 buf
726 }
727
728 fn make_ack_frame() -> Vec<u8> {
730 let mut buf = vec![0u8; 10];
731 buf[0] = 0xD4;
734 buf[1] = 0x00;
735 buf[2] = 0x00;
736 buf[3] = 0x00;
737 buf[4..10].copy_from_slice(&[0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF]);
738 buf
739 }
740
741 fn make_wds_data_frame() -> Vec<u8> {
743 let mut buf = vec![0u8; 30];
744 buf[0] = 0x08;
747 buf[1] = 0x03;
749 buf[2] = 0x00;
750 buf[3] = 0x00;
751 buf[4..10].copy_from_slice(&[0x01, 0x02, 0x03, 0x04, 0x05, 0x06]);
752 buf[10..16].copy_from_slice(&[0x11, 0x12, 0x13, 0x14, 0x15, 0x16]);
753 buf[16..22].copy_from_slice(&[0x21, 0x22, 0x23, 0x24, 0x25, 0x26]);
754 buf[22] = 0x00;
755 buf[23] = 0x00;
756 buf[24..30].copy_from_slice(&[0x31, 0x32, 0x33, 0x34, 0x35, 0x36]);
757 buf
758 }
759
760 #[test]
761 fn test_parse_beacon_frame_control() {
762 let buf = make_beacon_frame();
763 let layer = Dot11Layer::new(0, buf.len());
764
765 assert_eq!(layer.protocol_version(&buf).unwrap(), 0);
766 assert_eq!(layer.frame_type(&buf).unwrap(), 0);
767 assert_eq!(layer.subtype(&buf).unwrap(), 8);
768 assert_eq!(layer.flags(&buf).unwrap(), 0);
769 }
770
771 #[test]
772 fn test_parse_beacon_addresses() {
773 let buf = make_beacon_frame();
774 let layer = Dot11Layer::new(0, buf.len());
775
776 assert!(layer.addr1(&buf).unwrap().is_broadcast());
777 assert_eq!(
778 layer.addr2(&buf).unwrap(),
779 MacAddress::new([0x00, 0x11, 0x22, 0x33, 0x44, 0x55])
780 );
781 assert_eq!(
782 layer.addr3(&buf).unwrap(),
783 MacAddress::new([0x00, 0x11, 0x22, 0x33, 0x44, 0x55])
784 );
785 }
786
787 #[test]
788 fn test_parse_beacon_seq_ctrl() {
789 let buf = make_beacon_frame();
790 let layer = Dot11Layer::new(0, buf.len());
791
792 assert_eq!(layer.seq_ctrl_raw(&buf).unwrap(), 0x0010);
793 assert_eq!(layer.fragment_num(&buf).unwrap(), 0);
794 assert_eq!(layer.sequence_num(&buf).unwrap(), 1);
795 }
796
797 #[test]
798 fn test_beacon_header_len() {
799 let buf = make_beacon_frame();
800 let layer = Dot11Layer::new(0, buf.len());
801 assert_eq!(layer.compute_header_len(&buf), 24);
802 }
803
804 #[test]
805 fn test_parse_ack_frame() {
806 let buf = make_ack_frame();
807 let layer = Dot11Layer::new(0, buf.len());
808
809 assert_eq!(layer.frame_type(&buf).unwrap(), 1);
810 assert_eq!(layer.subtype(&buf).unwrap(), 13);
811 assert_eq!(layer.compute_header_len(&buf), 10);
812 assert_eq!(
813 layer.addr1(&buf).unwrap(),
814 MacAddress::new([0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF])
815 );
816 }
817
818 #[test]
819 fn test_parse_wds_frame() {
820 let buf = make_wds_data_frame();
821 let layer = Dot11Layer::new(0, buf.len());
822
823 assert_eq!(layer.frame_type(&buf).unwrap(), 2);
824 assert!(layer.to_ds(&buf).unwrap());
825 assert!(layer.from_ds(&buf).unwrap());
826 assert!(layer.has_addr4(&buf));
827 assert_eq!(layer.compute_header_len(&buf), 30);
828 assert_eq!(
829 layer.addr4(&buf).unwrap(),
830 MacAddress::new([0x31, 0x32, 0x33, 0x34, 0x35, 0x36])
831 );
832 }
833
834 #[test]
835 fn test_build_frame_control() {
836 let fc = build_frame_control(0, 0, 8, 0);
837 assert_eq!(fc.to_le_bytes(), [0x80, 0x00]);
838
839 let fc = build_frame_control(0, 1, 13, 0);
840 assert_eq!(fc.to_le_bytes(), [0xD4, 0x00]);
841
842 let fc = build_frame_control(0, 2, 0, 0x01);
843 assert_eq!(fc.to_le_bytes(), [0x08, 0x01]);
844 }
845
846 #[test]
847 fn test_flags_parsing() {
848 let mut buf = make_beacon_frame();
849 buf[1] = types::fc_flags::RETRY | types::fc_flags::PROTECTED;
850 let layer = Dot11Layer::new(0, buf.len());
851
852 assert!(layer.retry(&buf).unwrap());
853 assert!(layer.protected(&buf).unwrap());
854 assert!(!layer.to_ds(&buf).unwrap());
855 assert!(!layer.from_ds(&buf).unwrap());
856 }
857
858 #[test]
859 fn test_summary() {
860 let buf = make_beacon_frame();
861 let layer = Dot11Layer::new(0, buf.len());
862 let summary = layer.summary(&buf);
863 assert!(summary.contains("Management"));
864 assert!(summary.contains("Beacon"));
865 }
866
867 #[test]
868 fn test_field_access() {
869 let buf = make_beacon_frame();
870 let layer = Dot11Layer::new(0, buf.len());
871
872 let ft = layer.get_field(&buf, "type").unwrap().unwrap();
873 assert_eq!(ft, FieldValue::U8(0));
874
875 let st = layer.get_field(&buf, "subtype").unwrap().unwrap();
876 assert_eq!(st, FieldValue::U8(8));
877
878 let a1 = layer.get_field(&buf, "addr1").unwrap().unwrap();
879 assert_eq!(a1, FieldValue::Mac(MacAddress::BROADCAST));
880 }
881
882 #[test]
883 fn test_set_duration() {
884 let mut buf = make_beacon_frame();
885 let layer = Dot11Layer::new(0, buf.len());
886
887 layer.set_duration(&mut buf, 0x1234).unwrap();
888 assert_eq!(layer.duration(&buf).unwrap(), 0x1234);
889 }
890
891 #[test]
892 fn test_crc32() {
893 let data = b"123456789";
894 assert_eq!(crc32_ieee(data), 0xCBF43926);
895 }
896
897 #[test]
898 fn test_fcs_layer() {
899 let mut buf = make_beacon_frame();
900 let fcs = crc32_ieee(&buf);
901 buf.extend_from_slice(&fcs.to_le_bytes());
902
903 let fcs_layer = Dot11FcsLayer::new(0, buf.len());
904 assert_eq!(fcs_layer.fcs(&buf).unwrap(), fcs);
905 assert!(fcs_layer.verify_fcs(&buf).unwrap());
906
907 assert_eq!(fcs_layer.frame_type(&buf).unwrap(), 0);
908 assert_eq!(fcs_layer.subtype(&buf).unwrap(), 8);
909 }
910
911 #[test]
912 fn test_roundtrip_build_parse() {
913 let fc = build_frame_control(0, 0, 8, 0);
914 let mut buf = vec![0u8; 24];
915 buf[0..2].copy_from_slice(&fc.to_le_bytes());
916 buf[2..4].copy_from_slice(&0u16.to_le_bytes());
917 buf[4..10].copy_from_slice(&[0xff; 6]);
918 buf[10..16].copy_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]);
919 buf[16..22].copy_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]);
920 buf[22..24].copy_from_slice(&0x0020u16.to_le_bytes());
921
922 let layer = Dot11Layer::new(0, buf.len());
923 assert_eq!(layer.frame_type(&buf).unwrap(), 0);
924 assert_eq!(layer.subtype(&buf).unwrap(), 8);
925 assert_eq!(layer.sequence_num(&buf).unwrap(), 2);
926 assert_eq!(layer.fragment_num(&buf).unwrap(), 0);
927 }
928
929 #[test]
930 fn test_answers_management() {
931 let mut req = vec![0u8; 24];
932 req[0] = 0x00; req[4..10].copy_from_slice(&[0xBB; 6]);
934 req[10..16].copy_from_slice(&[0xAA; 6]);
935
936 let mut resp = vec![0u8; 24];
937 resp[0] = 0x10; resp[4..10].copy_from_slice(&[0xAA; 6]);
939 resp[10..16].copy_from_slice(&[0xBB; 6]);
940
941 let req_layer = Dot11Layer::new(0, req.len());
942 let resp_layer = Dot11Layer::new(0, resp.len());
943
944 assert!(resp_layer.answers(&resp, &req_layer, &req));
945 assert!(!req_layer.answers(&req, &resp_layer, &resp));
946 }
947}