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]
91#[must_use]
92pub fn fcf_frame_type(fcf: u16) -> u8 {
93 (fcf & 0x0007) as u8
94}
95
96#[inline]
98#[must_use]
99pub fn fcf_security(fcf: u16) -> bool {
100 (fcf & 0x0008) != 0
101}
102
103#[inline]
105#[must_use]
106pub fn fcf_pending(fcf: u16) -> bool {
107 (fcf & 0x0010) != 0
108}
109
110#[inline]
112#[must_use]
113pub fn fcf_ackreq(fcf: u16) -> bool {
114 (fcf & 0x0020) != 0
115}
116
117#[inline]
119#[must_use]
120pub fn fcf_panid_compress(fcf: u16) -> bool {
121 (fcf & 0x0040) != 0
122}
123
124#[inline]
126#[must_use]
127pub fn fcf_dest_addr_mode(fcf: u16) -> u8 {
128 ((fcf >> 10) & 0x03) as u8
129}
130
131#[inline]
133#[must_use]
134pub fn fcf_frame_ver(fcf: u16) -> u8 {
135 ((fcf >> 12) & 0x03) as u8
136}
137
138#[inline]
140#[must_use]
141pub fn fcf_src_addr_mode(fcf: u16) -> u8 {
142 ((fcf >> 14) & 0x03) as u8
143}
144
145#[must_use]
147pub fn build_fcf(
148 frame_type: u8,
149 security: bool,
150 pending: bool,
151 ackreq: bool,
152 panid_compress: bool,
153 dest_addr_mode: u8,
154 frame_ver: u8,
155 src_addr_mode: u8,
156) -> u16 {
157 let mut fcf: u16 = 0;
158 fcf |= u16::from(frame_type) & 0x07;
159 if security {
160 fcf |= 0x0008;
161 }
162 if pending {
163 fcf |= 0x0010;
164 }
165 if ackreq {
166 fcf |= 0x0020;
167 }
168 if panid_compress {
169 fcf |= 0x0040;
170 }
171 fcf |= (u16::from(dest_addr_mode) & 0x03) << 10;
173 fcf |= (u16::from(frame_ver) & 0x03) << 12;
174 fcf |= (u16::from(src_addr_mode) & 0x03) << 14;
175 fcf
176}
177
178#[must_use]
188pub fn compute_header_len(fcf: u16) -> usize {
189 let mut len = DOT15D4_MIN_HEADER_LEN; let dest_mode = fcf_dest_addr_mode(fcf);
191 let src_mode = fcf_src_addr_mode(fcf);
192 let panid_compress = fcf_panid_compress(fcf);
193
194 if dest_mode != types::addr_mode::NONE {
196 len += 2; len += types::addr_mode_len(dest_mode);
198 }
199
200 if src_mode != types::addr_mode::NONE {
202 if !panid_compress {
203 len += 2; }
205 len += types::addr_mode_len(src_mode);
206 }
207
208 len
209}
210
211#[inline]
213fn addr_start(start: usize) -> usize {
214 start + DOT15D4_MIN_HEADER_LEN
215}
216
217#[derive(Debug, Clone)]
226pub struct Dot15d4Layer {
227 pub index: LayerIndex,
228}
229
230impl Dot15d4Layer {
231 #[must_use]
233 pub fn new(start: usize, end: usize) -> Self {
234 Self {
235 index: LayerIndex::new(LayerKind::Dot15d4, start, end),
236 }
237 }
238
239 pub fn validate(buf: &[u8], offset: usize) -> Result<(), FieldError> {
241 if buf.len() < offset + DOT15D4_MIN_HEADER_LEN {
242 return Err(FieldError::BufferTooShort {
243 offset,
244 need: DOT15D4_MIN_HEADER_LEN,
245 have: buf.len().saturating_sub(offset),
246 });
247 }
248 Ok(())
249 }
250
251 #[inline]
257 pub fn fcf_raw(&self, buf: &[u8]) -> Result<u16, FieldError> {
258 read_fcf(buf, self.index.start)
259 }
260
261 pub fn fcf_frametype(&self, buf: &[u8]) -> Result<u8, FieldError> {
263 self.fcf_raw(buf).map(fcf_frame_type)
264 }
265
266 pub fn fcf_security(&self, buf: &[u8]) -> Result<bool, FieldError> {
268 self.fcf_raw(buf).map(fcf_security)
269 }
270
271 pub fn fcf_pending(&self, buf: &[u8]) -> Result<bool, FieldError> {
273 self.fcf_raw(buf).map(fcf_pending)
274 }
275
276 pub fn fcf_ackreq(&self, buf: &[u8]) -> Result<bool, FieldError> {
278 self.fcf_raw(buf).map(fcf_ackreq)
279 }
280
281 pub fn fcf_panidcompress(&self, buf: &[u8]) -> Result<bool, FieldError> {
283 self.fcf_raw(buf).map(fcf_panid_compress)
284 }
285
286 pub fn fcf_destaddrmode(&self, buf: &[u8]) -> Result<u8, FieldError> {
288 self.fcf_raw(buf).map(fcf_dest_addr_mode)
289 }
290
291 pub fn fcf_framever(&self, buf: &[u8]) -> Result<u8, FieldError> {
293 self.fcf_raw(buf).map(fcf_frame_ver)
294 }
295
296 pub fn fcf_srcaddrmode(&self, buf: &[u8]) -> Result<u8, FieldError> {
298 self.fcf_raw(buf).map(fcf_src_addr_mode)
299 }
300
301 pub fn seqnum(&self, buf: &[u8]) -> Result<u8, FieldError> {
307 let off = self.index.start + 2;
308 if buf.len() <= off {
309 return Err(FieldError::BufferTooShort {
310 offset: off,
311 need: 1,
312 have: buf.len().saturating_sub(off),
313 });
314 }
315 Ok(buf[off])
316 }
317
318 pub fn set_seqnum(&self, buf: &mut [u8], val: u8) -> Result<(), FieldError> {
320 let off = self.index.start + 2;
321 if buf.len() <= off {
322 return Err(FieldError::BufferTooShort {
323 offset: off,
324 need: 1,
325 have: buf.len().saturating_sub(off),
326 });
327 }
328 buf[off] = val;
329 Ok(())
330 }
331
332 fn dest_panid_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)))
345 }
346
347 fn dest_addr_offset(&self, buf: &[u8]) -> Result<Option<usize>, FieldError> {
350 let fcf = self.fcf_raw(buf)?;
351 let dest_mode = fcf_dest_addr_mode(fcf);
352 if dest_mode == types::addr_mode::NONE {
353 return Ok(None);
354 }
355 Ok(Some(addr_start(self.index.start) + 2))
357 }
358
359 fn src_panid_offset(&self, buf: &[u8]) -> Result<Option<usize>, FieldError> {
362 let fcf = self.fcf_raw(buf)?;
363 let dest_mode = fcf_dest_addr_mode(fcf);
364 let src_mode = fcf_src_addr_mode(fcf);
365 let panid_compress = fcf_panid_compress(fcf);
366
367 if src_mode == types::addr_mode::NONE || panid_compress {
368 return Ok(None);
369 }
370
371 let mut off = addr_start(self.index.start);
372 if dest_mode != types::addr_mode::NONE {
373 off += 2 + types::addr_mode_len(dest_mode); }
375 Ok(Some(off))
376 }
377
378 fn src_addr_offset(&self, buf: &[u8]) -> Result<Option<usize>, FieldError> {
381 let fcf = self.fcf_raw(buf)?;
382 let dest_mode = fcf_dest_addr_mode(fcf);
383 let src_mode = fcf_src_addr_mode(fcf);
384 let panid_compress = fcf_panid_compress(fcf);
385
386 if src_mode == types::addr_mode::NONE {
387 return Ok(None);
388 }
389
390 let mut off = addr_start(self.index.start);
391 if dest_mode != types::addr_mode::NONE {
393 off += 2 + types::addr_mode_len(dest_mode);
394 }
395 if !panid_compress {
397 off += 2;
398 }
399 Ok(Some(off))
400 }
401
402 pub fn dest_panid(&self, buf: &[u8]) -> Result<Option<u16>, FieldError> {
409 match self.dest_panid_offset(buf)? {
410 Some(off) => read_u16_le(buf, off).map(Some),
411 None => Ok(None),
412 }
413 }
414
415 pub fn dest_addr_short(&self, buf: &[u8]) -> Result<Option<u16>, FieldError> {
418 let fcf = self.fcf_raw(buf)?;
419 if fcf_dest_addr_mode(fcf) != types::addr_mode::SHORT {
420 return Ok(None);
421 }
422 match self.dest_addr_offset(buf)? {
423 Some(off) => read_u16_le(buf, off).map(Some),
424 None => Ok(None),
425 }
426 }
427
428 pub fn dest_addr_long(&self, buf: &[u8]) -> Result<Option<u64>, FieldError> {
431 let fcf = self.fcf_raw(buf)?;
432 if fcf_dest_addr_mode(fcf) != types::addr_mode::LONG {
433 return Ok(None);
434 }
435 match self.dest_addr_offset(buf)? {
436 Some(off) => read_u64_le(buf, off).map(Some),
437 None => Ok(None),
438 }
439 }
440
441 pub fn src_panid(&self, buf: &[u8]) -> Result<Option<u16>, FieldError> {
444 match self.src_panid_offset(buf)? {
445 Some(off) => read_u16_le(buf, off).map(Some),
446 None => Ok(None),
447 }
448 }
449
450 pub fn src_addr_short(&self, buf: &[u8]) -> Result<Option<u16>, FieldError> {
453 let fcf = self.fcf_raw(buf)?;
454 if fcf_src_addr_mode(fcf) != types::addr_mode::SHORT {
455 return Ok(None);
456 }
457 match self.src_addr_offset(buf)? {
458 Some(off) => read_u16_le(buf, off).map(Some),
459 None => Ok(None),
460 }
461 }
462
463 pub fn src_addr_long(&self, buf: &[u8]) -> Result<Option<u64>, FieldError> {
466 let fcf = self.fcf_raw(buf)?;
467 if fcf_src_addr_mode(fcf) != types::addr_mode::LONG {
468 return Ok(None);
469 }
470 match self.src_addr_offset(buf)? {
471 Some(off) => read_u64_le(buf, off).map(Some),
472 None => Ok(None),
473 }
474 }
475
476 pub fn set_fcf_frametype(&self, buf: &mut [u8], val: u8) -> Result<(), FieldError> {
482 let mut fcf = self.fcf_raw(buf)?;
483 fcf = (fcf & !0x0007) | (u16::from(val) & 0x07);
484 write_fcf(buf, self.index.start, fcf)
485 }
486
487 pub fn set_fcf_security(&self, buf: &mut [u8], val: bool) -> Result<(), FieldError> {
489 let mut fcf = self.fcf_raw(buf)?;
490 if val {
491 fcf |= 0x0008;
492 } else {
493 fcf &= !0x0008;
494 }
495 write_fcf(buf, self.index.start, fcf)
496 }
497
498 pub fn set_fcf_pending(&self, buf: &mut [u8], val: bool) -> Result<(), FieldError> {
500 let mut fcf = self.fcf_raw(buf)?;
501 if val {
502 fcf |= 0x0010;
503 } else {
504 fcf &= !0x0010;
505 }
506 write_fcf(buf, self.index.start, fcf)
507 }
508
509 pub fn set_fcf_ackreq(&self, buf: &mut [u8], val: bool) -> Result<(), FieldError> {
511 let mut fcf = self.fcf_raw(buf)?;
512 if val {
513 fcf |= 0x0020;
514 } else {
515 fcf &= !0x0020;
516 }
517 write_fcf(buf, self.index.start, fcf)
518 }
519
520 pub fn set_fcf_panidcompress(&self, buf: &mut [u8], val: bool) -> Result<(), FieldError> {
522 let mut fcf = self.fcf_raw(buf)?;
523 if val {
524 fcf |= 0x0040;
525 } else {
526 fcf &= !0x0040;
527 }
528 write_fcf(buf, self.index.start, fcf)
529 }
530
531 pub fn set_fcf_destaddrmode(&self, buf: &mut [u8], val: u8) -> Result<(), FieldError> {
533 let mut fcf = self.fcf_raw(buf)?;
534 fcf = (fcf & !0x0C00) | ((u16::from(val) & 0x03) << 10);
535 write_fcf(buf, self.index.start, fcf)
536 }
537
538 pub fn set_fcf_framever(&self, buf: &mut [u8], val: u8) -> Result<(), FieldError> {
540 let mut fcf = self.fcf_raw(buf)?;
541 fcf = (fcf & !0x3000) | ((u16::from(val) & 0x03) << 12);
542 write_fcf(buf, self.index.start, fcf)
543 }
544
545 pub fn set_fcf_srcaddrmode(&self, buf: &mut [u8], val: u8) -> Result<(), FieldError> {
547 let mut fcf = self.fcf_raw(buf)?;
548 fcf = (fcf & !0xC000) | ((u16::from(val) & 0x03) << 14);
549 write_fcf(buf, self.index.start, fcf)
550 }
551
552 pub fn set_dest_panid(&self, buf: &mut [u8], val: u16) -> Result<(), FieldError> {
558 match self.dest_panid_offset(buf)? {
559 Some(off) => write_u16_le(val, buf, off),
560 None => Err(FieldError::InvalidValue(
561 "dest_addr_mode is None, cannot set dest_panid".into(),
562 )),
563 }
564 }
565
566 pub fn set_dest_addr_short(&self, buf: &mut [u8], val: u16) -> Result<(), FieldError> {
568 let fcf = self.fcf_raw(buf)?;
569 if fcf_dest_addr_mode(fcf) != types::addr_mode::SHORT {
570 return Err(FieldError::InvalidValue(
571 "dest_addr_mode is not SHORT".into(),
572 ));
573 }
574 match self.dest_addr_offset(buf)? {
575 Some(off) => write_u16_le(val, buf, off),
576 None => Err(FieldError::InvalidValue("no dest address offset".into())),
577 }
578 }
579
580 pub fn set_dest_addr_long(&self, buf: &mut [u8], val: u64) -> Result<(), FieldError> {
582 let fcf = self.fcf_raw(buf)?;
583 if fcf_dest_addr_mode(fcf) != types::addr_mode::LONG {
584 return Err(FieldError::InvalidValue(
585 "dest_addr_mode is not LONG".into(),
586 ));
587 }
588 match self.dest_addr_offset(buf)? {
589 Some(off) => write_u64_le(val, buf, off),
590 None => Err(FieldError::InvalidValue("no dest address offset".into())),
591 }
592 }
593
594 pub fn set_src_panid(&self, buf: &mut [u8], val: u16) -> Result<(), FieldError> {
596 match self.src_panid_offset(buf)? {
597 Some(off) => write_u16_le(val, buf, off),
598 None => Err(FieldError::InvalidValue(
599 "src PAN ID not present (compressed or src_addr_mode is None)".into(),
600 )),
601 }
602 }
603
604 pub fn set_src_addr_short(&self, buf: &mut [u8], val: u16) -> Result<(), FieldError> {
606 let fcf = self.fcf_raw(buf)?;
607 if fcf_src_addr_mode(fcf) != types::addr_mode::SHORT {
608 return Err(FieldError::InvalidValue(
609 "src_addr_mode is not SHORT".into(),
610 ));
611 }
612 match self.src_addr_offset(buf)? {
613 Some(off) => write_u16_le(val, buf, off),
614 None => Err(FieldError::InvalidValue("no src address offset".into())),
615 }
616 }
617
618 pub fn set_src_addr_long(&self, buf: &mut [u8], val: u64) -> Result<(), FieldError> {
620 let fcf = self.fcf_raw(buf)?;
621 if fcf_src_addr_mode(fcf) != types::addr_mode::LONG {
622 return Err(FieldError::InvalidValue("src_addr_mode is not LONG".into()));
623 }
624 match self.src_addr_offset(buf)? {
625 Some(off) => write_u64_le(val, buf, off),
626 None => Err(FieldError::InvalidValue("no src address offset".into())),
627 }
628 }
629
630 pub fn get_field(&self, buf: &[u8], name: &str) -> Option<Result<FieldValue, FieldError>> {
636 match name {
637 "fcf_frametype" => Some(self.fcf_frametype(buf).map(FieldValue::U8)),
638 "fcf_security" => Some(self.fcf_security(buf).map(FieldValue::Bool)),
639 "fcf_pending" => Some(self.fcf_pending(buf).map(FieldValue::Bool)),
640 "fcf_ackreq" => Some(self.fcf_ackreq(buf).map(FieldValue::Bool)),
641 "fcf_panidcompress" => Some(self.fcf_panidcompress(buf).map(FieldValue::Bool)),
642 "fcf_destaddrmode" => Some(self.fcf_destaddrmode(buf).map(FieldValue::U8)),
643 "fcf_framever" => Some(self.fcf_framever(buf).map(FieldValue::U8)),
644 "fcf_srcaddrmode" => Some(self.fcf_srcaddrmode(buf).map(FieldValue::U8)),
645 "seqnum" => Some(self.seqnum(buf).map(FieldValue::U8)),
646 "dest_panid" => Some(
647 self.dest_panid(buf)
648 .map(|opt| opt.map_or(FieldValue::U16(0), FieldValue::U16)),
649 ),
650 "dest_addr_short" => Some(
651 self.dest_addr_short(buf)
652 .map(|opt| opt.map_or(FieldValue::U16(0), FieldValue::U16)),
653 ),
654 "dest_addr_long" => Some(
655 self.dest_addr_long(buf)
656 .map(|opt| opt.map_or(FieldValue::U64(0), FieldValue::U64)),
657 ),
658 "src_panid" => Some(
659 self.src_panid(buf)
660 .map(|opt| opt.map_or(FieldValue::U16(0), FieldValue::U16)),
661 ),
662 "src_addr_short" => Some(
663 self.src_addr_short(buf)
664 .map(|opt| opt.map_or(FieldValue::U16(0), FieldValue::U16)),
665 ),
666 "src_addr_long" => Some(
667 self.src_addr_long(buf)
668 .map(|opt| opt.map_or(FieldValue::U64(0), FieldValue::U64)),
669 ),
670 _ => None,
671 }
672 }
673
674 pub fn set_field(
676 &self,
677 buf: &mut [u8],
678 name: &str,
679 value: FieldValue,
680 ) -> Option<Result<(), FieldError>> {
681 match name {
682 "fcf_frametype" => Some(match value.as_u8() {
683 Some(v) => self.set_fcf_frametype(buf, v),
684 None => Err(FieldError::InvalidValue(
685 "expected u8 for fcf_frametype".into(),
686 )),
687 }),
688 "fcf_security" => Some(match value.as_bool() {
689 Some(v) => self.set_fcf_security(buf, v),
690 None => Err(FieldError::InvalidValue(
691 "expected bool for fcf_security".into(),
692 )),
693 }),
694 "fcf_pending" => Some(match value.as_bool() {
695 Some(v) => self.set_fcf_pending(buf, v),
696 None => Err(FieldError::InvalidValue(
697 "expected bool for fcf_pending".into(),
698 )),
699 }),
700 "fcf_ackreq" => Some(match value.as_bool() {
701 Some(v) => self.set_fcf_ackreq(buf, v),
702 None => Err(FieldError::InvalidValue(
703 "expected bool for fcf_ackreq".into(),
704 )),
705 }),
706 "fcf_panidcompress" => Some(match value.as_bool() {
707 Some(v) => self.set_fcf_panidcompress(buf, v),
708 None => Err(FieldError::InvalidValue(
709 "expected bool for fcf_panidcompress".into(),
710 )),
711 }),
712 "fcf_destaddrmode" => Some(match value.as_u8() {
713 Some(v) => self.set_fcf_destaddrmode(buf, v),
714 None => Err(FieldError::InvalidValue(
715 "expected u8 for fcf_destaddrmode".into(),
716 )),
717 }),
718 "fcf_framever" => Some(match value.as_u8() {
719 Some(v) => self.set_fcf_framever(buf, v),
720 None => Err(FieldError::InvalidValue(
721 "expected u8 for fcf_framever".into(),
722 )),
723 }),
724 "fcf_srcaddrmode" => Some(match value.as_u8() {
725 Some(v) => self.set_fcf_srcaddrmode(buf, v),
726 None => Err(FieldError::InvalidValue(
727 "expected u8 for fcf_srcaddrmode".into(),
728 )),
729 }),
730 "seqnum" => Some(match value.as_u8() {
731 Some(v) => self.set_seqnum(buf, v),
732 None => Err(FieldError::InvalidValue("expected u8 for seqnum".into())),
733 }),
734 "dest_panid" => Some(match value.as_u16() {
735 Some(v) => self.set_dest_panid(buf, v),
736 None => Err(FieldError::InvalidValue(
737 "expected u16 for dest_panid".into(),
738 )),
739 }),
740 "dest_addr_short" => Some(match value.as_u16() {
741 Some(v) => self.set_dest_addr_short(buf, v),
742 None => Err(FieldError::InvalidValue(
743 "expected u16 for dest_addr_short".into(),
744 )),
745 }),
746 "dest_addr_long" => Some(match value.as_u64() {
747 Some(v) => self.set_dest_addr_long(buf, v),
748 None => Err(FieldError::InvalidValue(
749 "expected u64 for dest_addr_long".into(),
750 )),
751 }),
752 "src_panid" => Some(match value.as_u16() {
753 Some(v) => self.set_src_panid(buf, v),
754 None => Err(FieldError::InvalidValue(
755 "expected u16 for src_panid".into(),
756 )),
757 }),
758 "src_addr_short" => Some(match value.as_u16() {
759 Some(v) => self.set_src_addr_short(buf, v),
760 None => Err(FieldError::InvalidValue(
761 "expected u16 for src_addr_short".into(),
762 )),
763 }),
764 "src_addr_long" => Some(match value.as_u64() {
765 Some(v) => self.set_src_addr_long(buf, v),
766 None => Err(FieldError::InvalidValue(
767 "expected u64 for src_addr_long".into(),
768 )),
769 }),
770 _ => None,
771 }
772 }
773
774 #[must_use]
776 pub fn field_names() -> &'static [&'static str] {
777 DOT15D4_FIELDS
778 }
779
780 #[must_use]
782 pub fn next_layer(&self, buf: &[u8]) -> Option<LayerKind> {
783 self.fcf_frametype(buf).ok().and_then(|ft| match ft {
784 types::frame_type::BEACON => None,
785 types::frame_type::DATA => Some(LayerKind::Raw),
786 types::frame_type::ACK => None,
787 types::frame_type::MAC_CMD => None,
788 _ => Some(LayerKind::Raw),
789 })
790 }
791
792 #[must_use]
794 pub fn format_long_addr(addr: u64) -> String {
795 let bytes = addr.to_be_bytes();
796 format!(
797 "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
798 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]
799 )
800 }
801
802 #[must_use]
804 pub fn hashret(&self, buf: &[u8]) -> Vec<u8> {
805 self.seqnum(buf).map(|s| vec![s]).unwrap_or_default()
806 }
807}
808
809impl Layer for Dot15d4Layer {
810 fn kind(&self) -> LayerKind {
811 LayerKind::Dot15d4
812 }
813
814 fn summary(&self, buf: &[u8]) -> String {
815 let ft = self.fcf_frametype(buf).unwrap_or(0);
816 let ackreq = self.fcf_ackreq(buf).unwrap_or(false);
817 let dest_mode = self.fcf_destaddrmode(buf).unwrap_or(0);
818 let src_mode = self.fcf_srcaddrmode(buf).unwrap_or(0);
819 let seq = self.seqnum(buf).unwrap_or(0);
820
821 format!(
822 "802.15.4 {} ackreq({}) ( {} -> {} ) Seq#{}",
823 types::frame_type_name(ft),
824 ackreq,
825 types::addr_mode_name(dest_mode),
826 types::addr_mode_name(src_mode),
827 seq,
828 )
829 }
830
831 fn header_len(&self, buf: &[u8]) -> usize {
832 match self.fcf_raw(buf) {
833 Ok(fcf) => {
834 let computed = compute_header_len(fcf);
835 let available = self.index.len();
836 computed.min(available)
837 },
838 Err(_) => DOT15D4_MIN_HEADER_LEN.min(self.index.len()),
839 }
840 }
841
842 fn hashret(&self, buf: &[u8]) -> Vec<u8> {
843 self.hashret(buf)
844 }
845
846 fn answers(&self, buf: &[u8], other: &Self, other_buf: &[u8]) -> bool {
847 if let (Ok(ft), Ok(seq), Ok(other_seq), Ok(other_ackreq)) = (
852 self.fcf_frametype(buf),
853 self.seqnum(buf),
854 other.seqnum(other_buf),
855 other.fcf_ackreq(other_buf),
856 ) && ft == types::frame_type::ACK
857 && seq == other_seq
858 && other_ackreq
859 {
860 return true;
861 }
862 false
863 }
864
865 fn field_names(&self) -> &'static [&'static str] {
866 DOT15D4_FIELDS
867 }
868}
869
870#[derive(Debug, Clone)]
880pub struct Dot15d4FcsLayer {
881 pub index: LayerIndex,
882}
883
884impl Dot15d4FcsLayer {
885 #[must_use]
887 pub fn new(start: usize, end: usize) -> Self {
888 Self {
889 index: LayerIndex::new(LayerKind::Dot15d4Fcs, start, end),
890 }
891 }
892
893 fn inner(&self) -> Dot15d4Layer {
895 Dot15d4Layer::new(self.index.start, self.index.end.saturating_sub(FCS_LEN))
896 }
897
898 pub fn fcs(&self, buf: &[u8]) -> Result<u16, FieldError> {
900 let slice = self.index.slice(buf);
901 if slice.len() < FCS_LEN {
902 return Err(FieldError::BufferTooShort {
903 offset: self.index.end.saturating_sub(FCS_LEN),
904 need: FCS_LEN,
905 have: slice.len(),
906 });
907 }
908 let fcs_offset = slice.len() - FCS_LEN;
909 Ok(u16::from_le_bytes([
910 slice[fcs_offset],
911 slice[fcs_offset + 1],
912 ]))
913 }
914
915 pub fn verify_fcs(&self, buf: &[u8]) -> Result<bool, FieldError> {
917 let slice = self.index.slice(buf);
918 if slice.len() < FCS_LEN + DOT15D4_MIN_HEADER_LEN {
919 return Err(FieldError::BufferTooShort {
920 offset: self.index.start,
921 need: DOT15D4_MIN_HEADER_LEN + FCS_LEN,
922 have: slice.len(),
923 });
924 }
925 let data = &slice[..slice.len() - FCS_LEN];
926 let expected = self.fcs(buf)?;
927 Ok(crc::verify_fcs(data, expected))
928 }
929
930 pub fn fcf_raw(&self, buf: &[u8]) -> Result<u16, FieldError> {
933 self.inner().fcf_raw(buf)
934 }
935
936 pub fn fcf_frametype(&self, buf: &[u8]) -> Result<u8, FieldError> {
937 self.inner().fcf_frametype(buf)
938 }
939
940 pub fn fcf_security(&self, buf: &[u8]) -> Result<bool, FieldError> {
941 self.inner().fcf_security(buf)
942 }
943
944 pub fn fcf_pending(&self, buf: &[u8]) -> Result<bool, FieldError> {
945 self.inner().fcf_pending(buf)
946 }
947
948 pub fn fcf_ackreq(&self, buf: &[u8]) -> Result<bool, FieldError> {
949 self.inner().fcf_ackreq(buf)
950 }
951
952 pub fn fcf_panidcompress(&self, buf: &[u8]) -> Result<bool, FieldError> {
953 self.inner().fcf_panidcompress(buf)
954 }
955
956 pub fn fcf_destaddrmode(&self, buf: &[u8]) -> Result<u8, FieldError> {
957 self.inner().fcf_destaddrmode(buf)
958 }
959
960 pub fn fcf_framever(&self, buf: &[u8]) -> Result<u8, FieldError> {
961 self.inner().fcf_framever(buf)
962 }
963
964 pub fn fcf_srcaddrmode(&self, buf: &[u8]) -> Result<u8, FieldError> {
965 self.inner().fcf_srcaddrmode(buf)
966 }
967
968 pub fn seqnum(&self, buf: &[u8]) -> Result<u8, FieldError> {
969 self.inner().seqnum(buf)
970 }
971
972 pub fn dest_panid(&self, buf: &[u8]) -> Result<Option<u16>, FieldError> {
973 self.inner().dest_panid(buf)
974 }
975
976 pub fn dest_addr_short(&self, buf: &[u8]) -> Result<Option<u16>, FieldError> {
977 self.inner().dest_addr_short(buf)
978 }
979
980 pub fn dest_addr_long(&self, buf: &[u8]) -> Result<Option<u64>, FieldError> {
981 self.inner().dest_addr_long(buf)
982 }
983
984 pub fn src_panid(&self, buf: &[u8]) -> Result<Option<u16>, FieldError> {
985 self.inner().src_panid(buf)
986 }
987
988 pub fn src_addr_short(&self, buf: &[u8]) -> Result<Option<u16>, FieldError> {
989 self.inner().src_addr_short(buf)
990 }
991
992 pub fn src_addr_long(&self, buf: &[u8]) -> Result<Option<u64>, FieldError> {
993 self.inner().src_addr_long(buf)
994 }
995
996 pub fn get_field(&self, buf: &[u8], name: &str) -> Option<Result<FieldValue, FieldError>> {
998 if name == "fcs" {
999 return Some(self.fcs(buf).map(FieldValue::U16));
1000 }
1001 self.inner().get_field(buf, name)
1002 }
1003
1004 pub fn set_field(
1006 &self,
1007 buf: &mut [u8],
1008 name: &str,
1009 value: FieldValue,
1010 ) -> Option<Result<(), FieldError>> {
1011 if name == "fcs" {
1013 return Some(Err(FieldError::InvalidValue(
1014 "FCS is computed automatically, cannot set directly".into(),
1015 )));
1016 }
1017 self.inner().set_field(buf, name, value)
1018 }
1019
1020 #[must_use]
1022 pub fn field_names() -> &'static [&'static str] {
1023 DOT15D4_FCS_FIELDS
1024 }
1025
1026 #[must_use]
1028 pub fn hashret(&self, buf: &[u8]) -> Vec<u8> {
1029 self.inner().hashret(buf)
1030 }
1031}
1032
1033impl Layer for Dot15d4FcsLayer {
1034 fn kind(&self) -> LayerKind {
1035 LayerKind::Dot15d4Fcs
1036 }
1037
1038 fn summary(&self, buf: &[u8]) -> String {
1039 let inner_summary = self.inner().summary(buf);
1040 let fcs_str = self
1041 .fcs(buf)
1042 .map(|f| format!(" FCS={f:#06x}"))
1043 .unwrap_or_default();
1044 format!("{inner_summary}{fcs_str}")
1045 }
1046
1047 fn header_len(&self, buf: &[u8]) -> usize {
1048 let inner_len = self.inner().header_len(buf);
1050 let total = inner_len + FCS_LEN;
1051 total.min(self.index.len())
1052 }
1053
1054 fn hashret(&self, buf: &[u8]) -> Vec<u8> {
1055 self.hashret(buf)
1056 }
1057
1058 fn answers(&self, buf: &[u8], other: &Self, other_buf: &[u8]) -> bool {
1059 self.inner().answers(buf, &other.inner(), other_buf)
1060 }
1061
1062 fn field_names(&self) -> &'static [&'static str] {
1063 DOT15D4_FCS_FIELDS
1064 }
1065}
1066
1067#[cfg(test)]
1068mod tests {
1069 use super::*;
1070
1071 fn sample_data_frame_short() -> Vec<u8> {
1079 let mut buf = Vec::new();
1086 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
1092 }
1093
1094 fn sample_data_frame_long() -> Vec<u8> {
1096 let mut buf = Vec::new();
1101 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
1108 }
1109
1110 fn sample_ack_frame() -> Vec<u8> {
1112 vec![0x02, 0x00, 0x05] }
1117
1118 #[test]
1119 fn test_fcf_helpers() {
1120 let fcf = build_fcf(1, false, false, true, true, 2, 0, 2);
1121 assert_eq!(fcf_frame_type(fcf), 1);
1122 assert!(!fcf_security(fcf));
1123 assert!(!fcf_pending(fcf));
1124 assert!(fcf_ackreq(fcf));
1125 assert!(fcf_panid_compress(fcf));
1126 assert_eq!(fcf_dest_addr_mode(fcf), 2);
1127 assert_eq!(fcf_frame_ver(fcf), 0);
1128 assert_eq!(fcf_src_addr_mode(fcf), 2);
1129 }
1130
1131 #[test]
1132 fn test_build_fcf_roundtrip() {
1133 for ft in 0..=5u8 {
1134 for dam in 0..=3u8 {
1135 for sam in 0..=3u8 {
1136 let fcf = build_fcf(ft, true, false, true, false, dam, 1, sam);
1137 assert_eq!(fcf_frame_type(fcf), ft);
1138 assert!(fcf_security(fcf));
1139 assert!(!fcf_pending(fcf));
1140 assert!(fcf_ackreq(fcf));
1141 assert!(!fcf_panid_compress(fcf));
1142 assert_eq!(fcf_dest_addr_mode(fcf), dam);
1143 assert_eq!(fcf_frame_ver(fcf), 1);
1144 assert_eq!(fcf_src_addr_mode(fcf), sam);
1145 }
1146 }
1147 }
1148 }
1149
1150 #[test]
1151 fn test_compute_header_len() {
1152 let fcf_ack = build_fcf(2, false, false, false, false, 0, 0, 0);
1154 assert_eq!(compute_header_len(fcf_ack), 3); let fcf_data = build_fcf(1, false, false, true, true, 2, 0, 2);
1158 assert_eq!(compute_header_len(fcf_data), 9);
1160
1161 let fcf_data2 = build_fcf(1, false, false, true, false, 2, 0, 2);
1163 assert_eq!(compute_header_len(fcf_data2), 11);
1165
1166 let fcf_data3 = build_fcf(1, false, false, false, true, 3, 0, 2);
1168 assert_eq!(compute_header_len(fcf_data3), 15);
1170
1171 let fcf_data4 = build_fcf(1, false, false, false, false, 3, 0, 3);
1173 assert_eq!(compute_header_len(fcf_data4), 23);
1175 }
1176
1177 #[test]
1178 fn test_parse_data_frame_short() {
1179 let buf = sample_data_frame_short();
1180 let layer = Dot15d4Layer::new(0, buf.len());
1181
1182 assert_eq!(layer.fcf_frametype(&buf).unwrap(), 1);
1183 assert!(!layer.fcf_security(&buf).unwrap());
1184 assert!(!layer.fcf_pending(&buf).unwrap());
1185 assert!(layer.fcf_ackreq(&buf).unwrap());
1186 assert!(layer.fcf_panidcompress(&buf).unwrap());
1187 assert_eq!(layer.fcf_destaddrmode(&buf).unwrap(), 2);
1188 assert_eq!(layer.fcf_framever(&buf).unwrap(), 0);
1189 assert_eq!(layer.fcf_srcaddrmode(&buf).unwrap(), 2);
1190 assert_eq!(layer.seqnum(&buf).unwrap(), 0x05);
1191
1192 assert_eq!(layer.dest_panid(&buf).unwrap(), Some(0x1234));
1193 assert_eq!(layer.dest_addr_short(&buf).unwrap(), Some(0xFFFF));
1194 assert_eq!(layer.dest_addr_long(&buf).unwrap(), None);
1195
1196 assert_eq!(layer.src_panid(&buf).unwrap(), None);
1198 assert_eq!(layer.src_addr_short(&buf).unwrap(), Some(0x0001));
1199 assert_eq!(layer.src_addr_long(&buf).unwrap(), None);
1200
1201 assert_eq!(layer.header_len(&buf), 9);
1203 }
1204
1205 #[test]
1206 fn test_parse_data_frame_long() {
1207 let buf = sample_data_frame_long();
1208 let layer = Dot15d4Layer::new(0, buf.len());
1209
1210 assert_eq!(layer.fcf_frametype(&buf).unwrap(), 1);
1211 assert_eq!(layer.fcf_destaddrmode(&buf).unwrap(), 3);
1212 assert_eq!(layer.fcf_srcaddrmode(&buf).unwrap(), 3);
1213 assert!(!layer.fcf_panidcompress(&buf).unwrap());
1214 assert_eq!(layer.seqnum(&buf).unwrap(), 0x0A);
1215
1216 assert_eq!(layer.dest_panid(&buf).unwrap(), Some(0x1234));
1217 assert_eq!(
1218 layer.dest_addr_long(&buf).unwrap(),
1219 Some(0x0102030405060708)
1220 );
1221 assert_eq!(layer.dest_addr_short(&buf).unwrap(), None);
1222
1223 assert_eq!(layer.src_panid(&buf).unwrap(), Some(0xABCD));
1224 assert_eq!(layer.src_addr_long(&buf).unwrap(), Some(0x1112131415161718));
1225 assert_eq!(layer.src_addr_short(&buf).unwrap(), None);
1226
1227 assert_eq!(layer.header_len(&buf), 23);
1229 }
1230
1231 #[test]
1232 fn test_parse_ack_frame() {
1233 let buf = sample_ack_frame();
1234 let layer = Dot15d4Layer::new(0, buf.len());
1235
1236 assert_eq!(layer.fcf_frametype(&buf).unwrap(), 2);
1237 assert_eq!(layer.fcf_destaddrmode(&buf).unwrap(), 0);
1238 assert_eq!(layer.fcf_srcaddrmode(&buf).unwrap(), 0);
1239 assert_eq!(layer.seqnum(&buf).unwrap(), 0x05);
1240
1241 assert_eq!(layer.dest_panid(&buf).unwrap(), None);
1242 assert_eq!(layer.dest_addr_short(&buf).unwrap(), None);
1243 assert_eq!(layer.src_panid(&buf).unwrap(), None);
1244 assert_eq!(layer.src_addr_short(&buf).unwrap(), None);
1245
1246 assert_eq!(layer.header_len(&buf), 3);
1247 }
1248
1249 #[test]
1250 fn test_ack_answers() {
1251 let data_buf = sample_data_frame_short();
1252 let data_layer = Dot15d4Layer::new(0, data_buf.len());
1253
1254 let ack_buf = sample_ack_frame();
1256 let ack_layer = Dot15d4Layer::new(0, ack_buf.len());
1257
1258 assert!(ack_layer.answers(&ack_buf, &data_layer, &data_buf));
1259 }
1260
1261 #[test]
1262 fn test_ack_does_not_answer_wrong_seq() {
1263 let data_buf = sample_data_frame_short(); let data_layer = Dot15d4Layer::new(0, data_buf.len());
1265
1266 let mut ack_buf = sample_ack_frame();
1268 ack_buf[2] = 0x06; let ack_layer = Dot15d4Layer::new(0, ack_buf.len());
1270
1271 assert!(!ack_layer.answers(&ack_buf, &data_layer, &data_buf));
1272 }
1273
1274 #[test]
1275 fn test_summary() {
1276 let buf = sample_data_frame_short();
1277 let layer = Dot15d4Layer::new(0, buf.len());
1278 let summary = layer.summary(&buf);
1279 assert!(summary.contains("Data"));
1280 assert!(summary.contains("ackreq(true)"));
1281 assert!(summary.contains("Short"));
1282 assert!(summary.contains("Seq#5"));
1283 }
1284
1285 #[test]
1286 fn test_get_field() {
1287 let buf = sample_data_frame_short();
1288 let layer = Dot15d4Layer::new(0, buf.len());
1289
1290 let ft = layer.get_field(&buf, "fcf_frametype").unwrap().unwrap();
1291 assert_eq!(ft, FieldValue::U8(1));
1292
1293 let seq = layer.get_field(&buf, "seqnum").unwrap().unwrap();
1294 assert_eq!(seq, FieldValue::U8(5));
1295
1296 let dp = layer.get_field(&buf, "dest_panid").unwrap().unwrap();
1297 assert_eq!(dp, FieldValue::U16(0x1234));
1298
1299 assert!(layer.get_field(&buf, "nonexistent").is_none());
1300 }
1301
1302 #[test]
1303 fn test_set_field() {
1304 let mut buf = sample_data_frame_short();
1305 let layer = Dot15d4Layer::new(0, buf.len());
1306
1307 layer
1308 .set_field(&mut buf, "seqnum", FieldValue::U8(42))
1309 .unwrap()
1310 .unwrap();
1311 assert_eq!(layer.seqnum(&buf).unwrap(), 42);
1312
1313 layer
1314 .set_field(&mut buf, "fcf_ackreq", FieldValue::Bool(false))
1315 .unwrap()
1316 .unwrap();
1317 assert!(!layer.fcf_ackreq(&buf).unwrap());
1318 }
1319
1320 #[test]
1321 fn test_set_dest_panid() {
1322 let mut buf = sample_data_frame_short();
1323 let layer = Dot15d4Layer::new(0, buf.len());
1324
1325 layer.set_dest_panid(&mut buf, 0xABCD).unwrap();
1326 assert_eq!(layer.dest_panid(&buf).unwrap(), Some(0xABCD));
1327 }
1328
1329 #[test]
1330 fn test_set_dest_addr_short() {
1331 let mut buf = sample_data_frame_short();
1332 let layer = Dot15d4Layer::new(0, buf.len());
1333
1334 layer.set_dest_addr_short(&mut buf, 0x1234).unwrap();
1335 assert_eq!(layer.dest_addr_short(&buf).unwrap(), Some(0x1234));
1336 }
1337
1338 #[test]
1339 fn test_set_src_addr_short() {
1340 let mut buf = sample_data_frame_short();
1341 let layer = Dot15d4Layer::new(0, buf.len());
1342
1343 layer.set_src_addr_short(&mut buf, 0x5678).unwrap();
1344 assert_eq!(layer.src_addr_short(&buf).unwrap(), Some(0x5678));
1345 }
1346
1347 #[test]
1348 fn test_fcs_layer_basic() {
1349 let mut frame = sample_data_frame_short();
1350 let fcs = crc::compute_fcs(&frame);
1352 frame.extend_from_slice(&fcs);
1353
1354 let layer = Dot15d4FcsLayer::new(0, frame.len());
1355 assert_eq!(layer.fcf_frametype(&frame).unwrap(), 1);
1356 assert_eq!(layer.seqnum(&frame).unwrap(), 0x05);
1357 assert!(layer.verify_fcs(&frame).unwrap());
1358 }
1359
1360 #[test]
1361 fn test_fcs_layer_corrupted() {
1362 let mut frame = sample_data_frame_short();
1363 frame.extend_from_slice(&[0x00, 0x00]);
1365
1366 let layer = Dot15d4FcsLayer::new(0, frame.len());
1367 assert!(!layer.verify_fcs(&frame).unwrap());
1368 }
1369
1370 #[test]
1371 fn test_fcs_layer_get_field() {
1372 let mut frame = sample_data_frame_short();
1373 let fcs_val = crc::crc_ccitt_kermit(&frame);
1374 let fcs_bytes = fcs_val.to_le_bytes();
1375 frame.extend_from_slice(&fcs_bytes);
1376
1377 let layer = Dot15d4FcsLayer::new(0, frame.len());
1378 let fcs = layer.get_field(&frame, "fcs").unwrap().unwrap();
1379 assert_eq!(fcs, FieldValue::U16(fcs_val));
1380
1381 let seq = layer.get_field(&frame, "seqnum").unwrap().unwrap();
1383 assert_eq!(seq, FieldValue::U8(5));
1384 }
1385
1386 #[test]
1387 fn test_fcs_layer_summary() {
1388 let mut frame = sample_data_frame_short();
1389 let fcs_bytes = crc::compute_fcs(&frame);
1390 frame.extend_from_slice(&fcs_bytes);
1391
1392 let layer = Dot15d4FcsLayer::new(0, frame.len());
1393 let summary = layer.summary(&frame);
1394 assert!(summary.contains("802.15.4"));
1395 assert!(summary.contains("FCS="));
1396 }
1397
1398 #[test]
1399 fn test_format_long_addr() {
1400 let addr: u64 = 0x0102030405060708;
1401 let formatted = Dot15d4Layer::format_long_addr(addr);
1402 assert_eq!(formatted, "01:02:03:04:05:06:07:08");
1403 }
1404
1405 #[test]
1406 fn test_validate() {
1407 assert!(Dot15d4Layer::validate(&[0x00, 0x00, 0x00], 0).is_ok());
1408 assert!(Dot15d4Layer::validate(&[0x00, 0x00], 0).is_err());
1409 assert!(Dot15d4Layer::validate(&[0x00, 0x00, 0x00], 1).is_err());
1410 }
1411
1412 #[test]
1413 fn test_field_names() {
1414 let names = Dot15d4Layer::field_names();
1415 assert!(names.contains(&"fcf_frametype"));
1416 assert!(names.contains(&"seqnum"));
1417 assert!(names.contains(&"dest_panid"));
1418 assert!(names.contains(&"src_addr_long"));
1419 }
1420
1421 #[test]
1422 fn test_fcs_field_names() {
1423 let names = Dot15d4FcsLayer::field_names();
1424 assert!(names.contains(&"fcs"));
1425 assert!(names.contains(&"fcf_frametype"));
1426 }
1427
1428 #[test]
1429 fn test_fcf_writers() {
1430 let mut buf = sample_data_frame_short();
1431 let layer = Dot15d4Layer::new(0, buf.len());
1432
1433 layer.set_fcf_frametype(&mut buf, 0).unwrap();
1435 assert_eq!(layer.fcf_frametype(&buf).unwrap(), 0);
1436
1437 layer.set_fcf_security(&mut buf, true).unwrap();
1439 assert!(layer.fcf_security(&buf).unwrap());
1440
1441 layer.set_fcf_pending(&mut buf, true).unwrap();
1443 assert!(layer.fcf_pending(&buf).unwrap());
1444
1445 layer.set_fcf_framever(&mut buf, 1).unwrap();
1447 assert_eq!(layer.fcf_framever(&buf).unwrap(), 1);
1448
1449 assert!(layer.fcf_ackreq(&buf).unwrap());
1451 assert!(layer.fcf_panidcompress(&buf).unwrap());
1452 assert_eq!(layer.fcf_destaddrmode(&buf).unwrap(), 2);
1453 assert_eq!(layer.fcf_srcaddrmode(&buf).unwrap(), 2);
1454 }
1455}