1pub mod beacon;
15pub mod builder;
16pub mod command;
17pub mod crc;
18pub mod security;
19pub mod types;
20
21pub use builder::{Dot15d4Builder, Dot15d4FcsBuilder};
22
23use crate::layer::field::{
24 FieldError, FieldValue, read_u16_le, read_u64_le, write_u16_le, write_u64_le,
25};
26use crate::layer::{Layer, LayerIndex, LayerKind};
27
28pub const DOT15D4_MIN_HEADER_LEN: usize = 3;
30
31pub const FCS_LEN: usize = 2;
33
34pub const DOT15D4_FIELDS: &[&str] = &[
36 "fcf_frametype",
37 "fcf_security",
38 "fcf_pending",
39 "fcf_ackreq",
40 "fcf_panidcompress",
41 "fcf_destaddrmode",
42 "fcf_framever",
43 "fcf_srcaddrmode",
44 "seqnum",
45 "dest_panid",
46 "dest_addr_short",
47 "dest_addr_long",
48 "src_panid",
49 "src_addr_short",
50 "src_addr_long",
51];
52
53pub const DOT15D4_FCS_FIELDS: &[&str] = &[
55 "fcf_frametype",
56 "fcf_security",
57 "fcf_pending",
58 "fcf_ackreq",
59 "fcf_panidcompress",
60 "fcf_destaddrmode",
61 "fcf_framever",
62 "fcf_srcaddrmode",
63 "seqnum",
64 "dest_panid",
65 "dest_addr_short",
66 "dest_addr_long",
67 "src_panid",
68 "src_addr_short",
69 "src_addr_long",
70 "fcs",
71];
72
73#[inline]
79fn read_fcf(buf: &[u8], offset: usize) -> Result<u16, FieldError> {
80 read_u16_le(buf, offset)
81}
82
83#[inline]
85fn write_fcf(buf: &mut [u8], offset: usize, fcf: u16) -> Result<(), FieldError> {
86 write_u16_le(fcf, buf, offset)
87}
88
89#[inline]
91pub fn fcf_frame_type(fcf: u16) -> u8 {
92 (fcf & 0x0007) as u8
93}
94
95#[inline]
97pub fn fcf_security(fcf: u16) -> bool {
98 (fcf & 0x0008) != 0
99}
100
101#[inline]
103pub fn fcf_pending(fcf: u16) -> bool {
104 (fcf & 0x0010) != 0
105}
106
107#[inline]
109pub fn fcf_ackreq(fcf: u16) -> bool {
110 (fcf & 0x0020) != 0
111}
112
113#[inline]
115pub fn fcf_panid_compress(fcf: u16) -> bool {
116 (fcf & 0x0040) != 0
117}
118
119#[inline]
121pub fn fcf_dest_addr_mode(fcf: u16) -> u8 {
122 ((fcf >> 10) & 0x03) as u8
123}
124
125#[inline]
127pub fn fcf_frame_ver(fcf: u16) -> u8 {
128 ((fcf >> 12) & 0x03) as u8
129}
130
131#[inline]
133pub fn fcf_src_addr_mode(fcf: u16) -> u8 {
134 ((fcf >> 14) & 0x03) as u8
135}
136
137pub fn build_fcf(
139 frame_type: u8,
140 security: bool,
141 pending: bool,
142 ackreq: bool,
143 panid_compress: bool,
144 dest_addr_mode: u8,
145 frame_ver: u8,
146 src_addr_mode: u8,
147) -> u16 {
148 let mut fcf: u16 = 0;
149 fcf |= (frame_type as u16) & 0x07;
150 if security {
151 fcf |= 0x0008;
152 }
153 if pending {
154 fcf |= 0x0010;
155 }
156 if ackreq {
157 fcf |= 0x0020;
158 }
159 if panid_compress {
160 fcf |= 0x0040;
161 }
162 fcf |= ((dest_addr_mode as u16) & 0x03) << 10;
164 fcf |= ((frame_ver as u16) & 0x03) << 12;
165 fcf |= ((src_addr_mode as u16) & 0x03) << 14;
166 fcf
167}
168
169pub fn compute_header_len(fcf: u16) -> usize {
179 let mut len = DOT15D4_MIN_HEADER_LEN; let dest_mode = fcf_dest_addr_mode(fcf);
181 let src_mode = fcf_src_addr_mode(fcf);
182 let panid_compress = fcf_panid_compress(fcf);
183
184 if dest_mode != types::addr_mode::NONE {
186 len += 2; len += types::addr_mode_len(dest_mode);
188 }
189
190 if src_mode != types::addr_mode::NONE {
192 if !panid_compress {
193 len += 2; }
195 len += types::addr_mode_len(src_mode);
196 }
197
198 len
199}
200
201#[inline]
203fn addr_start(start: usize) -> usize {
204 start + DOT15D4_MIN_HEADER_LEN
205}
206
207#[derive(Debug, Clone)]
216pub struct Dot15d4Layer {
217 pub index: LayerIndex,
218}
219
220impl Dot15d4Layer {
221 pub fn new(start: usize, end: usize) -> Self {
223 Self {
224 index: LayerIndex::new(LayerKind::Dot15d4, start, end),
225 }
226 }
227
228 pub fn validate(buf: &[u8], offset: usize) -> Result<(), FieldError> {
230 if buf.len() < offset + DOT15D4_MIN_HEADER_LEN {
231 return Err(FieldError::BufferTooShort {
232 offset,
233 need: DOT15D4_MIN_HEADER_LEN,
234 have: buf.len().saturating_sub(offset),
235 });
236 }
237 Ok(())
238 }
239
240 #[inline]
246 pub fn fcf_raw(&self, buf: &[u8]) -> Result<u16, FieldError> {
247 read_fcf(buf, self.index.start)
248 }
249
250 pub fn fcf_frametype(&self, buf: &[u8]) -> Result<u8, FieldError> {
252 self.fcf_raw(buf).map(fcf_frame_type)
253 }
254
255 pub fn fcf_security(&self, buf: &[u8]) -> Result<bool, FieldError> {
257 self.fcf_raw(buf).map(fcf_security)
258 }
259
260 pub fn fcf_pending(&self, buf: &[u8]) -> Result<bool, FieldError> {
262 self.fcf_raw(buf).map(fcf_pending)
263 }
264
265 pub fn fcf_ackreq(&self, buf: &[u8]) -> Result<bool, FieldError> {
267 self.fcf_raw(buf).map(fcf_ackreq)
268 }
269
270 pub fn fcf_panidcompress(&self, buf: &[u8]) -> Result<bool, FieldError> {
272 self.fcf_raw(buf).map(fcf_panid_compress)
273 }
274
275 pub fn fcf_destaddrmode(&self, buf: &[u8]) -> Result<u8, FieldError> {
277 self.fcf_raw(buf).map(fcf_dest_addr_mode)
278 }
279
280 pub fn fcf_framever(&self, buf: &[u8]) -> Result<u8, FieldError> {
282 self.fcf_raw(buf).map(fcf_frame_ver)
283 }
284
285 pub fn fcf_srcaddrmode(&self, buf: &[u8]) -> Result<u8, FieldError> {
287 self.fcf_raw(buf).map(fcf_src_addr_mode)
288 }
289
290 pub fn seqnum(&self, buf: &[u8]) -> Result<u8, FieldError> {
296 let off = self.index.start + 2;
297 if buf.len() <= off {
298 return Err(FieldError::BufferTooShort {
299 offset: off,
300 need: 1,
301 have: buf.len().saturating_sub(off),
302 });
303 }
304 Ok(buf[off])
305 }
306
307 pub fn set_seqnum(&self, buf: &mut [u8], val: u8) -> Result<(), FieldError> {
309 let off = self.index.start + 2;
310 if buf.len() <= off {
311 return Err(FieldError::BufferTooShort {
312 offset: off,
313 need: 1,
314 have: buf.len().saturating_sub(off),
315 });
316 }
317 buf[off] = val;
318 Ok(())
319 }
320
321 fn dest_panid_offset(&self, buf: &[u8]) -> Result<Option<usize>, FieldError> {
328 let fcf = self.fcf_raw(buf)?;
329 let dest_mode = fcf_dest_addr_mode(fcf);
330 if dest_mode == types::addr_mode::NONE {
331 return Ok(None);
332 }
333 Ok(Some(addr_start(self.index.start)))
334 }
335
336 fn dest_addr_offset(&self, buf: &[u8]) -> Result<Option<usize>, FieldError> {
339 let fcf = self.fcf_raw(buf)?;
340 let dest_mode = fcf_dest_addr_mode(fcf);
341 if dest_mode == types::addr_mode::NONE {
342 return Ok(None);
343 }
344 Ok(Some(addr_start(self.index.start) + 2))
346 }
347
348 fn src_panid_offset(&self, buf: &[u8]) -> Result<Option<usize>, FieldError> {
351 let fcf = self.fcf_raw(buf)?;
352 let dest_mode = fcf_dest_addr_mode(fcf);
353 let src_mode = fcf_src_addr_mode(fcf);
354 let panid_compress = fcf_panid_compress(fcf);
355
356 if src_mode == types::addr_mode::NONE || panid_compress {
357 return Ok(None);
358 }
359
360 let mut off = addr_start(self.index.start);
361 if dest_mode != types::addr_mode::NONE {
362 off += 2 + types::addr_mode_len(dest_mode); }
364 Ok(Some(off))
365 }
366
367 fn src_addr_offset(&self, buf: &[u8]) -> Result<Option<usize>, FieldError> {
370 let fcf = self.fcf_raw(buf)?;
371 let dest_mode = fcf_dest_addr_mode(fcf);
372 let src_mode = fcf_src_addr_mode(fcf);
373 let panid_compress = fcf_panid_compress(fcf);
374
375 if src_mode == types::addr_mode::NONE {
376 return Ok(None);
377 }
378
379 let mut off = addr_start(self.index.start);
380 if dest_mode != types::addr_mode::NONE {
382 off += 2 + types::addr_mode_len(dest_mode);
383 }
384 if !panid_compress {
386 off += 2;
387 }
388 Ok(Some(off))
389 }
390
391 pub fn dest_panid(&self, buf: &[u8]) -> Result<Option<u16>, FieldError> {
398 match self.dest_panid_offset(buf)? {
399 Some(off) => read_u16_le(buf, off).map(Some),
400 None => Ok(None),
401 }
402 }
403
404 pub fn dest_addr_short(&self, buf: &[u8]) -> Result<Option<u16>, FieldError> {
407 let fcf = self.fcf_raw(buf)?;
408 if fcf_dest_addr_mode(fcf) != types::addr_mode::SHORT {
409 return Ok(None);
410 }
411 match self.dest_addr_offset(buf)? {
412 Some(off) => read_u16_le(buf, off).map(Some),
413 None => Ok(None),
414 }
415 }
416
417 pub fn dest_addr_long(&self, buf: &[u8]) -> Result<Option<u64>, FieldError> {
420 let fcf = self.fcf_raw(buf)?;
421 if fcf_dest_addr_mode(fcf) != types::addr_mode::LONG {
422 return Ok(None);
423 }
424 match self.dest_addr_offset(buf)? {
425 Some(off) => read_u64_le(buf, off).map(Some),
426 None => Ok(None),
427 }
428 }
429
430 pub fn src_panid(&self, buf: &[u8]) -> Result<Option<u16>, FieldError> {
433 match self.src_panid_offset(buf)? {
434 Some(off) => read_u16_le(buf, off).map(Some),
435 None => Ok(None),
436 }
437 }
438
439 pub fn src_addr_short(&self, buf: &[u8]) -> Result<Option<u16>, FieldError> {
442 let fcf = self.fcf_raw(buf)?;
443 if fcf_src_addr_mode(fcf) != types::addr_mode::SHORT {
444 return Ok(None);
445 }
446 match self.src_addr_offset(buf)? {
447 Some(off) => read_u16_le(buf, off).map(Some),
448 None => Ok(None),
449 }
450 }
451
452 pub fn src_addr_long(&self, buf: &[u8]) -> Result<Option<u64>, FieldError> {
455 let fcf = self.fcf_raw(buf)?;
456 if fcf_src_addr_mode(fcf) != types::addr_mode::LONG {
457 return Ok(None);
458 }
459 match self.src_addr_offset(buf)? {
460 Some(off) => read_u64_le(buf, off).map(Some),
461 None => Ok(None),
462 }
463 }
464
465 pub fn set_fcf_frametype(&self, buf: &mut [u8], val: u8) -> Result<(), FieldError> {
471 let mut fcf = self.fcf_raw(buf)?;
472 fcf = (fcf & !0x0007) | ((val as u16) & 0x07);
473 write_fcf(buf, self.index.start, fcf)
474 }
475
476 pub fn set_fcf_security(&self, buf: &mut [u8], val: bool) -> Result<(), FieldError> {
478 let mut fcf = self.fcf_raw(buf)?;
479 if val {
480 fcf |= 0x0008;
481 } else {
482 fcf &= !0x0008;
483 }
484 write_fcf(buf, self.index.start, fcf)
485 }
486
487 pub fn set_fcf_pending(&self, buf: &mut [u8], val: bool) -> Result<(), FieldError> {
489 let mut fcf = self.fcf_raw(buf)?;
490 if val {
491 fcf |= 0x0010;
492 } else {
493 fcf &= !0x0010;
494 }
495 write_fcf(buf, self.index.start, fcf)
496 }
497
498 pub fn set_fcf_ackreq(&self, buf: &mut [u8], val: bool) -> Result<(), FieldError> {
500 let mut fcf = self.fcf_raw(buf)?;
501 if val {
502 fcf |= 0x0020;
503 } else {
504 fcf &= !0x0020;
505 }
506 write_fcf(buf, self.index.start, fcf)
507 }
508
509 pub fn set_fcf_panidcompress(&self, buf: &mut [u8], val: bool) -> Result<(), FieldError> {
511 let mut fcf = self.fcf_raw(buf)?;
512 if val {
513 fcf |= 0x0040;
514 } else {
515 fcf &= !0x0040;
516 }
517 write_fcf(buf, self.index.start, fcf)
518 }
519
520 pub fn set_fcf_destaddrmode(&self, buf: &mut [u8], val: u8) -> Result<(), FieldError> {
522 let mut fcf = self.fcf_raw(buf)?;
523 fcf = (fcf & !0x0C00) | (((val as u16) & 0x03) << 10);
524 write_fcf(buf, self.index.start, fcf)
525 }
526
527 pub fn set_fcf_framever(&self, buf: &mut [u8], val: u8) -> Result<(), FieldError> {
529 let mut fcf = self.fcf_raw(buf)?;
530 fcf = (fcf & !0x3000) | (((val as u16) & 0x03) << 12);
531 write_fcf(buf, self.index.start, fcf)
532 }
533
534 pub fn set_fcf_srcaddrmode(&self, buf: &mut [u8], val: u8) -> Result<(), FieldError> {
536 let mut fcf = self.fcf_raw(buf)?;
537 fcf = (fcf & !0xC000) | (((val as u16) & 0x03) << 14);
538 write_fcf(buf, self.index.start, fcf)
539 }
540
541 pub fn set_dest_panid(&self, buf: &mut [u8], val: u16) -> Result<(), FieldError> {
547 match self.dest_panid_offset(buf)? {
548 Some(off) => write_u16_le(val, buf, off),
549 None => Err(FieldError::InvalidValue(
550 "dest_addr_mode is None, cannot set dest_panid".into(),
551 )),
552 }
553 }
554
555 pub fn set_dest_addr_short(&self, buf: &mut [u8], val: u16) -> Result<(), FieldError> {
557 let fcf = self.fcf_raw(buf)?;
558 if fcf_dest_addr_mode(fcf) != types::addr_mode::SHORT {
559 return Err(FieldError::InvalidValue(
560 "dest_addr_mode is not SHORT".into(),
561 ));
562 }
563 match self.dest_addr_offset(buf)? {
564 Some(off) => write_u16_le(val, buf, off),
565 None => Err(FieldError::InvalidValue("no dest address offset".into())),
566 }
567 }
568
569 pub fn set_dest_addr_long(&self, buf: &mut [u8], val: u64) -> Result<(), FieldError> {
571 let fcf = self.fcf_raw(buf)?;
572 if fcf_dest_addr_mode(fcf) != types::addr_mode::LONG {
573 return Err(FieldError::InvalidValue(
574 "dest_addr_mode is not LONG".into(),
575 ));
576 }
577 match self.dest_addr_offset(buf)? {
578 Some(off) => write_u64_le(val, buf, off),
579 None => Err(FieldError::InvalidValue("no dest address offset".into())),
580 }
581 }
582
583 pub fn set_src_panid(&self, buf: &mut [u8], val: u16) -> Result<(), FieldError> {
585 match self.src_panid_offset(buf)? {
586 Some(off) => write_u16_le(val, buf, off),
587 None => Err(FieldError::InvalidValue(
588 "src PAN ID not present (compressed or src_addr_mode is None)".into(),
589 )),
590 }
591 }
592
593 pub fn set_src_addr_short(&self, buf: &mut [u8], val: u16) -> Result<(), FieldError> {
595 let fcf = self.fcf_raw(buf)?;
596 if fcf_src_addr_mode(fcf) != types::addr_mode::SHORT {
597 return Err(FieldError::InvalidValue(
598 "src_addr_mode is not SHORT".into(),
599 ));
600 }
601 match self.src_addr_offset(buf)? {
602 Some(off) => write_u16_le(val, buf, off),
603 None => Err(FieldError::InvalidValue("no src address offset".into())),
604 }
605 }
606
607 pub fn set_src_addr_long(&self, buf: &mut [u8], val: u64) -> Result<(), FieldError> {
609 let fcf = self.fcf_raw(buf)?;
610 if fcf_src_addr_mode(fcf) != types::addr_mode::LONG {
611 return Err(FieldError::InvalidValue("src_addr_mode is not LONG".into()));
612 }
613 match self.src_addr_offset(buf)? {
614 Some(off) => write_u64_le(val, buf, off),
615 None => Err(FieldError::InvalidValue("no src address offset".into())),
616 }
617 }
618
619 pub fn get_field(&self, buf: &[u8], name: &str) -> Option<Result<FieldValue, FieldError>> {
625 match name {
626 "fcf_frametype" => Some(self.fcf_frametype(buf).map(FieldValue::U8)),
627 "fcf_security" => Some(self.fcf_security(buf).map(FieldValue::Bool)),
628 "fcf_pending" => Some(self.fcf_pending(buf).map(FieldValue::Bool)),
629 "fcf_ackreq" => Some(self.fcf_ackreq(buf).map(FieldValue::Bool)),
630 "fcf_panidcompress" => Some(self.fcf_panidcompress(buf).map(FieldValue::Bool)),
631 "fcf_destaddrmode" => Some(self.fcf_destaddrmode(buf).map(FieldValue::U8)),
632 "fcf_framever" => Some(self.fcf_framever(buf).map(FieldValue::U8)),
633 "fcf_srcaddrmode" => Some(self.fcf_srcaddrmode(buf).map(FieldValue::U8)),
634 "seqnum" => Some(self.seqnum(buf).map(FieldValue::U8)),
635 "dest_panid" => Some(
636 self.dest_panid(buf)
637 .map(|opt| opt.map(FieldValue::U16).unwrap_or(FieldValue::U16(0))),
638 ),
639 "dest_addr_short" => Some(
640 self.dest_addr_short(buf)
641 .map(|opt| opt.map(FieldValue::U16).unwrap_or(FieldValue::U16(0))),
642 ),
643 "dest_addr_long" => Some(
644 self.dest_addr_long(buf)
645 .map(|opt| opt.map(FieldValue::U64).unwrap_or(FieldValue::U64(0))),
646 ),
647 "src_panid" => Some(
648 self.src_panid(buf)
649 .map(|opt| opt.map(FieldValue::U16).unwrap_or(FieldValue::U16(0))),
650 ),
651 "src_addr_short" => Some(
652 self.src_addr_short(buf)
653 .map(|opt| opt.map(FieldValue::U16).unwrap_or(FieldValue::U16(0))),
654 ),
655 "src_addr_long" => Some(
656 self.src_addr_long(buf)
657 .map(|opt| opt.map(FieldValue::U64).unwrap_or(FieldValue::U64(0))),
658 ),
659 _ => None,
660 }
661 }
662
663 pub fn set_field(
665 &self,
666 buf: &mut [u8],
667 name: &str,
668 value: FieldValue,
669 ) -> Option<Result<(), FieldError>> {
670 match name {
671 "fcf_frametype" => Some(match value.as_u8() {
672 Some(v) => self.set_fcf_frametype(buf, v),
673 None => Err(FieldError::InvalidValue(
674 "expected u8 for fcf_frametype".into(),
675 )),
676 }),
677 "fcf_security" => Some(match value.as_bool() {
678 Some(v) => self.set_fcf_security(buf, v),
679 None => Err(FieldError::InvalidValue(
680 "expected bool for fcf_security".into(),
681 )),
682 }),
683 "fcf_pending" => Some(match value.as_bool() {
684 Some(v) => self.set_fcf_pending(buf, v),
685 None => Err(FieldError::InvalidValue(
686 "expected bool for fcf_pending".into(),
687 )),
688 }),
689 "fcf_ackreq" => Some(match value.as_bool() {
690 Some(v) => self.set_fcf_ackreq(buf, v),
691 None => Err(FieldError::InvalidValue(
692 "expected bool for fcf_ackreq".into(),
693 )),
694 }),
695 "fcf_panidcompress" => Some(match value.as_bool() {
696 Some(v) => self.set_fcf_panidcompress(buf, v),
697 None => Err(FieldError::InvalidValue(
698 "expected bool for fcf_panidcompress".into(),
699 )),
700 }),
701 "fcf_destaddrmode" => Some(match value.as_u8() {
702 Some(v) => self.set_fcf_destaddrmode(buf, v),
703 None => Err(FieldError::InvalidValue(
704 "expected u8 for fcf_destaddrmode".into(),
705 )),
706 }),
707 "fcf_framever" => Some(match value.as_u8() {
708 Some(v) => self.set_fcf_framever(buf, v),
709 None => Err(FieldError::InvalidValue(
710 "expected u8 for fcf_framever".into(),
711 )),
712 }),
713 "fcf_srcaddrmode" => Some(match value.as_u8() {
714 Some(v) => self.set_fcf_srcaddrmode(buf, v),
715 None => Err(FieldError::InvalidValue(
716 "expected u8 for fcf_srcaddrmode".into(),
717 )),
718 }),
719 "seqnum" => Some(match value.as_u8() {
720 Some(v) => self.set_seqnum(buf, v),
721 None => Err(FieldError::InvalidValue("expected u8 for seqnum".into())),
722 }),
723 "dest_panid" => Some(match value.as_u16() {
724 Some(v) => self.set_dest_panid(buf, v),
725 None => Err(FieldError::InvalidValue(
726 "expected u16 for dest_panid".into(),
727 )),
728 }),
729 "dest_addr_short" => Some(match value.as_u16() {
730 Some(v) => self.set_dest_addr_short(buf, v),
731 None => Err(FieldError::InvalidValue(
732 "expected u16 for dest_addr_short".into(),
733 )),
734 }),
735 "dest_addr_long" => Some(match value.as_u64() {
736 Some(v) => self.set_dest_addr_long(buf, v),
737 None => Err(FieldError::InvalidValue(
738 "expected u64 for dest_addr_long".into(),
739 )),
740 }),
741 "src_panid" => Some(match value.as_u16() {
742 Some(v) => self.set_src_panid(buf, v),
743 None => Err(FieldError::InvalidValue(
744 "expected u16 for src_panid".into(),
745 )),
746 }),
747 "src_addr_short" => Some(match value.as_u16() {
748 Some(v) => self.set_src_addr_short(buf, v),
749 None => Err(FieldError::InvalidValue(
750 "expected u16 for src_addr_short".into(),
751 )),
752 }),
753 "src_addr_long" => Some(match value.as_u64() {
754 Some(v) => self.set_src_addr_long(buf, v),
755 None => Err(FieldError::InvalidValue(
756 "expected u64 for src_addr_long".into(),
757 )),
758 }),
759 _ => None,
760 }
761 }
762
763 pub fn field_names() -> &'static [&'static str] {
765 DOT15D4_FIELDS
766 }
767
768 pub fn next_layer(&self, buf: &[u8]) -> Option<LayerKind> {
770 self.fcf_frametype(buf).ok().and_then(|ft| match ft {
771 types::frame_type::BEACON => None,
772 types::frame_type::DATA => Some(LayerKind::Raw),
773 types::frame_type::ACK => None,
774 types::frame_type::MAC_CMD => None,
775 _ => Some(LayerKind::Raw),
776 })
777 }
778
779 pub fn format_long_addr(addr: u64) -> String {
781 let bytes = addr.to_be_bytes();
782 format!(
783 "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
784 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]
785 )
786 }
787
788 pub fn hashret(&self, buf: &[u8]) -> Vec<u8> {
790 self.seqnum(buf).map(|s| vec![s]).unwrap_or_default()
791 }
792}
793
794impl Layer for Dot15d4Layer {
795 fn kind(&self) -> LayerKind {
796 LayerKind::Dot15d4
797 }
798
799 fn summary(&self, buf: &[u8]) -> String {
800 let ft = self.fcf_frametype(buf).unwrap_or(0);
801 let ackreq = self.fcf_ackreq(buf).unwrap_or(false);
802 let dest_mode = self.fcf_destaddrmode(buf).unwrap_or(0);
803 let src_mode = self.fcf_srcaddrmode(buf).unwrap_or(0);
804 let seq = self.seqnum(buf).unwrap_or(0);
805
806 format!(
807 "802.15.4 {} ackreq({}) ( {} -> {} ) Seq#{}",
808 types::frame_type_name(ft),
809 ackreq,
810 types::addr_mode_name(dest_mode),
811 types::addr_mode_name(src_mode),
812 seq,
813 )
814 }
815
816 fn header_len(&self, buf: &[u8]) -> usize {
817 match self.fcf_raw(buf) {
818 Ok(fcf) => {
819 let computed = compute_header_len(fcf);
820 let available = self.index.len();
821 computed.min(available)
822 }
823 Err(_) => DOT15D4_MIN_HEADER_LEN.min(self.index.len()),
824 }
825 }
826
827 fn hashret(&self, buf: &[u8]) -> Vec<u8> {
828 self.hashret(buf)
829 }
830
831 fn answers(&self, buf: &[u8], other: &Self, other_buf: &[u8]) -> bool {
832 if let (Ok(ft), Ok(seq), Ok(other_seq), Ok(other_ackreq)) = (
837 self.fcf_frametype(buf),
838 self.seqnum(buf),
839 other.seqnum(other_buf),
840 other.fcf_ackreq(other_buf),
841 ) {
842 if ft == types::frame_type::ACK && seq == other_seq && other_ackreq {
843 return true;
844 }
845 }
846 false
847 }
848
849 fn field_names(&self) -> &'static [&'static str] {
850 DOT15D4_FIELDS
851 }
852}
853
854#[derive(Debug, Clone)]
864pub struct Dot15d4FcsLayer {
865 pub index: LayerIndex,
866}
867
868impl Dot15d4FcsLayer {
869 pub fn new(start: usize, end: usize) -> Self {
871 Self {
872 index: LayerIndex::new(LayerKind::Dot15d4Fcs, start, end),
873 }
874 }
875
876 fn inner(&self) -> Dot15d4Layer {
878 Dot15d4Layer::new(self.index.start, self.index.end.saturating_sub(FCS_LEN))
879 }
880
881 pub fn fcs(&self, buf: &[u8]) -> Result<u16, FieldError> {
883 let slice = self.index.slice(buf);
884 if slice.len() < FCS_LEN {
885 return Err(FieldError::BufferTooShort {
886 offset: self.index.end.saturating_sub(FCS_LEN),
887 need: FCS_LEN,
888 have: slice.len(),
889 });
890 }
891 let fcs_offset = slice.len() - FCS_LEN;
892 Ok(u16::from_le_bytes([
893 slice[fcs_offset],
894 slice[fcs_offset + 1],
895 ]))
896 }
897
898 pub fn verify_fcs(&self, buf: &[u8]) -> Result<bool, FieldError> {
900 let slice = self.index.slice(buf);
901 if slice.len() < FCS_LEN + DOT15D4_MIN_HEADER_LEN {
902 return Err(FieldError::BufferTooShort {
903 offset: self.index.start,
904 need: DOT15D4_MIN_HEADER_LEN + FCS_LEN,
905 have: slice.len(),
906 });
907 }
908 let data = &slice[..slice.len() - FCS_LEN];
909 let expected = self.fcs(buf)?;
910 Ok(crc::verify_fcs(data, expected))
911 }
912
913 pub fn fcf_raw(&self, buf: &[u8]) -> Result<u16, FieldError> {
916 self.inner().fcf_raw(buf)
917 }
918
919 pub fn fcf_frametype(&self, buf: &[u8]) -> Result<u8, FieldError> {
920 self.inner().fcf_frametype(buf)
921 }
922
923 pub fn fcf_security(&self, buf: &[u8]) -> Result<bool, FieldError> {
924 self.inner().fcf_security(buf)
925 }
926
927 pub fn fcf_pending(&self, buf: &[u8]) -> Result<bool, FieldError> {
928 self.inner().fcf_pending(buf)
929 }
930
931 pub fn fcf_ackreq(&self, buf: &[u8]) -> Result<bool, FieldError> {
932 self.inner().fcf_ackreq(buf)
933 }
934
935 pub fn fcf_panidcompress(&self, buf: &[u8]) -> Result<bool, FieldError> {
936 self.inner().fcf_panidcompress(buf)
937 }
938
939 pub fn fcf_destaddrmode(&self, buf: &[u8]) -> Result<u8, FieldError> {
940 self.inner().fcf_destaddrmode(buf)
941 }
942
943 pub fn fcf_framever(&self, buf: &[u8]) -> Result<u8, FieldError> {
944 self.inner().fcf_framever(buf)
945 }
946
947 pub fn fcf_srcaddrmode(&self, buf: &[u8]) -> Result<u8, FieldError> {
948 self.inner().fcf_srcaddrmode(buf)
949 }
950
951 pub fn seqnum(&self, buf: &[u8]) -> Result<u8, FieldError> {
952 self.inner().seqnum(buf)
953 }
954
955 pub fn dest_panid(&self, buf: &[u8]) -> Result<Option<u16>, FieldError> {
956 self.inner().dest_panid(buf)
957 }
958
959 pub fn dest_addr_short(&self, buf: &[u8]) -> Result<Option<u16>, FieldError> {
960 self.inner().dest_addr_short(buf)
961 }
962
963 pub fn dest_addr_long(&self, buf: &[u8]) -> Result<Option<u64>, FieldError> {
964 self.inner().dest_addr_long(buf)
965 }
966
967 pub fn src_panid(&self, buf: &[u8]) -> Result<Option<u16>, FieldError> {
968 self.inner().src_panid(buf)
969 }
970
971 pub fn src_addr_short(&self, buf: &[u8]) -> Result<Option<u16>, FieldError> {
972 self.inner().src_addr_short(buf)
973 }
974
975 pub fn src_addr_long(&self, buf: &[u8]) -> Result<Option<u64>, FieldError> {
976 self.inner().src_addr_long(buf)
977 }
978
979 pub fn get_field(&self, buf: &[u8], name: &str) -> Option<Result<FieldValue, FieldError>> {
981 if name == "fcs" {
982 return Some(self.fcs(buf).map(FieldValue::U16));
983 }
984 self.inner().get_field(buf, name)
985 }
986
987 pub fn set_field(
989 &self,
990 buf: &mut [u8],
991 name: &str,
992 value: FieldValue,
993 ) -> Option<Result<(), FieldError>> {
994 if name == "fcs" {
996 return Some(Err(FieldError::InvalidValue(
997 "FCS is computed automatically, cannot set directly".into(),
998 )));
999 }
1000 self.inner().set_field(buf, name, value)
1001 }
1002
1003 pub fn field_names() -> &'static [&'static str] {
1005 DOT15D4_FCS_FIELDS
1006 }
1007
1008 pub fn hashret(&self, buf: &[u8]) -> Vec<u8> {
1010 self.inner().hashret(buf)
1011 }
1012}
1013
1014impl Layer for Dot15d4FcsLayer {
1015 fn kind(&self) -> LayerKind {
1016 LayerKind::Dot15d4Fcs
1017 }
1018
1019 fn summary(&self, buf: &[u8]) -> String {
1020 let inner_summary = self.inner().summary(buf);
1021 let fcs_str = self
1022 .fcs(buf)
1023 .map(|f| format!(" FCS={:#06x}", f))
1024 .unwrap_or_default();
1025 format!("{}{}", inner_summary, fcs_str)
1026 }
1027
1028 fn header_len(&self, buf: &[u8]) -> usize {
1029 let inner_len = self.inner().header_len(buf);
1031 let total = inner_len + FCS_LEN;
1032 total.min(self.index.len())
1033 }
1034
1035 fn hashret(&self, buf: &[u8]) -> Vec<u8> {
1036 self.hashret(buf)
1037 }
1038
1039 fn answers(&self, buf: &[u8], other: &Self, other_buf: &[u8]) -> bool {
1040 self.inner().answers(buf, &other.inner(), other_buf)
1041 }
1042
1043 fn field_names(&self) -> &'static [&'static str] {
1044 DOT15D4_FCS_FIELDS
1045 }
1046}
1047
1048#[cfg(test)]
1049mod tests {
1050 use super::*;
1051
1052 fn sample_data_frame_short() -> Vec<u8> {
1060 let mut buf = Vec::new();
1067 buf.extend_from_slice(&[0x61, 0x88]); buf.push(0x05); buf.extend_from_slice(&[0x34, 0x12]); buf.extend_from_slice(&[0xFF, 0xFF]); buf.extend_from_slice(&[0x01, 0x00]); buf
1073 }
1074
1075 fn sample_data_frame_long() -> Vec<u8> {
1077 let mut buf = Vec::new();
1082 buf.extend_from_slice(&[0x01, 0xCC]); buf.push(0x0A); buf.extend_from_slice(&[0x34, 0x12]); buf.extend_from_slice(&[0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01]); buf.extend_from_slice(&[0xCD, 0xAB]); buf.extend_from_slice(&[0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11]); buf
1089 }
1090
1091 fn sample_ack_frame() -> Vec<u8> {
1093 vec![0x02, 0x00, 0x05] }
1098
1099 #[test]
1100 fn test_fcf_helpers() {
1101 let fcf = build_fcf(1, false, false, true, true, 2, 0, 2);
1102 assert_eq!(fcf_frame_type(fcf), 1);
1103 assert!(!fcf_security(fcf));
1104 assert!(!fcf_pending(fcf));
1105 assert!(fcf_ackreq(fcf));
1106 assert!(fcf_panid_compress(fcf));
1107 assert_eq!(fcf_dest_addr_mode(fcf), 2);
1108 assert_eq!(fcf_frame_ver(fcf), 0);
1109 assert_eq!(fcf_src_addr_mode(fcf), 2);
1110 }
1111
1112 #[test]
1113 fn test_build_fcf_roundtrip() {
1114 for ft in 0..=5u8 {
1115 for dam in 0..=3u8 {
1116 for sam in 0..=3u8 {
1117 let fcf = build_fcf(ft, true, false, true, false, dam, 1, sam);
1118 assert_eq!(fcf_frame_type(fcf), ft);
1119 assert!(fcf_security(fcf));
1120 assert!(!fcf_pending(fcf));
1121 assert!(fcf_ackreq(fcf));
1122 assert!(!fcf_panid_compress(fcf));
1123 assert_eq!(fcf_dest_addr_mode(fcf), dam);
1124 assert_eq!(fcf_frame_ver(fcf), 1);
1125 assert_eq!(fcf_src_addr_mode(fcf), sam);
1126 }
1127 }
1128 }
1129 }
1130
1131 #[test]
1132 fn test_compute_header_len() {
1133 let fcf_ack = build_fcf(2, false, false, false, false, 0, 0, 0);
1135 assert_eq!(compute_header_len(fcf_ack), 3); let fcf_data = build_fcf(1, false, false, true, true, 2, 0, 2);
1139 assert_eq!(compute_header_len(fcf_data), 9);
1141
1142 let fcf_data2 = build_fcf(1, false, false, true, false, 2, 0, 2);
1144 assert_eq!(compute_header_len(fcf_data2), 11);
1146
1147 let fcf_data3 = build_fcf(1, false, false, false, true, 3, 0, 2);
1149 assert_eq!(compute_header_len(fcf_data3), 15);
1151
1152 let fcf_data4 = build_fcf(1, false, false, false, false, 3, 0, 3);
1154 assert_eq!(compute_header_len(fcf_data4), 23);
1156 }
1157
1158 #[test]
1159 fn test_parse_data_frame_short() {
1160 let buf = sample_data_frame_short();
1161 let layer = Dot15d4Layer::new(0, buf.len());
1162
1163 assert_eq!(layer.fcf_frametype(&buf).unwrap(), 1);
1164 assert!(!layer.fcf_security(&buf).unwrap());
1165 assert!(!layer.fcf_pending(&buf).unwrap());
1166 assert!(layer.fcf_ackreq(&buf).unwrap());
1167 assert!(layer.fcf_panidcompress(&buf).unwrap());
1168 assert_eq!(layer.fcf_destaddrmode(&buf).unwrap(), 2);
1169 assert_eq!(layer.fcf_framever(&buf).unwrap(), 0);
1170 assert_eq!(layer.fcf_srcaddrmode(&buf).unwrap(), 2);
1171 assert_eq!(layer.seqnum(&buf).unwrap(), 0x05);
1172
1173 assert_eq!(layer.dest_panid(&buf).unwrap(), Some(0x1234));
1174 assert_eq!(layer.dest_addr_short(&buf).unwrap(), Some(0xFFFF));
1175 assert_eq!(layer.dest_addr_long(&buf).unwrap(), None);
1176
1177 assert_eq!(layer.src_panid(&buf).unwrap(), None);
1179 assert_eq!(layer.src_addr_short(&buf).unwrap(), Some(0x0001));
1180 assert_eq!(layer.src_addr_long(&buf).unwrap(), None);
1181
1182 assert_eq!(layer.header_len(&buf), 9);
1184 }
1185
1186 #[test]
1187 fn test_parse_data_frame_long() {
1188 let buf = sample_data_frame_long();
1189 let layer = Dot15d4Layer::new(0, buf.len());
1190
1191 assert_eq!(layer.fcf_frametype(&buf).unwrap(), 1);
1192 assert_eq!(layer.fcf_destaddrmode(&buf).unwrap(), 3);
1193 assert_eq!(layer.fcf_srcaddrmode(&buf).unwrap(), 3);
1194 assert!(!layer.fcf_panidcompress(&buf).unwrap());
1195 assert_eq!(layer.seqnum(&buf).unwrap(), 0x0A);
1196
1197 assert_eq!(layer.dest_panid(&buf).unwrap(), Some(0x1234));
1198 assert_eq!(
1199 layer.dest_addr_long(&buf).unwrap(),
1200 Some(0x0102030405060708)
1201 );
1202 assert_eq!(layer.dest_addr_short(&buf).unwrap(), None);
1203
1204 assert_eq!(layer.src_panid(&buf).unwrap(), Some(0xABCD));
1205 assert_eq!(layer.src_addr_long(&buf).unwrap(), Some(0x1112131415161718));
1206 assert_eq!(layer.src_addr_short(&buf).unwrap(), None);
1207
1208 assert_eq!(layer.header_len(&buf), 23);
1210 }
1211
1212 #[test]
1213 fn test_parse_ack_frame() {
1214 let buf = sample_ack_frame();
1215 let layer = Dot15d4Layer::new(0, buf.len());
1216
1217 assert_eq!(layer.fcf_frametype(&buf).unwrap(), 2);
1218 assert_eq!(layer.fcf_destaddrmode(&buf).unwrap(), 0);
1219 assert_eq!(layer.fcf_srcaddrmode(&buf).unwrap(), 0);
1220 assert_eq!(layer.seqnum(&buf).unwrap(), 0x05);
1221
1222 assert_eq!(layer.dest_panid(&buf).unwrap(), None);
1223 assert_eq!(layer.dest_addr_short(&buf).unwrap(), None);
1224 assert_eq!(layer.src_panid(&buf).unwrap(), None);
1225 assert_eq!(layer.src_addr_short(&buf).unwrap(), None);
1226
1227 assert_eq!(layer.header_len(&buf), 3);
1228 }
1229
1230 #[test]
1231 fn test_ack_answers() {
1232 let data_buf = sample_data_frame_short();
1233 let data_layer = Dot15d4Layer::new(0, data_buf.len());
1234
1235 let ack_buf = sample_ack_frame();
1237 let ack_layer = Dot15d4Layer::new(0, ack_buf.len());
1238
1239 assert!(ack_layer.answers(&ack_buf, &data_layer, &data_buf));
1240 }
1241
1242 #[test]
1243 fn test_ack_does_not_answer_wrong_seq() {
1244 let data_buf = sample_data_frame_short(); let data_layer = Dot15d4Layer::new(0, data_buf.len());
1246
1247 let mut ack_buf = sample_ack_frame();
1249 ack_buf[2] = 0x06; let ack_layer = Dot15d4Layer::new(0, ack_buf.len());
1251
1252 assert!(!ack_layer.answers(&ack_buf, &data_layer, &data_buf));
1253 }
1254
1255 #[test]
1256 fn test_summary() {
1257 let buf = sample_data_frame_short();
1258 let layer = Dot15d4Layer::new(0, buf.len());
1259 let summary = layer.summary(&buf);
1260 assert!(summary.contains("Data"));
1261 assert!(summary.contains("ackreq(true)"));
1262 assert!(summary.contains("Short"));
1263 assert!(summary.contains("Seq#5"));
1264 }
1265
1266 #[test]
1267 fn test_get_field() {
1268 let buf = sample_data_frame_short();
1269 let layer = Dot15d4Layer::new(0, buf.len());
1270
1271 let ft = layer.get_field(&buf, "fcf_frametype").unwrap().unwrap();
1272 assert_eq!(ft, FieldValue::U8(1));
1273
1274 let seq = layer.get_field(&buf, "seqnum").unwrap().unwrap();
1275 assert_eq!(seq, FieldValue::U8(5));
1276
1277 let dp = layer.get_field(&buf, "dest_panid").unwrap().unwrap();
1278 assert_eq!(dp, FieldValue::U16(0x1234));
1279
1280 assert!(layer.get_field(&buf, "nonexistent").is_none());
1281 }
1282
1283 #[test]
1284 fn test_set_field() {
1285 let mut buf = sample_data_frame_short();
1286 let layer = Dot15d4Layer::new(0, buf.len());
1287
1288 layer
1289 .set_field(&mut buf, "seqnum", FieldValue::U8(42))
1290 .unwrap()
1291 .unwrap();
1292 assert_eq!(layer.seqnum(&buf).unwrap(), 42);
1293
1294 layer
1295 .set_field(&mut buf, "fcf_ackreq", FieldValue::Bool(false))
1296 .unwrap()
1297 .unwrap();
1298 assert!(!layer.fcf_ackreq(&buf).unwrap());
1299 }
1300
1301 #[test]
1302 fn test_set_dest_panid() {
1303 let mut buf = sample_data_frame_short();
1304 let layer = Dot15d4Layer::new(0, buf.len());
1305
1306 layer.set_dest_panid(&mut buf, 0xABCD).unwrap();
1307 assert_eq!(layer.dest_panid(&buf).unwrap(), Some(0xABCD));
1308 }
1309
1310 #[test]
1311 fn test_set_dest_addr_short() {
1312 let mut buf = sample_data_frame_short();
1313 let layer = Dot15d4Layer::new(0, buf.len());
1314
1315 layer.set_dest_addr_short(&mut buf, 0x1234).unwrap();
1316 assert_eq!(layer.dest_addr_short(&buf).unwrap(), Some(0x1234));
1317 }
1318
1319 #[test]
1320 fn test_set_src_addr_short() {
1321 let mut buf = sample_data_frame_short();
1322 let layer = Dot15d4Layer::new(0, buf.len());
1323
1324 layer.set_src_addr_short(&mut buf, 0x5678).unwrap();
1325 assert_eq!(layer.src_addr_short(&buf).unwrap(), Some(0x5678));
1326 }
1327
1328 #[test]
1329 fn test_fcs_layer_basic() {
1330 let mut frame = sample_data_frame_short();
1331 let fcs = crc::compute_fcs(&frame);
1333 frame.extend_from_slice(&fcs);
1334
1335 let layer = Dot15d4FcsLayer::new(0, frame.len());
1336 assert_eq!(layer.fcf_frametype(&frame).unwrap(), 1);
1337 assert_eq!(layer.seqnum(&frame).unwrap(), 0x05);
1338 assert!(layer.verify_fcs(&frame).unwrap());
1339 }
1340
1341 #[test]
1342 fn test_fcs_layer_corrupted() {
1343 let mut frame = sample_data_frame_short();
1344 frame.extend_from_slice(&[0x00, 0x00]);
1346
1347 let layer = Dot15d4FcsLayer::new(0, frame.len());
1348 assert!(!layer.verify_fcs(&frame).unwrap());
1349 }
1350
1351 #[test]
1352 fn test_fcs_layer_get_field() {
1353 let mut frame = sample_data_frame_short();
1354 let fcs_val = crc::crc_ccitt_kermit(&frame);
1355 let fcs_bytes = fcs_val.to_le_bytes();
1356 frame.extend_from_slice(&fcs_bytes);
1357
1358 let layer = Dot15d4FcsLayer::new(0, frame.len());
1359 let fcs = layer.get_field(&frame, "fcs").unwrap().unwrap();
1360 assert_eq!(fcs, FieldValue::U16(fcs_val));
1361
1362 let seq = layer.get_field(&frame, "seqnum").unwrap().unwrap();
1364 assert_eq!(seq, FieldValue::U8(5));
1365 }
1366
1367 #[test]
1368 fn test_fcs_layer_summary() {
1369 let mut frame = sample_data_frame_short();
1370 let fcs_bytes = crc::compute_fcs(&frame);
1371 frame.extend_from_slice(&fcs_bytes);
1372
1373 let layer = Dot15d4FcsLayer::new(0, frame.len());
1374 let summary = layer.summary(&frame);
1375 assert!(summary.contains("802.15.4"));
1376 assert!(summary.contains("FCS="));
1377 }
1378
1379 #[test]
1380 fn test_format_long_addr() {
1381 let addr: u64 = 0x0102030405060708;
1382 let formatted = Dot15d4Layer::format_long_addr(addr);
1383 assert_eq!(formatted, "01:02:03:04:05:06:07:08");
1384 }
1385
1386 #[test]
1387 fn test_validate() {
1388 assert!(Dot15d4Layer::validate(&[0x00, 0x00, 0x00], 0).is_ok());
1389 assert!(Dot15d4Layer::validate(&[0x00, 0x00], 0).is_err());
1390 assert!(Dot15d4Layer::validate(&[0x00, 0x00, 0x00], 1).is_err());
1391 }
1392
1393 #[test]
1394 fn test_field_names() {
1395 let names = Dot15d4Layer::field_names();
1396 assert!(names.contains(&"fcf_frametype"));
1397 assert!(names.contains(&"seqnum"));
1398 assert!(names.contains(&"dest_panid"));
1399 assert!(names.contains(&"src_addr_long"));
1400 }
1401
1402 #[test]
1403 fn test_fcs_field_names() {
1404 let names = Dot15d4FcsLayer::field_names();
1405 assert!(names.contains(&"fcs"));
1406 assert!(names.contains(&"fcf_frametype"));
1407 }
1408
1409 #[test]
1410 fn test_fcf_writers() {
1411 let mut buf = sample_data_frame_short();
1412 let layer = Dot15d4Layer::new(0, buf.len());
1413
1414 layer.set_fcf_frametype(&mut buf, 0).unwrap();
1416 assert_eq!(layer.fcf_frametype(&buf).unwrap(), 0);
1417
1418 layer.set_fcf_security(&mut buf, true).unwrap();
1420 assert!(layer.fcf_security(&buf).unwrap());
1421
1422 layer.set_fcf_pending(&mut buf, true).unwrap();
1424 assert!(layer.fcf_pending(&buf).unwrap());
1425
1426 layer.set_fcf_framever(&mut buf, 1).unwrap();
1428 assert_eq!(layer.fcf_framever(&buf).unwrap(), 1);
1429
1430 assert!(layer.fcf_ackreq(&buf).unwrap());
1432 assert!(layer.fcf_panidcompress(&buf).unwrap());
1433 assert_eq!(layer.fcf_destaddrmode(&buf).unwrap(), 2);
1434 assert_eq!(layer.fcf_srcaddrmode(&buf).unwrap(), 2);
1435 }
1436}