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