1use core::cmp;
16#[cfg(feature = "alloc")]
17use core::convert::TryFrom;
18#[cfg(feature = "alloc")]
19use core::iter::FromIterator;
20use core::iter::Iterator;
21#[cfg(feature = "alloc")]
22use core::{mem, slice};
23
24use crate::layers::dev_traits::*;
25use crate::layers::traits::*;
26use crate::layers::*;
27use crate::utils;
28use crate::writer::PacketWritable;
29
30use bitflags::bitflags;
31
32#[cfg(feature = "alloc")]
33use pkts_macros::Layer;
34use pkts_macros::{LayerRef, StatelessLayer};
35
36#[cfg(all(not(feature = "std"), feature = "alloc"))]
37use alloc::boxed::Box;
38#[cfg(all(not(feature = "std"), feature = "alloc"))]
39use alloc::vec::Vec;
40
41const CHUNK_TYPE_DATA: u8 = 0;
43const CHUNK_TYPE_INIT: u8 = 1;
44const CHUNK_TYPE_INIT_ACK: u8 = 2;
45const CHUNK_TYPE_SACK: u8 = 3;
46const CHUNK_TYPE_HEARTBEAT: u8 = 4;
47const CHUNK_TYPE_HEARTBEAT_ACK: u8 = 5;
48const CHUNK_TYPE_ABORT: u8 = 6;
49const CHUNK_TYPE_SHUTDOWN: u8 = 7;
50const CHUNK_TYPE_SHUTDOWN_ACK: u8 = 8;
51const CHUNK_TYPE_ERROR: u8 = 9;
52const CHUNK_TYPE_COOKIE_ECHO: u8 = 10;
53const CHUNK_TYPE_COOKIE_ACK: u8 = 11;
54const CHUNK_TYPE_SHUTDOWN_COMPLETE: u8 = 14;
55
56const INIT_OPT_IPV4_ADDRESS: u16 = 5;
58const INIT_OPT_IPV6_ADDRESS: u16 = 6;
59const INIT_OPT_COOKIE_PRESERVATIVE: u16 = 9;
60const INIT_OPT_HOSTNAME_ADDR: u16 = 11;
61const INIT_OPT_SUPP_ADDR_TYPES: u16 = 12;
62
63const INIT_ACK_OPT_STATE_COOKIE: u16 = 7;
65const INIT_ACK_OPT_IPV4_ADDRESS: u16 = 5;
66const INIT_ACK_OPT_IPV6_ADDRESS: u16 = 6;
67const INIT_ACK_OPT_UNRECOGNIZED_PARAM: u16 = 8;
68const INIT_ACK_OPT_HOSTNAME_ADDR: u16 = 11;
69
70const ERR_CODE_INVALID_STREAM_ID: u16 = 1;
72const ERR_CODE_MISSING_MAND_PARAM: u16 = 2;
73const ERR_CODE_STALE_COOKIE: u16 = 3;
74const ERR_CODE_OUT_OF_RESOURCE: u16 = 4;
75const ERR_CODE_UNRESOLVABLE_ADDRESS: u16 = 5;
76const ERR_CODE_UNRECOGNIZED_CHUNK: u16 = 6;
77const ERR_CODE_INVALID_MAND_PARAM: u16 = 7;
78const ERR_CODE_UNRECOGNIZED_PARAMS: u16 = 8;
79const ERR_CODE_NO_USER_DATA: u16 = 9;
80const ERR_CODE_COOKIE_RCVD_SHUTTING_DOWN: u16 = 10;
81const ERR_CODE_RESTART_ASSOC_NEW_ADDR: u16 = 11;
82const ERR_CODE_USER_INITIATED_ABORT: u16 = 12;
83const ERR_CODE_PROTOCOL_VIOLATION: u16 = 13;
84
85#[derive(Clone, Debug, Layer, StatelessLayer)]
104#[metadata_type(TcpMetadata)]
105#[ref_type(SctpRef)]
106#[cfg(feature = "alloc")]
107pub struct Sctp {
108 sport: u16,
109 dport: u16,
110 verify_tag: u32,
111 chksum: Option<u32>,
112 control_chunks: Vec<SctpControlChunk>,
113 payload_chunks: Vec<Box<dyn LayerObject>>,
114}
115
116#[cfg(feature = "alloc")]
117impl Sctp {
118 #[inline]
120 pub fn sport(&self) -> u16 {
121 self.sport
122 }
123
124 #[inline]
126 pub fn set_sport(&mut self, sport: u16) {
127 self.sport = sport;
128 }
129
130 #[inline]
132 pub fn dport(&self) -> u16 {
133 self.dport
134 }
135
136 #[inline]
138 pub fn set_dport(&mut self, dport: u16) {
139 self.dport = dport;
140 }
141
142 #[inline]
146 pub fn verify_tag(&self) -> u32 {
147 self.verify_tag
148 }
149
150 #[inline]
152 pub fn set_verify_tag(&mut self, verify_tag: u32) {
153 self.verify_tag = verify_tag;
154 }
155
156 #[inline]
166 pub fn chksum(&self) -> Option<u32> {
167 self.chksum
168 }
169
170 #[inline]
181 pub fn set_chksum(&mut self, chksum: u32) {
182 self.chksum = Some(chksum);
183 }
184
185 #[inline]
194 pub fn clear_chksum(&mut self) {
195 self.chksum = None;
196 }
197
198 #[inline]
200 pub fn generate_chksum(&mut self) {
201 todo!() }
203
204 #[inline]
218 pub fn control_chunks(&self) -> &Vec<SctpControlChunk> {
219 &self.control_chunks
220 }
221
222 #[inline]
237 pub fn control_chunks_mut(&mut self) -> &mut Vec<SctpControlChunk> {
238 &mut self.control_chunks
239 }
240
241 }
278
279#[cfg(feature = "alloc")]
280#[doc(hidden)]
281impl FromBytesCurrent for Sctp {
282 fn from_bytes_current_layer_unchecked(bytes: &[u8]) -> Self {
283 let sctp = SctpRef::from_bytes_unchecked(bytes);
284
285 let mut control_chunks = Vec::new();
286 let control_iter = sctp.control_chunks();
287 for chunk in control_iter {
288 control_chunks.push(chunk.into());
289 }
290
291 let mut payload_chunks = Vec::new();
292 let payload_iter = sctp.payload_chunks();
293 for chunk in payload_iter {
294 payload_chunks.push(chunk.to_boxed_layer());
295 }
296
297 Sctp {
298 sport: sctp.sport(),
299 dport: sctp.dport(),
300 verify_tag: sctp.verify_tag(),
301 chksum: None,
302 control_chunks,
303 payload_chunks,
304 }
305 }
306
307 fn payload_from_bytes_unchecked_default(&mut self, _bytes: &[u8]) {}
308}
309
310#[cfg(feature = "alloc")]
311impl LayerLength for Sctp {
312 fn len(&self) -> usize {
313 8 + self.control_chunks.iter().map(|c| c.len()).sum::<usize>()
314 + self.payload_chunks.iter().map(|c| c.len()).sum::<usize>()
315 }
316}
317
318#[cfg(feature = "alloc")]
319impl LayerObject for Sctp {
320 #[inline]
321 fn can_add_payload_default(&self, payload: &dyn LayerObject) -> bool {
322 payload.as_any().downcast_ref::<&SctpDataChunk>().is_some()
323 }
324
325 #[inline]
326 fn add_payload_unchecked(&mut self, payload: Box<dyn LayerObject>) {
327 self.payload_chunks.push(payload);
328 }
329
330 #[inline]
331 fn payloads(&self) -> &[Box<dyn LayerObject>] {
332 &self.payload_chunks
333 }
334
335 #[inline]
336 fn payloads_mut(&mut self) -> &mut [Box<dyn LayerObject>] {
337 &mut self.payload_chunks
338 }
339
340 fn remove_payload_at(&mut self, index: usize) -> Option<Box<dyn LayerObject>> {
341 if index < self.payload_chunks.len() {
342 Some(self.payload_chunks.remove(index))
343 } else {
344 None
345 }
346 }
347}
348
349#[cfg(feature = "alloc")]
350impl ToBytes for Sctp {
351 fn to_bytes_checksummed(
352 &self,
353 writer: &mut PacketWriter<'_, Vec<u8>>,
354 _prev: Option<(LayerId, usize)>,
355 ) -> Result<(), SerializationError> {
356 let start = writer.len();
357 writer.update_layer::<Sctp>();
358 writer.write_slice(&self.sport.to_be_bytes())?;
359 writer.write_slice(&self.dport.to_be_bytes())?;
360 writer.write_slice(&self.verify_tag.to_be_bytes())?;
361 writer.write_slice(&self.chksum.unwrap_or(0).to_be_bytes())?;
362 for chunk in &self.control_chunks {
363 chunk.to_bytes_extended(writer)?;
364 }
365
366 for chunk in &self.payload_chunks {
367 chunk.to_bytes_checksummed(writer, Some((Self::layer_id(), start)))?;
368 }
369
370 Ok(())
373 }
374}
375
376#[derive(Clone, Copy, Debug, LayerRef, StatelessLayer)]
395#[owned_type(Sctp)]
396#[metadata_type(SctpMetadata)]
397pub struct SctpRef<'a> {
398 #[data_field]
399 data: &'a [u8],
400}
401
402impl<'a> SctpRef<'a> {
403 #[inline]
405 pub fn sport(&self) -> u16 {
406 u16::from_be_bytes(utils::to_array(self.data, 0).unwrap())
407 }
408
409 #[inline]
411 pub fn dport(&self) -> u16 {
412 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
413 }
414
415 #[inline]
419 pub fn verify_tag(&self) -> u32 {
420 u32::from_be_bytes(utils::to_array(self.data, 4).unwrap())
421 }
422
423 #[inline]
425 pub fn chksum(&self) -> u32 {
426 u32::from_be_bytes(utils::to_array(self.data, 8).unwrap())
427 }
428
429 #[inline]
443 pub fn control_chunks(&self) -> ControlChunksIterRef<'a> {
444 ControlChunksIterRef {
445 chunk_iter: self.chunks(),
446 }
447 }
448
449 #[inline]
462 pub fn payload_chunks(&self) -> DataChunksIterRef<'a> {
463 DataChunksIterRef {
464 chunk_iter: self.chunks(),
465 }
466 }
467
468 #[inline]
474 pub fn chunks(&self) -> ChunksIterRef<'a> {
475 ChunksIterRef {
476 bytes: &self.data[12..],
477 }
478 }
479}
480
481impl<'a> FromBytesRef<'a> for SctpRef<'a> {
482 #[inline]
483 fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
484 SctpRef { data: bytes }
485 }
486}
487
488#[doc(hidden)]
489impl LayerOffset for SctpRef<'_> {
490 #[inline]
491 fn payload_byte_index_default(_bytes: &[u8], _layer_type: LayerId) -> Option<usize> {
492 None }
495}
496
497impl Validate for SctpRef<'_> {
498 fn validate_current_layer(curr_layer: &[u8]) -> Result<(), ValidationError> {
499 let mut remaining = match curr_layer.get(12..) {
500 Some(rem) => rem,
501 None => {
502 return Err(ValidationError {
503 layer: Self::name(),
504 class: ValidationErrorClass::InsufficientBytes,
505 #[cfg(feature = "error_string")]
506 reason: "insufficient bytes in SCTP packet for Common Header",
507 })
508 }
509 };
510
511 let mut data_reached = false;
512 let mut single_chunk = false;
513 let mut shutdown = false;
514 let mut chunk_cnt = 0;
515
516 while let Some(&chunk_type) = remaining.first() {
517 chunk_cnt += 1;
518 let chunk_validation = match chunk_type {
519 CHUNK_TYPE_DATA => {
520 data_reached = true;
521 SctpDataChunkRef::validate(remaining)
522 }
523 _ if data_reached => {
524 return Err(ValidationError {
525 layer: Self::name(),
526 class: ValidationErrorClass::InvalidValue,
527 #[cfg(feature = "error_string")]
528 reason: "SCTP Control Chunk not allowed after DATA Chunk in Chunks field",
529 })
530 }
531 CHUNK_TYPE_INIT => {
532 single_chunk = true;
533 InitChunkRef::validate(remaining)
534 }
535 CHUNK_TYPE_INIT_ACK => {
536 single_chunk = true;
537 InitAckChunkRef::validate(remaining)
538 }
539 CHUNK_TYPE_SACK => SackChunkRef::validate(remaining),
540 CHUNK_TYPE_HEARTBEAT => HeartbeatChunkRef::validate(remaining),
541 CHUNK_TYPE_HEARTBEAT_ACK => HeartbeatAckChunkRef::validate(remaining),
542 CHUNK_TYPE_ABORT => AbortChunkRef::validate(remaining),
543 CHUNK_TYPE_SHUTDOWN => {
544 shutdown = true;
545 ShutdownChunkRef::validate(remaining)
546 }
547 CHUNK_TYPE_SHUTDOWN_ACK => {
548 shutdown = true;
549 ShutdownAckChunkRef::validate(remaining)
550 }
551 CHUNK_TYPE_ERROR => ErrorChunkRef::validate(remaining),
552 CHUNK_TYPE_COOKIE_ECHO => CookieEchoChunkRef::validate(remaining),
553 CHUNK_TYPE_COOKIE_ACK => CookieAckChunkRef::validate(remaining),
554 CHUNK_TYPE_SHUTDOWN_COMPLETE => {
555 single_chunk = true;
556 ShutdownCompleteChunkRef::validate(remaining)
557 }
558 _ => UnknownChunkRef::validate(remaining),
559 };
560
561 match chunk_validation {
562 Err(e) => {
563 if let ValidationErrorClass::ExcessBytes(l) = e.class {
564 remaining = &remaining[remaining.len() - l..];
565 } else {
566 return Err(e);
567 }
568 }
569 Ok(()) => return Ok(()),
570 }
571 }
572
573 if single_chunk && chunk_cnt > 1 {
574 return Err(ValidationError {
575 layer: Self::name(),
576 class: ValidationErrorClass::InvalidValue,
577 #[cfg(feature = "error_string")]
578 reason: "multiple chunks bundled in one SCTP message where only one was allowed (chunk types INIT, INIT_ACK and SHUTDOWN_COMPLETE cannot be bundled with other chunks)",
579 });
580 }
581
582 if shutdown && data_reached {
583 return Err(ValidationError {
584 layer: Self::name(),
585 class: ValidationErrorClass::InvalidValue,
586 #[cfg(feature = "error_string")]
587 reason:
588 "SCTP SHUTDOWN/SHUTDOWN_ACK Chunk cannot be bundled with DATA (Payload) Chunks",
589 });
590 }
591
592 Ok(()) }
594
595 #[inline]
596 fn validate_payload_default(_curr_layer: &[u8]) -> Result<(), ValidationError> {
597 Ok(()) }
599}
600
601#[derive(Clone, Copy, Debug)]
603pub struct ControlChunksIterRef<'a> {
604 chunk_iter: ChunksIterRef<'a>,
605}
606
607impl<'a> Iterator for ControlChunksIterRef<'a> {
608 type Item = SctpControlChunkRef<'a>;
609
610 #[inline]
611 fn next(&mut self) -> Option<Self::Item> {
612 for chunk in self.chunk_iter.by_ref() {
613 if let ChunkRef::Control(c) = chunk {
614 return Some(c);
615 }
616 }
617 None
618 }
619}
620
621#[derive(Clone, Copy, Debug)]
623pub struct DataChunksIterRef<'a> {
624 chunk_iter: ChunksIterRef<'a>,
625}
626
627impl<'a> Iterator for DataChunksIterRef<'a> {
628 type Item = SctpDataChunkRef<'a>;
629
630 #[inline]
631 fn next(&mut self) -> Option<Self::Item> {
632 for chunk in self.chunk_iter.by_ref() {
633 if let ChunkRef::Payload(c) = chunk {
634 return Some(c);
635 }
636 }
637 None
638 }
639}
640
641#[derive(Clone, Copy, Debug)]
643pub enum ChunkRef<'a> {
644 Control(SctpControlChunkRef<'a>),
645 Payload(SctpDataChunkRef<'a>),
646}
647
648#[derive(Clone, Copy, Debug)]
650pub struct ChunksIterRef<'a> {
651 bytes: &'a [u8],
652}
653
654impl<'a> Iterator for ChunksIterRef<'a> {
655 type Item = ChunkRef<'a>;
656
657 fn next(&mut self) -> Option<Self::Item> {
658 let (chunk_type, unpadded_len) =
659 match (self.bytes.first(), utils::get_array::<2>(self.bytes, 2)) {
660 (Some(&t), Some(&l)) => (t, u16::from_be_bytes(l)),
661 _ => return None,
662 };
663
664 let len = utils::padded_length::<4>(unpadded_len as usize);
665 match (self.bytes.get(..len), self.bytes.get(len..)) {
666 (Some(chunk_bytes), Some(rem)) => {
667 self.bytes = rem;
668 if chunk_type == CHUNK_TYPE_DATA {
669 Some(ChunkRef::Payload(SctpDataChunkRef::from_bytes_unchecked(
670 chunk_bytes,
671 )))
672 } else {
673 Some(ChunkRef::Control(
674 SctpControlChunkRef::from_bytes_unchecked(chunk_bytes),
675 ))
676 }
677 }
678 _ => {
679 panic!("insufficient bytes for ChunkRef in iterator.");
680 }
681 }
682 }
683}
684
685#[derive(Clone, Debug)]
691#[cfg(feature = "alloc")]
692pub enum SctpControlChunk {
693 Init(InitChunk),
694 InitAck(InitAckChunk),
695 Sack(SackChunk),
696 Heartbeat(HeartbeatChunk),
697 HeartbeatAck(HeartbeatAckChunk),
698 Abort(AbortChunk),
699 Shutdown(ShutdownChunk),
700 ShutdownAck(ShutdownAckChunk),
701 Error(ErrorChunk),
702 CookieEcho(CookieEchoChunk),
703 CookieAck(CookieAckChunk),
704 ShutdownComplete(ShutdownCompleteChunk),
705 Unknown(UnknownChunk),
706}
707
708#[cfg(feature = "alloc")]
709impl SctpControlChunk {
710 #[inline]
711 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
712 Self::validate(bytes)?;
713 Ok(Self::from_bytes_unchecked(bytes))
714 }
715
716 #[inline]
717 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
718 Self::from(SctpControlChunkRef::from_bytes_unchecked(bytes))
719 }
720
721 #[inline]
722 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
723 SctpControlChunkRef::validate(bytes)
724 }
725
726 pub fn chunk_type(&self) -> u8 {
727 match self {
728 SctpControlChunk::Init(c) => c.chunk_type(),
729 SctpControlChunk::InitAck(c) => c.chunk_type(),
730 SctpControlChunk::Sack(c) => c.chunk_type(),
731 SctpControlChunk::Heartbeat(c) => c.chunk_type(),
732 SctpControlChunk::HeartbeatAck(c) => c.chunk_type(),
733 SctpControlChunk::Abort(c) => c.chunk_type(),
734 SctpControlChunk::Shutdown(c) => c.chunk_type(),
735 SctpControlChunk::ShutdownAck(c) => c.chunk_type(),
736 SctpControlChunk::Error(c) => c.chunk_type(),
737 SctpControlChunk::CookieEcho(c) => c.chunk_type(),
738 SctpControlChunk::CookieAck(c) => c.chunk_type(),
739 SctpControlChunk::ShutdownComplete(c) => c.chunk_type(),
740 SctpControlChunk::Unknown(c) => c.chunk_type(),
741 }
742 }
743
744 pub fn len(&self) -> usize {
745 match self {
746 SctpControlChunk::Init(c) => c.len(),
747 SctpControlChunk::InitAck(c) => c.len(),
748 SctpControlChunk::Sack(c) => c.len(),
749 SctpControlChunk::Heartbeat(c) => c.len(),
750 SctpControlChunk::HeartbeatAck(c) => c.len(),
751 SctpControlChunk::Abort(c) => c.len(),
752 SctpControlChunk::Shutdown(c) => c.len(),
753 SctpControlChunk::ShutdownAck(c) => c.len(),
754 SctpControlChunk::Error(c) => c.len(),
755 SctpControlChunk::CookieEcho(c) => c.len(),
756 SctpControlChunk::CookieAck(c) => c.len(),
757 SctpControlChunk::ShutdownComplete(c) => c.len(),
758 SctpControlChunk::Unknown(c) => c.len(),
759 }
760 }
761
762 pub fn to_bytes_extended<T: PacketWritable>(
763 &self,
764 writer: &mut PacketWriter<'_, T>,
765 ) -> Result<(), SerializationError> {
766 match self {
767 SctpControlChunk::Init(c) => c.to_bytes_extended(writer),
768 SctpControlChunk::InitAck(c) => c.to_bytes_extended(writer),
769 SctpControlChunk::Sack(c) => c.to_bytes_extended(writer),
770 SctpControlChunk::Heartbeat(c) => c.to_bytes_extended(writer),
771 SctpControlChunk::HeartbeatAck(c) => c.to_bytes_extended(writer),
772 SctpControlChunk::Abort(c) => c.to_bytes_extended(writer),
773 SctpControlChunk::Shutdown(c) => c.to_bytes_extended(writer),
774 SctpControlChunk::ShutdownAck(c) => c.to_bytes_extended(writer),
775 SctpControlChunk::Error(c) => c.to_bytes_extended(writer),
776 SctpControlChunk::CookieEcho(c) => c.to_bytes_extended(writer),
777 SctpControlChunk::CookieAck(c) => c.to_bytes_extended(writer),
778 SctpControlChunk::ShutdownComplete(c) => c.to_bytes_extended(writer),
779 SctpControlChunk::Unknown(c) => c.to_bytes_extended(writer),
780 }
781 }
782}
783
784#[cfg(feature = "alloc")]
785impl From<SctpControlChunkRef<'_>> for SctpControlChunk {
786 #[inline]
787 fn from(value: SctpControlChunkRef<'_>) -> Self {
788 SctpControlChunk::from(&value)
789 }
790}
791
792#[cfg(feature = "alloc")]
793impl From<&SctpControlChunkRef<'_>> for SctpControlChunk {
794 fn from(value: &SctpControlChunkRef<'_>) -> Self {
795 match value {
796 SctpControlChunkRef::Init(c) => SctpControlChunk::Init(c.into()),
797 SctpControlChunkRef::InitAck(c) => SctpControlChunk::InitAck(c.into()),
798 SctpControlChunkRef::Sack(c) => SctpControlChunk::Sack(c.into()),
799 SctpControlChunkRef::Heartbeat(c) => SctpControlChunk::Heartbeat(c.into()),
800 SctpControlChunkRef::HeartbeatAck(c) => SctpControlChunk::HeartbeatAck(c.into()),
801 SctpControlChunkRef::Abort(c) => SctpControlChunk::Abort(c.into()),
802 SctpControlChunkRef::Shutdown(c) => SctpControlChunk::Shutdown(c.into()),
803 SctpControlChunkRef::ShutdownAck(c) => SctpControlChunk::ShutdownAck(c.into()),
804 SctpControlChunkRef::Error(c) => SctpControlChunk::Error(c.into()),
805 SctpControlChunkRef::CookieEcho(c) => SctpControlChunk::CookieEcho(c.into()),
806 SctpControlChunkRef::CookieAck(c) => SctpControlChunk::CookieAck(c.into()),
807 SctpControlChunkRef::ShutdownComplete(c) => {
808 SctpControlChunk::ShutdownComplete(c.into())
809 }
810 SctpControlChunkRef::Unknown(c) => SctpControlChunk::Unknown(c.into()),
811 }
812 }
813}
814
815#[derive(Clone, Copy, Debug)]
817pub enum SctpControlChunkRef<'a> {
818 Init(InitChunkRef<'a>),
819 InitAck(InitAckChunkRef<'a>),
820 Sack(SackChunkRef<'a>),
821 Heartbeat(HeartbeatChunkRef<'a>),
822 HeartbeatAck(HeartbeatAckChunkRef<'a>),
823 Abort(AbortChunkRef<'a>),
824 Shutdown(ShutdownChunkRef<'a>),
825 ShutdownAck(ShutdownAckChunkRef<'a>),
826 Error(ErrorChunkRef<'a>),
827 CookieEcho(CookieEchoChunkRef<'a>),
828 CookieAck(CookieAckChunkRef<'a>),
829 ShutdownComplete(ShutdownCompleteChunkRef<'a>),
830 Unknown(UnknownChunkRef<'a>),
831}
832
833impl<'a> SctpControlChunkRef<'a> {
834 #[inline]
835 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
836 Self::validate(bytes)?;
837 Ok(Self::from_bytes_unchecked(bytes))
838 }
839
840 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
841 let chunk_type = bytes[0];
842 match chunk_type {
843 CHUNK_TYPE_INIT => Self::Init(InitChunkRef { data: bytes }),
844 CHUNK_TYPE_INIT_ACK => Self::InitAck(InitAckChunkRef { data: bytes }),
845 CHUNK_TYPE_SACK => Self::Sack(SackChunkRef { data: bytes }),
846 CHUNK_TYPE_HEARTBEAT => Self::Heartbeat(HeartbeatChunkRef { data: bytes }),
847 CHUNK_TYPE_HEARTBEAT_ACK => Self::HeartbeatAck(HeartbeatAckChunkRef { data: bytes }),
848 CHUNK_TYPE_ABORT => Self::Abort(AbortChunkRef { data: bytes }),
849 CHUNK_TYPE_SHUTDOWN => Self::Shutdown(ShutdownChunkRef { data: bytes }),
850 CHUNK_TYPE_SHUTDOWN_ACK => Self::ShutdownAck(ShutdownAckChunkRef { data: bytes }),
851 CHUNK_TYPE_ERROR => Self::Error(ErrorChunkRef { data: bytes }),
852 CHUNK_TYPE_COOKIE_ECHO => Self::CookieEcho(CookieEchoChunkRef { data: bytes }),
853 CHUNK_TYPE_COOKIE_ACK => Self::CookieAck(CookieAckChunkRef { data: bytes }),
854 CHUNK_TYPE_SHUTDOWN_COMPLETE => {
855 Self::ShutdownComplete(ShutdownCompleteChunkRef { data: bytes })
856 }
857 _ => Self::Unknown(UnknownChunkRef { data: bytes }),
858 }
859 }
860
861 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
862 let chunk_type = bytes[0];
863 match chunk_type {
864 CHUNK_TYPE_INIT => InitChunkRef::validate(bytes),
865 CHUNK_TYPE_INIT_ACK => InitAckChunkRef::validate(bytes),
866 CHUNK_TYPE_SACK => SackChunkRef::validate(bytes),
867 CHUNK_TYPE_HEARTBEAT => HeartbeatChunkRef::validate(bytes),
868 CHUNK_TYPE_HEARTBEAT_ACK => HeartbeatAckChunkRef::validate(bytes),
869 CHUNK_TYPE_ABORT => AbortChunkRef::validate(bytes),
870 CHUNK_TYPE_SHUTDOWN => ShutdownChunkRef::validate(bytes),
871 CHUNK_TYPE_SHUTDOWN_ACK => ShutdownAckChunkRef::validate(bytes),
872 CHUNK_TYPE_ERROR => ErrorChunkRef::validate(bytes),
873 CHUNK_TYPE_COOKIE_ECHO => CookieEchoChunkRef::validate(bytes),
874 CHUNK_TYPE_COOKIE_ACK => CookieAckChunkRef::validate(bytes),
875 CHUNK_TYPE_SHUTDOWN_COMPLETE => ShutdownCompleteChunkRef::validate(bytes),
876 _ => UnknownChunkRef::validate(bytes),
877 }
878 }
879}
880
881#[derive(Clone, Debug)]
904#[cfg(feature = "alloc")]
905pub struct InitChunk {
906 flags: u8,
907 init_tag: u32,
908 a_rwnd: u32,
909 ostreams: u16,
910 istreams: u16,
911 init_tsn: u32,
912 options: Vec<InitOption>,
913}
914
915#[cfg(feature = "alloc")]
916impl InitChunk {
917 #[inline]
920 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
921 Self::validate(bytes)?;
922 Ok(Self::from_bytes_unchecked(bytes))
923 }
924
925 #[inline]
932 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
933 Self::from(InitChunkRef::from_bytes_unchecked(bytes))
934 }
935
936 #[inline]
941 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
942 InitChunkRef::validate(bytes)
943 }
944
945 #[inline]
947 pub fn chunk_type(&self) -> u8 {
948 CHUNK_TYPE_INIT
949 }
950
951 #[inline]
953 pub fn flags_raw(&self) -> u8 {
954 self.flags
955 }
956
957 #[inline]
959 pub fn set_flags_raw(&mut self, flags: u8) {
960 self.flags = flags;
961 }
962
963 #[inline]
965 pub fn unpadded_len(&self) -> usize {
966 20 + self.options.iter().map(|o| o.len()).sum::<usize>()
967 }
968
969 #[inline]
971 pub fn len(&self) -> usize {
972 utils::padded_length::<4>(self.unpadded_len())
973 }
974
975 #[inline]
980 pub fn init_tag(&self) -> u32 {
981 self.init_tag
982 }
983
984 #[inline]
986 pub fn set_init_tag(&mut self, init_tag: u32) {
987 self.init_tag = init_tag;
988 }
989
990 #[inline]
995 pub fn a_rwnd(&self) -> u32 {
996 self.a_rwnd
997 }
998
999 #[inline]
1001 pub fn set_a_rwnd(&mut self, a_rwnd: u32) {
1002 self.a_rwnd = a_rwnd;
1003 }
1004
1005 #[inline]
1008 pub fn ostreams(&self) -> u16 {
1009 self.ostreams
1010 }
1011
1012 #[inline]
1014 pub fn set_ostreams(&mut self, ostreams: u16) {
1015 self.ostreams = ostreams;
1016 }
1017
1018 #[inline]
1021 pub fn istreams(&self) -> u16 {
1022 self.istreams
1023 }
1024
1025 #[inline]
1027 pub fn set_istreams(&mut self, istreams: u16) {
1028 self.istreams = istreams;
1029 }
1030
1031 #[inline]
1035 pub fn init_tsn(&self) -> u32 {
1036 self.init_tsn
1037 }
1038
1039 #[inline]
1041 pub fn set_init_tsn(&mut self, init_tsn: u32) {
1042 self.init_tsn = init_tsn;
1043 }
1044
1045 #[inline]
1047 pub fn options(&self) -> &Vec<InitOption> {
1048 &self.options
1049 }
1050
1051 #[inline]
1053 pub fn options_mut(&mut self) -> &mut Vec<InitOption> {
1054 &mut self.options
1055 }
1056
1057 pub fn to_bytes_extended<T: PacketWritable>(
1058 &self,
1059 writer: &mut PacketWriter<'_, T>,
1060 ) -> Result<(), SerializationError> {
1061 writer.write_slice(&[CHUNK_TYPE_INIT])?;
1062 writer.write_slice(&[self.flags])?;
1063 writer.write_slice(&self.unpadded_len().to_be_bytes())?;
1064 writer.write_slice(&self.init_tag.to_be_bytes())?;
1065 writer.write_slice(&self.a_rwnd.to_be_bytes())?;
1066 writer.write_slice(&self.ostreams.to_be_bytes())?;
1067 writer.write_slice(&self.istreams.to_be_bytes())?;
1068 writer.write_slice(&self.init_tsn.to_be_bytes())?;
1069 for option in &self.options {
1070 option.to_bytes_extended(writer)?;
1071 }
1072 Ok(())
1075 }
1076}
1077
1078#[cfg(feature = "alloc")]
1079impl From<InitChunkRef<'_>> for InitChunk {
1080 #[inline]
1081 fn from(value: InitChunkRef<'_>) -> Self {
1082 Self::from(&value)
1083 }
1084}
1085
1086#[cfg(feature = "alloc")]
1087impl From<&InitChunkRef<'_>> for InitChunk {
1088 fn from(value: &InitChunkRef<'_>) -> Self {
1089 let mut options = Vec::new();
1090 let iter = value.options_iter();
1091 for option in iter {
1092 options.push(option.into());
1093 }
1094
1095 InitChunk {
1096 flags: value.flags_raw(),
1097 init_tag: value.init_tag(),
1098 a_rwnd: value.a_rwnd(),
1099 ostreams: value.ostreams(),
1100 istreams: value.istreams(),
1101 init_tsn: value.init_tsn(),
1102 options,
1103 }
1104 }
1105}
1106
1107#[derive(Clone, Copy, Debug)]
1130pub struct InitChunkRef<'a> {
1131 data: &'a [u8],
1132}
1133
1134impl<'a> InitChunkRef<'a> {
1135 #[inline]
1136 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
1137 Self::validate(bytes)?;
1138 Ok(Self::from_bytes_unchecked(bytes))
1139 }
1140
1141 #[inline]
1142 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
1143 InitChunkRef { data: bytes }
1144 }
1145
1146 pub fn validate(bytes: &'a [u8]) -> Result<(), ValidationError> {
1147 match utils::to_array(bytes, 2) {
1148 Some(unpadded_len_arr) => {
1149 let len = u16::from_be_bytes(unpadded_len_arr) as usize;
1150
1151 if bytes.len() < cmp::max(len, 20) {
1152 return Err(ValidationError {
1153 layer: SctpRef::name(),
1154 class: ValidationErrorClass::InsufficientBytes,
1155 #[cfg(feature = "error_string")]
1156 reason: "insufficient bytes in SCTP INIT chunk for header and optional parameters",
1157 });
1158 }
1159
1160 if len % 4 != 0 {
1161 return Err(ValidationError {
1162 layer: SctpRef::name(),
1163 class: ValidationErrorClass::InvalidValue,
1164 #[cfg(feature = "error_string")]
1165 reason: "SCTP INIT chunk length was not a multiple of 4",
1166 });
1167 }
1168
1169 if len < 20 {
1170 return Err(ValidationError {
1171 layer: SctpRef::name(),
1172 class: ValidationErrorClass::InvalidValue,
1173 #[cfg(feature = "error_string")]
1174 reason:
1175 "length field of SCTP INIT chunk was too short to cover entire header",
1176 });
1177 }
1178
1179 let mut options = &bytes[20..];
1180 while !options.is_empty() {
1181 match InitOptionRef::validate(options) {
1182 Err(e) => {
1183 if let ValidationErrorClass::ExcessBytes(extra) = e.class {
1184 options = &options[options.len() - extra..];
1185 } else {
1186 return Err(ValidationError {
1187 layer: SctpRef::name(),
1188 class: ValidationErrorClass::InvalidValue,
1189 #[cfg(feature = "error_string")]
1190 reason: e.reason,
1191 });
1192 }
1193 }
1194 _ => break,
1195 }
1196 }
1197
1198 if len < bytes.len() {
1199 Err(ValidationError {
1200 layer: SctpRef::name(),
1201 class: ValidationErrorClass::ExcessBytes(bytes.len() - len),
1202 #[cfg(feature = "error_string")]
1203 reason: "extra bytes remain at end of SCTP INIT chunk",
1204 })
1205 } else {
1206 Ok(())
1207 }
1208 }
1209 _ => Err(ValidationError {
1210 layer: SctpRef::name(),
1211 class: ValidationErrorClass::InsufficientBytes,
1212 #[cfg(feature = "error_string")]
1213 reason: "insufficient bytes in SCTP INIT chunk for header Length field",
1214 }),
1215 }
1216 }
1217
1218 #[inline]
1219 pub fn chunk_type(&self) -> u8 {
1220 self.data[0]
1221 }
1222
1223 #[inline]
1224 pub fn flags_raw(&self) -> u8 {
1225 self.data[1]
1226 }
1227
1228 #[inline]
1229 pub fn unpadded_len(&self) -> u16 {
1230 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
1231 }
1232
1233 #[inline]
1234 pub fn len(&self) -> usize {
1235 utils::padded_length::<4>(self.unpadded_len() as usize)
1236 }
1237
1238 #[inline]
1239 pub fn init_tag(&self) -> u32 {
1240 u32::from_be_bytes(utils::to_array(self.data, 4).unwrap())
1241 }
1242
1243 #[inline]
1244 pub fn a_rwnd(&self) -> u32 {
1245 u32::from_be_bytes(utils::to_array(self.data, 8).unwrap())
1246 }
1247
1248 #[inline]
1249 pub fn ostreams(&self) -> u16 {
1250 u16::from_be_bytes(utils::to_array(self.data, 12).unwrap())
1251 }
1252
1253 #[inline]
1254 pub fn istreams(&self) -> u16 {
1255 u16::from_be_bytes(utils::to_array(self.data, 14).unwrap())
1256 }
1257
1258 #[inline]
1259 pub fn init_tsn(&self) -> u32 {
1260 u32::from_be_bytes(utils::to_array(self.data, 16).unwrap())
1261 }
1262
1263 #[inline]
1264 pub fn options_iter(&self) -> InitOptionsIterRef<'a> {
1265 InitOptionsIterRef { bytes: self.data }
1266 }
1267}
1268
1269#[derive(Clone, Copy, Debug)]
1270pub struct InitOptionsIterRef<'a> {
1271 bytes: &'a [u8],
1272}
1273
1274impl<'a> Iterator for InitOptionsIterRef<'a> {
1275 type Item = InitOptionRef<'a>;
1276
1277 fn next(&mut self) -> Option<Self::Item> {
1278 let (opt_type, unpadded_len) = match (
1279 utils::get_array(self.bytes, 0).map(|&a| u16::from_be_bytes(a)),
1280 utils::get_array(self.bytes, 2).map(|&a| u16::from_be_bytes(a)),
1281 ) {
1282 (Some(t), Some(l)) => (t, l),
1283 _ => return None,
1284 };
1285
1286 let min_len = match opt_type {
1287 INIT_OPT_IPV4_ADDRESS | INIT_OPT_COOKIE_PRESERVATIVE => 8,
1288 INIT_OPT_IPV6_ADDRESS => 20,
1289 INIT_OPT_HOSTNAME_ADDR | INIT_OPT_SUPP_ADDR_TYPES => 4,
1290 _ => 4,
1291 };
1292
1293 if self.bytes.len() < min_len {
1294 self.bytes = &[]; return None;
1296 }
1297
1298 let len = cmp::max(min_len, utils::padded_length::<4>(unpadded_len as usize));
1299 match (self.bytes.get(..len), self.bytes.get(len..)) {
1300 (Some(opt_bytes), Some(rem)) => {
1301 self.bytes = rem;
1302 Some(InitOptionRef::from_bytes_unchecked(opt_bytes))
1303 }
1304 _ => {
1305 let opt_bytes = self.bytes;
1307 self.bytes = &[];
1308 Some(InitOptionRef::from_bytes_unchecked(opt_bytes))
1309 }
1310 }
1311 }
1312}
1313
1314#[derive(Clone, Debug)]
1315#[cfg(feature = "alloc")]
1316pub enum InitOption {
1317 Ipv4Address(u32),
1318 Ipv6Address(u128),
1319 CookiePreservative(u32),
1320 HostnameAddress(Vec<u8>),
1321 SupportedAddressTypes(Vec<u16>),
1322 Unknown(u16, Vec<u8>),
1323}
1324
1325#[cfg(feature = "alloc")]
1326impl InitOption {
1327 #[inline]
1328 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
1329 Self::validate(bytes)?;
1330 Ok(Self::from_bytes_unchecked(bytes))
1331 }
1332
1333 #[inline]
1334 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
1335 Self::from(InitOptionRef::from_bytes_unchecked(bytes))
1336 }
1337
1338 #[inline]
1339 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
1340 InitOptionRef::validate(bytes)
1341 }
1342
1343 #[inline]
1344 pub fn new_ipv4_address(addr: u32) -> Self {
1345 Self::Ipv4Address(addr)
1346 }
1347
1348 #[inline]
1349 pub fn new_ipv6_address(addr: u128) -> Self {
1350 Self::Ipv6Address(addr)
1351 }
1352
1353 #[inline]
1354 pub fn new_cookie_preservative(cookie_lifespan: u32) -> Self {
1355 Self::CookiePreservative(cookie_lifespan)
1356 }
1357
1358 pub fn option_type(&self) -> u16 {
1359 match self {
1360 Self::Ipv4Address(_) => INIT_OPT_IPV4_ADDRESS,
1361 Self::Ipv6Address(_) => INIT_OPT_IPV6_ADDRESS,
1362 Self::CookiePreservative(_) => INIT_OPT_COOKIE_PRESERVATIVE,
1363 Self::HostnameAddress(_) => INIT_OPT_HOSTNAME_ADDR,
1364 Self::SupportedAddressTypes(_) => INIT_OPT_SUPP_ADDR_TYPES,
1365 Self::Unknown(t, _) => *t,
1366 }
1367 }
1368
1369 pub fn unpadded_len(&self) -> usize {
1370 match self {
1371 Self::Ipv4Address(_) => 8,
1372 Self::Ipv6Address(_) => 20,
1373 Self::CookiePreservative(_) => 8,
1374 Self::HostnameAddress(h) => 4 + h.len(),
1375 Self::SupportedAddressTypes(addr_types) => 4 + (2 * addr_types.len()),
1376 Self::Unknown(_, d) => 4 + d.len(),
1377 }
1378 }
1379
1380 #[inline]
1381 pub fn len(&self) -> usize {
1382 utils::padded_length::<4>(self.unpadded_len())
1383 }
1384
1385 pub fn to_bytes_extended<T: PacketWritable>(
1386 &self,
1387 writer: &mut PacketWriter<'_, T>,
1388 ) -> Result<(), SerializationError> {
1389 match self {
1390 Self::Ipv4Address(ipv4) => {
1391 writer.write_slice(&INIT_OPT_IPV4_ADDRESS.to_be_bytes())?;
1392 writer.write_slice(&8u16.to_be_bytes())?;
1393 writer.write_slice(&ipv4.to_be_bytes())?;
1394 }
1395 Self::Ipv6Address(ipv6) => {
1396 writer.write_slice(&INIT_OPT_IPV6_ADDRESS.to_be_bytes())?;
1397 writer.write_slice(&20u16.to_be_bytes())?;
1398 writer.write_slice(&ipv6.to_be_bytes())?;
1399 }
1400 Self::CookiePreservative(cookie_lifespan) => {
1401 writer.write_slice(&INIT_OPT_COOKIE_PRESERVATIVE.to_be_bytes())?;
1402 writer.write_slice(&8u16.to_be_bytes())?;
1403 writer.write_slice(&cookie_lifespan.to_be_bytes())?;
1404 }
1405 Self::HostnameAddress(addr) => {
1406 let unpadded_len = u16::try_from(self.unpadded_len())
1407 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?;
1408 writer.write_slice(&INIT_OPT_HOSTNAME_ADDR.to_be_bytes())?;
1409 writer.write_slice(&unpadded_len.to_be_bytes())?;
1410 writer.write_slice(&addr)?;
1411 for _ in unpadded_len as usize..utils::padded_length::<4>(unpadded_len as usize) {
1412 writer.write_slice(&[0])?;
1413 }
1414 }
1415 Self::SupportedAddressTypes(addr_types) => {
1416 let unpadded_len = u16::try_from(self.unpadded_len())
1417 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?;
1418 writer.write_slice(&INIT_OPT_SUPP_ADDR_TYPES.to_be_bytes())?;
1419 writer.write_slice(&unpadded_len.to_be_bytes())?;
1420 for addr_type in addr_types {
1421 writer.write_slice(&addr_type.to_be_bytes())?;
1422 }
1423
1424 for _ in unpadded_len as usize..utils::padded_length::<4>(unpadded_len as usize) {
1425 writer.write_slice(&[0])?;
1426 }
1427 }
1428 Self::Unknown(opt_type, data) => {
1429 let unpadded_len = u16::try_from(self.unpadded_len())
1430 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?;
1431 writer.write_slice(&opt_type.to_be_bytes())?;
1432 writer.write_slice(&unpadded_len.to_be_bytes())?;
1433 writer.write_slice(data)?;
1434 for _ in unpadded_len as usize..utils::padded_length::<4>(unpadded_len as usize) {
1435 writer.write_slice(&[0])?;
1436 }
1437 }
1438 }
1439 Ok(())
1440 }
1441}
1442
1443#[cfg(feature = "alloc")]
1444impl From<InitOptionRef<'_>> for InitOption {
1445 #[inline]
1446 fn from(value: InitOptionRef<'_>) -> Self {
1447 Self::from(&value)
1448 }
1449}
1450
1451#[cfg(feature = "alloc")]
1452impl From<&InitOptionRef<'_>> for InitOption {
1453 fn from(value: &InitOptionRef<'_>) -> Self {
1454 match value.payload() {
1455 InitOptionPayloadRef::Ipv4Address(ipv4) => InitOption::Ipv4Address(ipv4),
1456 InitOptionPayloadRef::Ipv6Address(ipv6) => InitOption::Ipv6Address(ipv6),
1457 InitOptionPayloadRef::CookiePreservative(cookie) => {
1458 InitOption::CookiePreservative(cookie)
1459 }
1460 InitOptionPayloadRef::HostnameAddress(addr) => {
1461 InitOption::HostnameAddress(Vec::from(addr))
1462 }
1463 InitOptionPayloadRef::SupportedAddressTypes(mut addr_bytes) => {
1464 let mut v = Vec::new();
1465 while let (Some(&addr_arr), Some(remaining)) =
1466 (utils::get_array(addr_bytes, 0), addr_bytes.get(2..))
1467 {
1468 v.push(u16::from_be_bytes(addr_arr));
1469 addr_bytes = remaining;
1470 }
1471 InitOption::SupportedAddressTypes(v)
1472 }
1473 InitOptionPayloadRef::Unknown(opt_type, value) => {
1474 InitOption::Unknown(opt_type, Vec::from(value))
1475 }
1476 }
1477 }
1478}
1479
1480#[derive(Clone, Copy, Debug)]
1481pub struct InitOptionRef<'a> {
1482 data: &'a [u8],
1483}
1484
1485impl<'a> InitOptionRef<'a> {
1486 #[inline]
1487 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
1488 Self::validate(bytes)?;
1489 Ok(Self::from_bytes_unchecked(bytes))
1490 }
1491
1492 #[inline]
1493 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
1494 InitOptionRef { data: bytes }
1495 }
1496
1497 pub fn validate(bytes: &'a [u8]) -> Result<(), ValidationError> {
1498 let header = (utils::to_array(bytes, 0), utils::to_array(bytes, 2));
1499 match header {
1500 (Some(opt_type_arr), Some(unpadded_len_arr)) => {
1501 let opt_type = u16::from_be_bytes(opt_type_arr);
1502 let unpadded_len = u16::from_be_bytes(unpadded_len_arr);
1503 let len = utils::padded_length::<4>(unpadded_len as usize);
1504
1505 if bytes.len() < len {
1506 return Err(ValidationError {
1507 layer: SctpRef::name(),
1508 class: ValidationErrorClass::InsufficientBytes,
1509 #[cfg(feature = "error_string")]
1510 reason:
1511 "insufficient bytes in SCTP INIT option for payload + padding bytes",
1512 });
1513 }
1514
1515 let expected_unpadded_len = match opt_type {
1516 INIT_OPT_IPV4_ADDRESS => Some(8),
1517 INIT_OPT_IPV6_ADDRESS => Some(20),
1518 INIT_OPT_COOKIE_PRESERVATIVE => Some(8),
1519 _ => None,
1520 };
1521
1522 if let Some(e_len) = expected_unpadded_len {
1523 if unpadded_len != e_len {
1524 return Err(ValidationError {
1525 layer: SctpRef::name(),
1526 class: ValidationErrorClass::InvalidValue,
1527 #[cfg(feature = "error_string")]
1528 reason: "SCTP INIT option Length field didn't match expected length based on Option Type",
1529 });
1530 }
1531 }
1532
1533 if opt_type == INIT_OPT_SUPP_ADDR_TYPES && unpadded_len % 2 != 0 {
1534 return Err(ValidationError {
1535 layer: SctpRef::name(),
1536 class: ValidationErrorClass::InvalidValue,
1537 #[cfg(feature = "error_string")]
1538 reason: "SCTP INIT option payload had missing or trailing byte for Supported Address Types option",
1539 });
1540 }
1541
1542 if len < bytes.len() {
1543 Err(ValidationError {
1544 layer: SctpRef::name(),
1545 class: ValidationErrorClass::ExcessBytes(bytes.len() - len),
1546 #[cfg(feature = "error_string")]
1547 reason: "extra bytes remain at end of SCTP INIT option",
1548 })
1549 } else {
1550 Ok(())
1551 }
1552 }
1553 _ => Err(ValidationError {
1554 layer: SctpRef::name(),
1555 class: ValidationErrorClass::InsufficientBytes,
1556 #[cfg(feature = "error_string")]
1557 reason: "insufficient bytes in SCTP INIT option for header",
1558 }),
1559 }
1560 }
1561
1562 #[inline]
1563 pub fn opt_type(&self) -> u16 {
1564 u16::from_be_bytes(utils::to_array(self.data, 0).unwrap())
1565 }
1566
1567 #[inline]
1568 pub fn unpadded_len(&self) -> u16 {
1569 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
1570 }
1571
1572 #[inline]
1573 pub fn len(&self) -> usize {
1574 utils::padded_length::<4>(self.unpadded_len() as usize)
1575 }
1576
1577 pub fn payload(&self) -> InitOptionPayloadRef<'a> {
1578 match self.opt_type() {
1579 INIT_OPT_IPV4_ADDRESS => InitOptionPayloadRef::Ipv4Address(u32::from_be_bytes(
1580 utils::to_array(self.data, 4).unwrap(),
1581 )),
1582 INIT_OPT_IPV6_ADDRESS => InitOptionPayloadRef::Ipv6Address(u128::from_be_bytes(
1583 utils::to_array::<16>(self.data, 4).unwrap(),
1584 )),
1585 INIT_OPT_COOKIE_PRESERVATIVE => InitOptionPayloadRef::CookiePreservative(
1586 u32::from_be_bytes(utils::to_array(self.data, 4).unwrap()),
1587 ),
1588 INIT_OPT_HOSTNAME_ADDR => InitOptionPayloadRef::HostnameAddress(
1589 self.data
1590 .get(4..4 + self.unpadded_len().checked_sub(4).unwrap() as usize)
1591 .unwrap(),
1592 ),
1593 INIT_OPT_SUPP_ADDR_TYPES => InitOptionPayloadRef::SupportedAddressTypes(
1594 self.data
1595 .get(4..4 + self.unpadded_len().checked_sub(4).unwrap() as usize)
1596 .unwrap(),
1597 ),
1598 _ => InitOptionPayloadRef::Unknown(
1599 self.opt_type(),
1600 self.data
1601 .get(4..4 + self.unpadded_len().checked_sub(4).unwrap() as usize)
1602 .unwrap(),
1603 ),
1604 }
1605 }
1606}
1607
1608pub enum InitOptionPayloadRef<'a> {
1609 Ipv4Address(u32),
1610 Ipv6Address(u128),
1611 CookiePreservative(u32),
1612 HostnameAddress(&'a [u8]),
1613 SupportedAddressTypes(&'a [u8]),
1614 Unknown(u16, &'a [u8]),
1615}
1616
1617#[derive(Clone, Debug)]
1618#[cfg(feature = "alloc")]
1619pub struct InitAckChunk {
1620 flags: u8,
1621 init_tag: u32,
1622 a_rwnd: u32,
1623 ostreams: u16,
1624 istreams: u16,
1625 init_tsn: u32,
1626 options: Vec<InitAckOption>,
1627}
1628
1629#[cfg(feature = "alloc")]
1630impl InitAckChunk {
1631 #[inline]
1632 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
1633 Self::validate(bytes)?;
1634 Ok(Self::from_bytes_unchecked(bytes))
1635 }
1636
1637 #[inline]
1638 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
1639 Self::from(InitAckChunkRef::from_bytes_unchecked(bytes))
1640 }
1641
1642 #[inline]
1643 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
1644 InitAckChunkRef::validate(bytes)
1645 }
1646
1647 #[inline]
1648 pub fn chunk_type(&self) -> u8 {
1649 CHUNK_TYPE_INIT_ACK
1650 }
1651
1652 #[inline]
1653 pub fn flags_raw(&self) -> u8 {
1654 self.flags
1655 }
1656
1657 #[inline]
1658 pub fn set_flags_raw(&mut self, flags: u8) {
1659 self.flags = flags;
1660 }
1661
1662 #[inline]
1663 pub fn unpadded_len(&self) -> usize {
1664 20 + self.options.iter().map(|o| o.len()).sum::<usize>()
1665 }
1666
1667 #[inline]
1668 pub fn len(&self) -> usize {
1669 utils::padded_length::<4>(self.unpadded_len())
1670 }
1671
1672 #[inline]
1673 pub fn init_tag(&self) -> u32 {
1674 self.init_tag
1675 }
1676
1677 #[inline]
1678 pub fn set_init_tag(&mut self, init_tag: u32) {
1679 self.init_tag = init_tag;
1680 }
1681
1682 #[inline]
1683 pub fn a_rwnd(&self) -> u32 {
1684 self.a_rwnd
1685 }
1686
1687 #[inline]
1688 pub fn set_a_rwnd(&mut self, a_rwnd: u32) {
1689 self.a_rwnd = a_rwnd;
1690 }
1691
1692 #[inline]
1693 pub fn ostreams(&self) -> u16 {
1694 self.ostreams
1695 }
1696
1697 #[inline]
1698 pub fn set_ostreams(&mut self, ostreams: u16) {
1699 self.ostreams = ostreams;
1700 }
1701
1702 #[inline]
1703 pub fn istreams(&self) -> u16 {
1704 self.istreams
1705 }
1706
1707 #[inline]
1708 pub fn set_istreams(&mut self, istreams: u16) {
1709 self.istreams = istreams;
1710 }
1711
1712 #[inline]
1713 pub fn init_tsn(&self) -> u32 {
1714 self.init_tsn
1715 }
1716
1717 #[inline]
1718 pub fn set_init_tsn(&mut self, init_tsn: u32) {
1719 self.init_tsn = init_tsn;
1720 }
1721
1722 #[inline]
1723 pub fn options(&self) -> &Vec<InitAckOption> {
1724 &self.options
1725 }
1726
1727 #[inline]
1728 pub fn options_mut(&mut self) -> &mut Vec<InitAckOption> {
1729 &mut self.options
1730 }
1731
1732 pub fn to_bytes_extended<T: PacketWritable>(
1733 &self,
1734 writer: &mut PacketWriter<'_, T>,
1735 ) -> Result<(), SerializationError> {
1736 writer.write_slice(&[CHUNK_TYPE_INIT_ACK, self.flags])?;
1737 writer.write_slice(
1738 &u16::try_from(self.unpadded_len())
1739 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?
1740 .to_be_bytes(),
1741 )?;
1742 writer.write_slice(&self.init_tag.to_be_bytes())?;
1743 writer.write_slice(&self.a_rwnd.to_be_bytes())?;
1744 writer.write_slice(&self.ostreams.to_be_bytes())?;
1745 writer.write_slice(&self.istreams.to_be_bytes())?;
1746 writer.write_slice(&self.init_tsn.to_be_bytes())?;
1747 for option in &self.options {
1748 option.to_bytes_extended(writer)?;
1749 }
1750
1751 Ok(())
1752 }
1753}
1754
1755#[cfg(feature = "alloc")]
1756impl From<InitAckChunkRef<'_>> for InitAckChunk {
1757 #[inline]
1758 fn from(value: InitAckChunkRef<'_>) -> Self {
1759 Self::from(&value)
1760 }
1761}
1762
1763#[cfg(feature = "alloc")]
1764impl From<&InitAckChunkRef<'_>> for InitAckChunk {
1765 fn from(value: &InitAckChunkRef<'_>) -> Self {
1766 let mut options = Vec::new();
1767 let iter = value.options_iter();
1768 for option in iter {
1769 options.push(option.into());
1770 }
1771
1772 InitAckChunk {
1773 flags: value.flags_raw(),
1774 init_tag: value.init_tag(),
1775 a_rwnd: value.a_rwnd(),
1776 ostreams: value.ostreams(),
1777 istreams: value.istreams(),
1778 init_tsn: value.init_tsn(),
1779 options,
1780 }
1781 }
1782}
1783
1784#[derive(Clone, Copy, Debug)]
1785pub struct InitAckChunkRef<'a> {
1786 data: &'a [u8],
1787}
1788
1789impl<'a> InitAckChunkRef<'a> {
1790 #[inline]
1791 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
1792 Self::validate(bytes)?;
1793 Ok(Self::from_bytes_unchecked(bytes))
1794 }
1795
1796 #[inline]
1797 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
1798 InitAckChunkRef { data: bytes }
1799 }
1800
1801 pub fn validate(bytes: &'a [u8]) -> Result<(), ValidationError> {
1802 match utils::to_array(bytes, 2) {
1803 Some(unpadded_len_arr) => {
1804 let len = u16::from_be_bytes(unpadded_len_arr) as usize;
1805
1806 if bytes.len() < cmp::max(len, 20) {
1807 return Err(ValidationError {
1808 layer: SctpRef::name(),
1809 class: ValidationErrorClass::InsufficientBytes,
1810 #[cfg(feature = "error_string")]
1811 reason: "insufficient bytes in SCTP INIT ACK chunk for header and optional parameters",
1812 });
1813 }
1814
1815 if len % 4 != 0 {
1816 return Err(ValidationError {
1817 layer: SctpRef::name(),
1818 class: ValidationErrorClass::InvalidValue,
1819 #[cfg(feature = "error_string")]
1820 reason: "SCTP INIT ACK chunk length was not a multiple of 4",
1821 });
1822 }
1823
1824 if len < 20 {
1825 return Err(ValidationError {
1826 layer: SctpRef::name(),
1827 class: ValidationErrorClass::InvalidValue,
1828 #[cfg(feature = "error_string")]
1829 reason: "length field of SCTP INIT ACK chunk was too short for header",
1830 });
1831 }
1832
1833 let mut options = &bytes[20..];
1834 while !options.is_empty() {
1835 match InitAckOptionRef::validate(options) {
1836 Err(e) => {
1837 if let ValidationErrorClass::ExcessBytes(extra) = e.class {
1838 options = &options[options.len() - extra..];
1839 } else {
1840 return Err(e);
1841 }
1842 }
1843 _ => break,
1844 }
1845 }
1846
1847 if len < bytes.len() {
1848 Err(ValidationError {
1849 layer: SctpRef::name(),
1850 class: ValidationErrorClass::ExcessBytes(bytes.len() - len),
1851 #[cfg(feature = "error_string")]
1852 reason: "extra bytes remain at end of SCTP INIT ACK chunk",
1853 })
1854 } else {
1855 Ok(())
1856 }
1857 }
1858 _ => Err(ValidationError {
1859 layer: SctpRef::name(),
1860 class: ValidationErrorClass::InsufficientBytes,
1861 #[cfg(feature = "error_string")]
1862 reason: "insufficient bytes in SCTP INIT ACK chunk for header Length field",
1863 }),
1864 }
1865 }
1866
1867 #[inline]
1868 pub fn chunk_type(&self) -> u8 {
1869 self.data[0]
1870 }
1871
1872 #[inline]
1873 pub fn flags_raw(&self) -> u8 {
1874 self.data[1]
1875 }
1876
1877 #[inline]
1878 pub fn unpadded_len(&self) -> u16 {
1879 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
1880 }
1881
1882 #[inline]
1883 pub fn len(&self) -> usize {
1884 utils::padded_length::<4>(self.unpadded_len() as usize)
1885 }
1886
1887 #[inline]
1888 pub fn init_tag(&self) -> u32 {
1889 u32::from_be_bytes(utils::to_array(self.data, 4).unwrap())
1890 }
1891
1892 #[inline]
1893 pub fn a_rwnd(&self) -> u32 {
1894 u32::from_be_bytes(utils::to_array(self.data, 8).unwrap())
1895 }
1896
1897 #[inline]
1898 pub fn ostreams(&self) -> u16 {
1899 u16::from_be_bytes(utils::to_array(self.data, 12).unwrap())
1900 }
1901
1902 #[inline]
1903 pub fn istreams(&self) -> u16 {
1904 u16::from_be_bytes(utils::to_array(self.data, 14).unwrap())
1905 }
1906
1907 #[inline]
1908 pub fn init_tsn(&self) -> u32 {
1909 u32::from_be_bytes(utils::to_array(self.data, 16).unwrap())
1910 }
1911
1912 #[inline]
1913 pub fn options_iter(&self) -> InitAckOptionsIterRef<'a> {
1914 InitAckOptionsIterRef {
1915 bytes: &self.data[20..],
1916 }
1917 }
1918}
1919
1920#[derive(Clone, Copy, Debug)]
1921pub struct InitAckOptionsIterRef<'a> {
1922 bytes: &'a [u8],
1923}
1924
1925impl<'a> Iterator for InitAckOptionsIterRef<'a> {
1926 type Item = InitAckOptionRef<'a>;
1927
1928 fn next(&mut self) -> Option<Self::Item> {
1929 let (opt_type, unpadded_len) = match (
1930 utils::get_array(self.bytes, 0).map(|&a| u16::from_be_bytes(a)),
1931 utils::get_array(self.bytes, 2).map(|&a| u16::from_be_bytes(a)),
1932 ) {
1933 (Some(t), Some(l)) => (t, l),
1934 _ => return None,
1935 };
1936
1937 let min_len = match opt_type {
1938 INIT_ACK_OPT_IPV4_ADDRESS => 8,
1939 INIT_ACK_OPT_IPV6_ADDRESS => 20,
1940 INIT_ACK_OPT_HOSTNAME_ADDR
1941 | INIT_ACK_OPT_STATE_COOKIE
1942 | INIT_ACK_OPT_UNRECOGNIZED_PARAM => 4,
1943 _ => 4,
1944 };
1945
1946 if self.bytes.len() < min_len {
1947 self.bytes = &[]; return None;
1949 }
1950
1951 let len = cmp::max(min_len, utils::padded_length::<4>(unpadded_len as usize));
1952 match (self.bytes.get(..len), self.bytes.get(len..)) {
1953 (Some(opt_bytes), Some(rem)) => {
1954 self.bytes = rem;
1955 Some(InitAckOptionRef::from_bytes_unchecked(opt_bytes))
1956 }
1957 _ => {
1958 let opt_bytes = self.bytes;
1960 self.bytes = &[];
1961 Some(InitAckOptionRef::from_bytes_unchecked(opt_bytes))
1962 }
1963 }
1964 }
1965}
1966
1967#[derive(Clone, Debug)]
1968#[cfg(feature = "alloc")]
1969pub enum InitAckOption {
1970 StateCookie(Vec<u8>),
1971 Ipv4Address(u32),
1972 Ipv6Address(u128),
1973 UnrecognizedParameter(InitOption),
1974 HostnameAddress(Vec<u8>),
1975 Unknown(u16, Vec<u8>),
1976}
1977
1978#[cfg(feature = "alloc")]
1979impl InitAckOption {
1980 #[inline]
1981 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
1982 Self::validate(bytes)?;
1983 Ok(Self::from_bytes_unchecked(bytes))
1984 }
1985
1986 #[inline]
1987 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
1988 Self::from(InitAckOptionRef::from_bytes_unchecked(bytes))
1989 }
1990
1991 #[inline]
1992 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
1993 InitAckOptionRef::validate(bytes)
1994 }
1995
1996 pub fn option_type(&self) -> u16 {
1997 match self {
1998 Self::StateCookie(_) => INIT_ACK_OPT_STATE_COOKIE,
1999 Self::Ipv4Address(_) => INIT_ACK_OPT_IPV4_ADDRESS,
2000 Self::Ipv6Address(_) => INIT_ACK_OPT_IPV6_ADDRESS,
2001 Self::UnrecognizedParameter(_) => INIT_ACK_OPT_UNRECOGNIZED_PARAM,
2002 Self::HostnameAddress(_) => INIT_ACK_OPT_HOSTNAME_ADDR,
2003 Self::Unknown(t, _) => *t,
2004 }
2005 }
2006
2007 pub fn unpadded_len(&self) -> usize {
2008 match self {
2009 Self::StateCookie(s) => 4 + s.len(),
2010 Self::Ipv4Address(_) => 8,
2011 Self::Ipv6Address(_) => 20,
2012 Self::UnrecognizedParameter(p) => 4 + p.len(),
2013 Self::HostnameAddress(h) => 4 + h.len(),
2015 Self::Unknown(_, v) => 4 + v.len(),
2016 }
2017 }
2018
2019 #[inline]
2020 pub fn len(&self) -> usize {
2021 utils::padded_length::<4>(self.unpadded_len())
2022 }
2023
2024 pub fn to_bytes_extended<T: PacketWritable>(
2025 &self,
2026 writer: &mut PacketWriter<'_, T>,
2027 ) -> Result<(), SerializationError> {
2028 let unpadded_len = u16::try_from(self.unpadded_len())
2029 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?
2030 .to_be_bytes();
2031
2032 match self {
2033 InitAckOption::StateCookie(c) => {
2034 writer.write_slice(&INIT_ACK_OPT_STATE_COOKIE.to_be_bytes())?;
2035 writer.write_slice(&unpadded_len)?;
2036 writer.write_slice(c)?;
2037 for _ in self.unpadded_len()..self.len() {
2038 writer.write_slice(&[0])?;
2039 }
2040 }
2041 InitAckOption::Ipv4Address(ipv4) => {
2042 writer.write_slice(&INIT_ACK_OPT_IPV4_ADDRESS.to_be_bytes())?;
2043 writer.write_slice(&unpadded_len)?;
2044 writer.write_slice(&ipv4.to_be_bytes())?;
2045 }
2046 InitAckOption::Ipv6Address(ipv6) => {
2047 writer.write_slice(&INIT_ACK_OPT_IPV6_ADDRESS.to_be_bytes())?;
2048 writer.write_slice(&unpadded_len)?;
2049 writer.write_slice(&ipv6.to_be_bytes())?;
2050 }
2051 InitAckOption::UnrecognizedParameter(param) => {
2052 writer.write_slice(&INIT_ACK_OPT_UNRECOGNIZED_PARAM.to_be_bytes())?;
2053 writer.write_slice(&unpadded_len)?;
2054 param.to_bytes_extended(writer)?;
2055 }
2057 InitAckOption::HostnameAddress(host) => {
2058 writer.write_slice(&INIT_ACK_OPT_HOSTNAME_ADDR.to_be_bytes())?;
2059 writer.write_slice(&unpadded_len)?;
2060 writer.write_slice(&host)?;
2061 for _ in self.unpadded_len()..self.len() {
2062 writer.write_slice(&[0])?;
2063 }
2064 }
2065 InitAckOption::Unknown(t, v) => {
2066 writer.write_slice(&t.to_be_bytes())?;
2067 writer.write_slice(&unpadded_len)?;
2068 writer.write_slice(v)?;
2069 for _ in self.unpadded_len()..self.len() {
2070 writer.write_slice(&[0])?;
2071 }
2072 }
2073 }
2074
2075 Ok(())
2076 }
2077}
2078
2079#[cfg(feature = "alloc")]
2080impl From<InitAckOptionRef<'_>> for InitAckOption {
2081 #[inline]
2082 fn from(value: InitAckOptionRef<'_>) -> Self {
2083 Self::from(&value)
2084 }
2085}
2086
2087#[cfg(feature = "alloc")]
2088impl From<&InitAckOptionRef<'_>> for InitAckOption {
2089 fn from(value: &InitAckOptionRef<'_>) -> Self {
2090 match value.payload() {
2091 InitAckOptionPayloadRef::StateCookie(cookie) => {
2092 InitAckOption::StateCookie(Vec::from(cookie))
2093 }
2094 InitAckOptionPayloadRef::Ipv4Address(ipv4) => InitAckOption::Ipv4Address(ipv4),
2095 InitAckOptionPayloadRef::Ipv6Address(ipv6) => InitAckOption::Ipv6Address(ipv6),
2096 InitAckOptionPayloadRef::UnrecognizedParameter(param) => {
2097 InitAckOption::UnrecognizedParameter(param.into())
2098 }
2099 InitAckOptionPayloadRef::HostnameAddress(host) => {
2100 InitAckOption::HostnameAddress(Vec::from(host))
2101 }
2102 InitAckOptionPayloadRef::Unknown(t, v) => InitAckOption::Unknown(t, Vec::from(v)),
2103 }
2104 }
2105}
2106
2107#[derive(Clone, Copy, Debug)]
2108pub struct InitAckOptionRef<'a> {
2109 data: &'a [u8],
2110}
2111
2112impl<'a> InitAckOptionRef<'a> {
2113 #[inline]
2114 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
2115 Self::validate(bytes)?;
2116 Ok(Self::from_bytes_unchecked(bytes))
2117 }
2118
2119 #[inline]
2120 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
2121 InitAckOptionRef { data: bytes }
2122 }
2123
2124 pub fn validate(bytes: &'a [u8]) -> Result<(), ValidationError> {
2125 let header = (utils::to_array(bytes, 0), utils::to_array(bytes, 2));
2126 match header {
2127 (Some(opt_type_arr), Some(unpadded_len_arr)) => {
2128 let opt_type = u16::from_be_bytes(opt_type_arr);
2129 let unpadded_len = u16::from_be_bytes(unpadded_len_arr);
2130 let len = utils::padded_length::<4>(unpadded_len as usize);
2131
2132 if bytes.len() < cmp::max(len, 4) {
2133 return Err(ValidationError {
2134 layer: SctpRef::name(),
2135 class: ValidationErrorClass::InsufficientBytes,
2136 #[cfg(feature = "error_string")]
2137 reason:
2138 "insufficient bytes in SCTP INIT ACK option for payload + padding bytes",
2139 });
2140 }
2141
2142 let expected_unpadded_len = match opt_type {
2143 INIT_ACK_OPT_IPV4_ADDRESS => Some(8),
2144 INIT_ACK_OPT_IPV6_ADDRESS => Some(20),
2145 _ => None,
2146 };
2147
2148 if let Some(e_len) = expected_unpadded_len {
2149 if unpadded_len != e_len {
2150 return Err(ValidationError {
2151 layer: SctpRef::name(),
2152 class: ValidationErrorClass::InvalidValue,
2153 #[cfg(feature = "error_string")]
2154 reason: "SCTP INIT ACK option Length field didn't match expected length based on Option Type",
2155 });
2156 }
2157 } else if unpadded_len < 4 {
2158 return Err(ValidationError {
2159 layer: SctpRef::name(),
2160 class: ValidationErrorClass::InvalidValue,
2161 #[cfg(feature = "error_string")]
2162 reason: "SCTP INIT ACK option Length field too short to cover header",
2163 });
2164 }
2165
2166 if opt_type == INIT_ACK_OPT_UNRECOGNIZED_PARAM {
2167 match InitOptionRef::validate(&bytes[4..len]) {
2169 Ok(_) => (),
2170 Err(_) => return Err(ValidationError {
2171 layer: SctpRef::name(),
2172 class: ValidationErrorClass::InvalidValue,
2173 #[cfg(feature = "error_string")]
2174 reason: "SCTP INIT ACK Unrecognized Parameter Option had malformed INIT parameter in its payload",
2175 })
2176 };
2177 }
2178
2179 if len < bytes.len() {
2180 Err(ValidationError {
2181 layer: SctpRef::name(),
2182 class: ValidationErrorClass::ExcessBytes(bytes.len() - len),
2183 #[cfg(feature = "error_string")]
2184 reason: "extra bytes remain at end of SCTP INIT ACK Option",
2185 })
2186 } else {
2187 Ok(())
2188 }
2189 }
2190 _ => Err(ValidationError {
2191 layer: SctpRef::name(),
2192 class: ValidationErrorClass::InsufficientBytes,
2193 #[cfg(feature = "error_string")]
2194 reason: "insufficient bytes in SCTP INIT ACK Option for header",
2195 }),
2196 }
2197 }
2198
2199 #[inline]
2200 pub fn opt_type(&self) -> u16 {
2201 u16::from_be_bytes(utils::to_array(self.data, 0).unwrap())
2202 }
2203
2204 #[inline]
2205 pub fn unpadded_len(&self) -> u16 {
2206 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
2207 }
2208
2209 #[inline]
2210 pub fn len(&self) -> usize {
2211 utils::padded_length::<4>(self.unpadded_len() as usize)
2212 }
2213
2214 pub fn payload(&self) -> InitAckOptionPayloadRef<'a> {
2215 match self.opt_type() {
2216 INIT_ACK_OPT_IPV4_ADDRESS => InitAckOptionPayloadRef::Ipv4Address(u32::from_be_bytes(
2217 utils::to_array(self.data, 4).unwrap(),
2218 )),
2219 INIT_ACK_OPT_IPV6_ADDRESS => InitAckOptionPayloadRef::Ipv6Address(u128::from_be_bytes(
2220 utils::to_array::<16>(self.data, 4).unwrap(),
2221 )),
2222 INIT_ACK_OPT_HOSTNAME_ADDR => InitAckOptionPayloadRef::HostnameAddress(
2223 &self.data[4..self.unpadded_len() as usize],
2224 ),
2225 INIT_ACK_OPT_STATE_COOKIE => InitAckOptionPayloadRef::StateCookie(
2226 &self.data[4..4 + self.unpadded_len() as usize],
2227 ),
2228 INIT_ACK_OPT_UNRECOGNIZED_PARAM => InitAckOptionPayloadRef::UnrecognizedParameter(
2229 InitOptionRef::from_bytes_unchecked(&self.data[4..self.unpadded_len() as usize]),
2230 ),
2231 _ => InitAckOptionPayloadRef::Unknown(
2232 self.opt_type(),
2233 &self.data[4..self.unpadded_len() as usize],
2234 ),
2235 }
2236 }
2237}
2238
2239pub enum InitAckOptionPayloadRef<'a> {
2240 StateCookie(&'a [u8]),
2241 Ipv4Address(u32),
2242 Ipv6Address(u128),
2243 UnrecognizedParameter(InitOptionRef<'a>),
2244 HostnameAddress(&'a [u8]),
2245 Unknown(u16, &'a [u8]),
2246}
2247
2248#[derive(Clone, Debug)]
2249#[cfg(feature = "alloc")]
2250pub struct SackChunk {
2251 flags: u8,
2252 cum_tsn_ack: u32,
2253 a_rwnd: u32,
2254 gap_ack_blocks: Vec<(u16, u16)>,
2255 duplicate_tsns: Vec<u32>,
2256}
2257
2258#[cfg(feature = "alloc")]
2259impl SackChunk {
2260 #[inline]
2261 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
2262 Self::validate(bytes)?;
2263 Ok(Self::from_bytes_unchecked(bytes))
2264 }
2265
2266 #[inline]
2267 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
2268 Self::from(SackChunkRef::from_bytes_unchecked(bytes))
2269 }
2270
2271 #[inline]
2272 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
2273 SackChunkRef::validate(bytes)
2274 }
2275
2276 #[inline]
2277 pub fn chunk_type(&self) -> u8 {
2278 CHUNK_TYPE_SACK
2279 }
2280
2281 #[inline]
2282 pub fn flags_raw(&self) -> u8 {
2283 self.flags
2284 }
2285
2286 #[inline]
2287 pub fn set_flags_raw(&mut self, flags: u8) {
2288 self.flags = flags;
2289 }
2290
2291 #[inline]
2292 pub fn unpadded_len(&self) -> usize {
2293 16 + (self.gap_ack_blocks.len() * 4) + (self.duplicate_tsns.len() * 4)
2294 }
2295
2296 #[inline]
2297 pub fn len(&self) -> usize {
2298 utils::padded_length::<4>(self.unpadded_len())
2299 }
2300
2301 #[inline]
2302 pub fn ack(&self) -> u32 {
2303 self.cum_tsn_ack
2304 }
2305
2306 #[inline]
2307 pub fn set_ack(&mut self, ack: u32) {
2308 self.cum_tsn_ack = ack;
2309 }
2310
2311 #[inline]
2312 pub fn a_rwnd(&self) -> u32 {
2313 self.a_rwnd
2314 }
2315
2316 #[inline]
2317 pub fn set_a_rwnd(&mut self, a_rwnd: u32) {
2318 self.a_rwnd = a_rwnd;
2319 }
2320
2321 #[inline]
2322 pub fn gap_ack_blocks(&self) -> &Vec<(u16, u16)> {
2323 &self.gap_ack_blocks
2324 }
2325
2326 #[inline]
2327 pub fn gap_ack_blocks_mut(&mut self) -> &mut Vec<(u16, u16)> {
2328 &mut self.gap_ack_blocks
2329 }
2330
2331 #[inline]
2332 pub fn duplicate_tsns(&self) -> &Vec<u32> {
2333 &self.duplicate_tsns
2334 }
2335
2336 #[inline]
2337 pub fn duplicate_tsns_mut(&mut self) -> &mut Vec<u32> {
2338 &mut self.duplicate_tsns
2339 }
2340
2341 pub fn to_bytes_extended<T: PacketWritable>(
2342 &self,
2343 writer: &mut PacketWriter<'_, T>,
2344 ) -> Result<(), SerializationError> {
2345 writer.write_slice(&[CHUNK_TYPE_SACK])?;
2346 writer.write_slice(&[self.flags])?;
2347 writer.write_slice(
2348 &u16::try_from(self.unpadded_len())
2349 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?
2350 .to_be_bytes(),
2351 )?;
2352 writer.write_slice(&self.cum_tsn_ack.to_be_bytes())?;
2353 writer.write_slice(&self.a_rwnd.to_be_bytes())?;
2354 writer.write_slice(
2355 &u16::try_from(self.gap_ack_blocks.len())
2356 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?
2357 .to_be_bytes(),
2358 )?;
2359 writer.write_slice(
2360 &u16::try_from(self.duplicate_tsns.len())
2361 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?
2362 .to_be_bytes(),
2363 )?;
2364 for (gap_ack_start, gap_ack_end) in &self.gap_ack_blocks {
2365 writer.write_slice(&gap_ack_start.to_be_bytes())?;
2366 writer.write_slice(&gap_ack_end.to_be_bytes())?;
2367 }
2368
2369 for dup_tsn in &self.duplicate_tsns {
2370 writer.write_slice(&dup_tsn.to_be_bytes())?;
2371 }
2372 Ok(())
2375 }
2376}
2377
2378#[cfg(feature = "alloc")]
2379impl From<SackChunkRef<'_>> for SackChunk {
2380 #[inline]
2381 fn from(value: SackChunkRef<'_>) -> Self {
2382 Self::from(&value)
2383 }
2384}
2385
2386#[cfg(feature = "alloc")]
2387impl From<&SackChunkRef<'_>> for SackChunk {
2388 fn from(value: &SackChunkRef<'_>) -> Self {
2389 let mut gap_ack_blocks = Vec::new();
2390 for gap_ack in value.gap_ack_blocks_iter() {
2391 gap_ack_blocks.push(gap_ack);
2392 }
2393
2394 let mut duplicate_tsns = Vec::new();
2395 for dup_tsn in value.duplicate_tsn_iter() {
2396 duplicate_tsns.push(dup_tsn);
2397 }
2398
2399 SackChunk {
2400 flags: value.flags_raw(),
2401 cum_tsn_ack: value.ack(),
2402 a_rwnd: value.a_rwnd(),
2403 gap_ack_blocks,
2404 duplicate_tsns,
2405 }
2406 }
2407}
2408
2409#[derive(Clone, Copy, Debug)]
2410pub struct SackChunkRef<'a> {
2411 data: &'a [u8],
2412}
2413
2414impl<'a> SackChunkRef<'a> {
2415 #[inline]
2416 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
2417 Self::validate(bytes)?;
2418 Ok(Self::from_bytes_unchecked(bytes))
2419 }
2420
2421 #[inline]
2422 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
2423 SackChunkRef { data: bytes }
2424 }
2425
2426 pub fn validate(bytes: &'a [u8]) -> Result<(), ValidationError> {
2427 match utils::to_array(bytes, 2) {
2428 Some(unpadded_len_arr) => {
2429 let len = u16::from_be_bytes(unpadded_len_arr) as usize;
2430
2431 if bytes.len() < cmp::max(len, 16) {
2432 return Err(ValidationError {
2433 layer: SctpRef::name(),
2434 class: ValidationErrorClass::InsufficientBytes,
2435 #[cfg(feature = "error_string")]
2436 reason: "insufficient bytes in SCTP SACK chunk for header and optional parameters",
2437 });
2438 }
2439
2440 if len % 4 != 0 {
2441 return Err(ValidationError {
2442 layer: SctpRef::name(),
2443 class: ValidationErrorClass::InvalidValue,
2444 #[cfg(feature = "error_string")]
2445 reason: "SCTP SACK chunk length must be a multiple of 4",
2446 });
2447 }
2448
2449 if len < 16 {
2450 return Err(ValidationError {
2451 layer: SctpRef::name(),
2452 class: ValidationErrorClass::InvalidValue,
2453 #[cfg(feature = "error_string")]
2454 reason: "length field of SCTP SACK chunk was too short for header",
2455 });
2456 }
2457
2458 let (gap_ack_cnt, dup_tsn_cnt) = match (utils::to_array(bytes, 12), utils::to_array(bytes, 14)) {
2459 (Some(gap_ack_cnt_arr), Some(dup_tsn_cnt_arr)) => (u16::from_be_bytes(gap_ack_cnt_arr) as usize, u16::from_be_bytes(dup_tsn_cnt_arr) as usize),
2460 _ => return Err(ValidationError {
2461 layer: SctpRef::name(),
2462 class: ValidationErrorClass::InsufficientBytes,
2463 #[cfg(feature = "error_string")]
2464 reason: "insufficient bytes in SCTP SACK chunk for Number of Duplicate TSNs field"
2465 })
2466 };
2467
2468 if 16 + (gap_ack_cnt * 4) + (dup_tsn_cnt * 4) != len {
2469 return Err(ValidationError {
2470 layer: SctpRef::name(),
2471 class: ValidationErrorClass::InvalidValue,
2472 #[cfg(feature = "error_string")]
2473 reason: "SCTP SACK chunk Length field did not match the total length of header + Gap Ack Blocks + Duplicate TSNs"
2474 });
2475 }
2476
2477 if len < bytes.len() {
2478 Err(ValidationError {
2479 layer: SctpRef::name(),
2480 class: ValidationErrorClass::ExcessBytes(bytes.len() - len),
2481 #[cfg(feature = "error_string")]
2482 reason: "extra bytes remain at end of SCTP SACK chunk",
2483 })
2484 } else {
2485 Ok(())
2486 }
2487 }
2488 _ => Err(ValidationError {
2489 layer: SctpRef::name(),
2490 class: ValidationErrorClass::InsufficientBytes,
2491 #[cfg(feature = "error_string")]
2492 reason: "insufficient bytes in SCTP SACK chunk for header Length field",
2493 }),
2494 }
2495 }
2496
2497 #[inline]
2498 pub fn chunk_type(&self) -> u8 {
2499 self.data[0]
2500 }
2501
2502 #[inline]
2503 pub fn flags_raw(&self) -> u8 {
2504 self.data[1]
2505 }
2506
2507 #[inline]
2508 pub fn unpadded_len(&self) -> u16 {
2509 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
2510 }
2511
2512 #[inline]
2513 pub fn len(&self) -> usize {
2514 utils::padded_length::<4>(self.unpadded_len() as usize)
2515 }
2516
2517 #[inline]
2518 pub fn ack(&self) -> u32 {
2519 u32::from_be_bytes(utils::to_array(self.data, 4).unwrap())
2520 }
2521
2522 #[inline]
2523 pub fn a_rwnd(&self) -> u32 {
2524 u32::from_be_bytes(utils::to_array(self.data, 8).unwrap())
2525 }
2526
2527 #[inline]
2528 pub fn gap_ack_block_cnt(&self) -> u16 {
2529 u16::from_be_bytes(utils::to_array(self.data, 12).unwrap())
2530 }
2531
2532 #[inline]
2533 pub fn dup_tsn_cnt(&self) -> u16 {
2534 u16::from_be_bytes(utils::to_array(self.data, 14).unwrap())
2535 }
2536
2537 #[inline]
2538 pub fn gap_ack_blocks_iter(&self) -> GapAckBlockIterRef<'a> {
2539 GapAckBlockIterRef {
2540 bytes: &self.data[16..],
2541 block_idx: 0,
2542 block_total: self.gap_ack_block_cnt() as usize,
2543 }
2544 }
2545
2546 #[inline]
2547 pub fn duplicate_tsn_iter(&self) -> DuplicateTsnIterRef {
2548 DuplicateTsnIterRef {
2549 bytes: &self.data[16 + (4 * self.gap_ack_block_cnt() as usize)..],
2550 tsn_idx: 0,
2551 tsn_total: self.dup_tsn_cnt() as usize,
2552 }
2553 }
2554}
2555
2556#[derive(Clone, Copy, Debug)]
2557pub struct GapAckBlockIterRef<'a> {
2558 bytes: &'a [u8],
2559 block_idx: usize,
2560 block_total: usize,
2561}
2562
2563impl<'b> Iterator for GapAckBlockIterRef<'b> {
2564 type Item = (u16, u16);
2565
2566 fn next(&mut self) -> Option<Self::Item> {
2567 if self.block_idx == self.block_total {
2568 return None;
2569 }
2570
2571 let start = u16::from_be_bytes(utils::to_array(self.bytes, 0).unwrap());
2572 let end = u16::from_be_bytes(utils::to_array(self.bytes, 2).unwrap());
2573 self.bytes = &self.bytes[4..];
2574 self.block_idx += 1;
2575
2576 Some((start, end))
2577 }
2578}
2579
2580#[derive(Clone, Copy, Debug)]
2581pub struct DuplicateTsnIterRef<'a> {
2582 bytes: &'a [u8],
2583 tsn_idx: usize,
2584 tsn_total: usize,
2585}
2586
2587impl<'b> Iterator for DuplicateTsnIterRef<'b> {
2588 type Item = u32;
2589
2590 fn next(&mut self) -> Option<Self::Item> {
2591 if self.tsn_idx == self.tsn_total {
2592 return None;
2593 }
2594
2595 let dup_tsn = u32::from_be_bytes(utils::to_array(self.bytes, 0).unwrap());
2596 self.bytes = &self.bytes[4..];
2597 self.tsn_idx += 1;
2598
2599 Some(dup_tsn)
2600 }
2601}
2602
2603#[derive(Clone, Debug)]
2604#[cfg(feature = "alloc")]
2605pub struct HeartbeatChunk {
2606 flags: u8,
2607 heartbeat: Vec<u8>,
2608}
2609
2610#[cfg(feature = "alloc")]
2611impl HeartbeatChunk {
2612 #[inline]
2613 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
2614 Self::validate(bytes)?;
2615 Ok(Self::from_bytes_unchecked(bytes))
2616 }
2617
2618 #[inline]
2619 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
2620 Self::from(HeartbeatChunkRef::from_bytes_unchecked(bytes))
2621 }
2622
2623 #[inline]
2624 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
2625 HeartbeatChunkRef::validate(bytes)
2626 }
2627
2628 #[inline]
2629 pub fn chunk_type(&self) -> u8 {
2630 CHUNK_TYPE_HEARTBEAT
2631 }
2632
2633 #[inline]
2634 pub fn flags(&self) -> u8 {
2635 self.flags
2636 }
2637
2638 #[inline]
2639 pub fn unpadded_len(&self) -> usize {
2640 8 + self.heartbeat.len()
2641 }
2642
2643 #[inline]
2644 pub fn len(&self) -> usize {
2645 utils::padded_length::<4>(self.unpadded_len())
2646 }
2647
2648 #[inline]
2649 pub fn heartbeat(&self) -> &Vec<u8> {
2650 &self.heartbeat
2651 }
2652
2653 #[inline]
2654 pub fn heartbeat_mut(&mut self) -> &mut Vec<u8> {
2655 &mut self.heartbeat
2656 }
2657
2658 pub fn to_bytes_extended<T: PacketWritable>(
2659 &self,
2660 writer: &mut PacketWriter<'_, T>,
2661 ) -> Result<(), SerializationError> {
2662 writer.write_slice(&[CHUNK_TYPE_HEARTBEAT, self.flags])?;
2663 writer.write_slice(
2664 &u16::try_from(self.unpadded_len())
2665 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?
2666 .to_be_bytes(),
2667 )?;
2668 writer.write_slice(&1u16.to_be_bytes())?; writer.write_slice(
2670 &u16::try_from(self.heartbeat.len())
2671 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?
2672 .to_be_bytes(),
2673 )?;
2674 writer.write_slice(&self.heartbeat)?;
2675 for _ in self.unpadded_len()..self.len() {
2676 writer.write_slice(&[0])?;
2677 }
2678
2679 Ok(())
2680 }
2681}
2682
2683#[cfg(feature = "alloc")]
2684impl From<HeartbeatChunkRef<'_>> for HeartbeatChunk {
2685 #[inline]
2686 fn from(value: HeartbeatChunkRef<'_>) -> Self {
2687 Self::from(&value)
2688 }
2689}
2690
2691#[cfg(feature = "alloc")]
2692impl From<&HeartbeatChunkRef<'_>> for HeartbeatChunk {
2693 #[inline]
2694 fn from(value: &HeartbeatChunkRef<'_>) -> Self {
2695 HeartbeatChunk {
2696 flags: value.flags_raw(),
2697 heartbeat: Vec::from(value.heartbeat_info().heartbeat()),
2698 }
2699 }
2700}
2701
2702#[derive(Clone, Copy, Debug)]
2703pub struct HeartbeatChunkRef<'a> {
2704 data: &'a [u8],
2705}
2706
2707impl<'a> HeartbeatChunkRef<'a> {
2708 #[inline]
2709 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
2710 Self::validate(bytes)?;
2711 Ok(Self::from_bytes_unchecked(bytes))
2712 }
2713
2714 #[inline]
2715 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
2716 HeartbeatChunkRef { data: bytes }
2717 }
2718
2719 pub fn validate(bytes: &'a [u8]) -> Result<(), ValidationError> {
2720 match utils::to_array(bytes, 2) {
2721 Some(unpadded_len_arr) => {
2722 let unpadded_len = u16::from_be_bytes(unpadded_len_arr) as usize;
2723 let len = utils::padded_length::<4>(unpadded_len);
2724
2725 if bytes.len() < cmp::max(len, 8) {
2726 return Err(ValidationError {
2727 layer: SctpRef::name(),
2728 class: ValidationErrorClass::InsufficientBytes,
2729 #[cfg(feature = "error_string")]
2730 reason: "insufficient bytes in SCTP HEARTBEAT chunk for header + Heartbeat Info option",
2731 });
2732 }
2733
2734 #[allow(unused_variables)]
2735 if let Err(e) = HeartbeatInfoRef::validate(&bytes[4..len]) {
2736 return Err(ValidationError {
2737 layer: SctpRef::name(),
2738 class: ValidationErrorClass::InvalidValue,
2739 #[cfg(feature = "error_string")]
2740 reason: e.reason,
2741 });
2742 }
2743
2744 for b in bytes.iter().take(len).skip(unpadded_len) {
2745 if *b != 0 {
2746 return Err(ValidationError {
2747 layer: SctpRef::name(),
2748 class: ValidationErrorClass::InvalidValue,
2749 #[cfg(feature = "error_string")]
2750 reason: "invalid nonzero padding values at end of SCTP HEARTBEAT chunk",
2751 });
2752 }
2753 }
2754
2755 if len < bytes.len() {
2756 Err(ValidationError {
2757 layer: SctpRef::name(),
2758 class: ValidationErrorClass::ExcessBytes(bytes.len() - len),
2759 #[cfg(feature = "error_string")]
2760 reason: "extra bytes remain at end of SCTP HEARTBEAT chunk",
2761 })
2762 } else {
2763 Ok(())
2764 }
2765 }
2766 _ => Err(ValidationError {
2767 layer: SctpRef::name(),
2768 class: ValidationErrorClass::InsufficientBytes,
2769 #[cfg(feature = "error_string")]
2770 reason: "insufficient bytes in SCTP HEARTBEAT chunk for header",
2771 }),
2772 }
2773 }
2774
2775 #[inline]
2776 pub fn chunk_type(&self) -> u8 {
2777 self.data[0]
2778 }
2779
2780 #[inline]
2781 pub fn flags_raw(&self) -> u8 {
2782 self.data[1]
2783 }
2784
2785 #[inline]
2786 pub fn unpadded_len(&self) -> u16 {
2787 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
2788 }
2789
2790 #[inline]
2791 pub fn len(&self) -> usize {
2792 utils::padded_length::<4>(self.unpadded_len() as usize)
2793 }
2794
2795 #[inline]
2796 pub fn heartbeat_info(&self) -> HeartbeatInfoRef<'a> {
2797 HeartbeatInfoRef {
2798 data: self.data.get(4..).unwrap(),
2799 }
2800 }
2801}
2802
2803#[derive(Clone, Copy, Debug)]
2804pub struct HeartbeatInfoRef<'a> {
2805 data: &'a [u8],
2806}
2807
2808impl<'a> HeartbeatInfoRef<'a> {
2809 #[inline]
2810 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
2811 Self::validate(bytes)?;
2812 Ok(Self::from_bytes_unchecked(bytes))
2813 }
2814
2815 #[inline]
2816 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
2817 HeartbeatInfoRef { data: bytes }
2818 }
2819
2820 pub fn validate(bytes: &'a [u8]) -> Result<(), ValidationError> {
2821 match utils::to_array(bytes, 2) {
2822 Some(unpadded_len_arr) => {
2823 let unpadded_len = u16::from_be_bytes(unpadded_len_arr);
2824 let len = utils::padded_length::<4>(unpadded_len as usize);
2825
2826 if len > bytes.len() {
2827 return Err(ValidationError {
2828 layer: SctpRef::name(),
2829 class: ValidationErrorClass::InsufficientBytes,
2830 #[cfg(feature = "error_string")]
2831 reason: "insufficient bytes in SCTP HEARTBEAT chunk Heartbeat Info option for Heartbeat field + padding bytes",
2832 });
2833 }
2834
2835 if len < bytes.len() {
2836 Err(ValidationError {
2837 layer: SctpRef::name(),
2838 class: ValidationErrorClass::ExcessBytes(bytes.len() - len),
2839 #[cfg(feature = "error_string")]
2840 reason: "extra bytes remain at end of SCTP HEARTBEAT chunk Heartbeat Info option",
2841 })
2842 } else {
2843 Ok(())
2844 }
2845 }
2846 _ => Err(ValidationError {
2847 layer: SctpRef::name(),
2848 class: ValidationErrorClass::InsufficientBytes,
2849 #[cfg(feature = "error_string")]
2850 reason:
2851 "insufficient bytes in SCTP HEARTBEAT chunk Heartbeat Info option for header",
2852 }),
2853 }
2854 }
2855
2856 #[inline]
2857 pub fn opt_type(&self) -> u16 {
2858 u16::from_be_bytes(utils::to_array(self.data, 0).unwrap())
2859 }
2860
2861 #[inline]
2862 pub fn unpadded_len(&self) -> u16 {
2863 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
2864 }
2865
2866 #[inline]
2867 pub fn len(&self) -> usize {
2868 utils::padded_length::<4>(self.unpadded_len() as usize)
2869 }
2870
2871 #[inline]
2872 pub fn heartbeat(&self) -> &'a [u8] {
2873 &self.data[4..self.unpadded_len() as usize]
2874 }
2875}
2876
2877#[derive(Clone, Debug)]
2878#[cfg(feature = "alloc")]
2879pub struct HeartbeatAckChunk {
2880 flags: u8,
2881 heartbeat: Vec<u8>,
2882}
2883
2884#[cfg(feature = "alloc")]
2885impl HeartbeatAckChunk {
2886 #[inline]
2887 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
2888 Self::validate(bytes)?;
2889 Ok(Self::from_bytes_unchecked(bytes))
2890 }
2891
2892 #[inline]
2893 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
2894 Self::from(HeartbeatAckChunkRef::from_bytes_unchecked(bytes))
2895 }
2896
2897 #[inline]
2898 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
2899 HeartbeatAckChunkRef::validate(bytes)
2900 }
2901
2902 #[inline]
2903 pub fn chunk_type(&self) -> u8 {
2904 CHUNK_TYPE_HEARTBEAT_ACK
2905 }
2906
2907 #[inline]
2908 pub fn flags(&self) -> u8 {
2909 self.flags
2910 }
2911
2912 #[inline]
2913 pub fn unpadded_len(&self) -> usize {
2914 8 + self.heartbeat.len()
2915 }
2916
2917 #[inline]
2918 pub fn len(&self) -> usize {
2919 utils::padded_length::<4>(self.unpadded_len())
2920 }
2921
2922 #[inline]
2923 pub fn heartbeat(&self) -> &Vec<u8> {
2924 &self.heartbeat
2925 }
2926
2927 #[inline]
2928 pub fn heartbeat_mut(&mut self) -> &mut Vec<u8> {
2929 &mut self.heartbeat
2930 }
2931
2932 pub fn to_bytes_extended<T: PacketWritable>(
2933 &self,
2934 writer: &mut PacketWriter<'_, T>,
2935 ) -> Result<(), SerializationError> {
2936 writer.write_slice(&[CHUNK_TYPE_HEARTBEAT_ACK, self.flags])?;
2937 writer.write_slice(
2938 &u16::try_from(self.unpadded_len())
2939 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?
2940 .to_be_bytes(),
2941 )?;
2942 writer.write_slice(&1u16.to_be_bytes())?; writer.write_slice(
2944 &u16::try_from(self.heartbeat.len())
2945 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?
2946 .to_be_bytes(),
2947 )?;
2948 writer.write_slice(&self.heartbeat)?;
2949 for _ in self.unpadded_len()..self.len() {
2950 writer.write_slice(&[0])?;
2951 }
2952
2953 Ok(())
2954 }
2955}
2956
2957#[cfg(feature = "alloc")]
2958impl From<HeartbeatAckChunkRef<'_>> for HeartbeatAckChunk {
2959 #[inline]
2960 fn from(value: HeartbeatAckChunkRef<'_>) -> Self {
2961 Self::from(&value)
2962 }
2963}
2964
2965#[cfg(feature = "alloc")]
2966impl From<&HeartbeatAckChunkRef<'_>> for HeartbeatAckChunk {
2967 #[inline]
2968 fn from(value: &HeartbeatAckChunkRef<'_>) -> Self {
2969 HeartbeatAckChunk {
2970 flags: value.flags_raw(),
2971 heartbeat: Vec::from(value.heartbeat_info().heartbeat()),
2972 }
2973 }
2974}
2975
2976#[derive(Clone, Copy, Debug)]
2977pub struct HeartbeatAckChunkRef<'a> {
2978 data: &'a [u8],
2979}
2980
2981impl<'a> HeartbeatAckChunkRef<'a> {
2982 #[inline]
2983 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
2984 Self::validate(bytes)?;
2985 Ok(Self::from_bytes_unchecked(bytes))
2986 }
2987
2988 #[inline]
2989 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
2990 HeartbeatAckChunkRef { data: bytes }
2991 }
2992
2993 pub fn validate(bytes: &'a [u8]) -> Result<(), ValidationError> {
2994 match utils::to_array(bytes, 2) {
2995 Some(unpadded_len_arr) => {
2996 let len = u16::from_be_bytes(unpadded_len_arr) as usize;
2997
2998 if len > bytes.len() {
2999 return Err(ValidationError {
3000 layer: SctpRef::name(),
3001 class: ValidationErrorClass::InsufficientBytes,
3002 #[cfg(feature = "error_string")]
3003 reason: "insufficient bytes in SCTP HEARTBEAT ACK chunk for header + Heartbeat field",
3004 });
3005 }
3006
3007 if len % 4 != 0 {
3008 return Err(ValidationError {
3009 layer: SctpRef::name(),
3010 class: ValidationErrorClass::InvalidValue,
3011 #[cfg(feature = "error_string")]
3012 reason: "SCTP HEARTBEAT ACK chunk length was not a multiple of 4",
3013 });
3014 }
3015
3016 HeartbeatInfoRef::validate(&bytes[4..len])?;
3017
3018 if len < bytes.len() {
3019 Err(ValidationError {
3020 layer: SctpRef::name(),
3021 class: ValidationErrorClass::ExcessBytes(bytes.len() - len),
3022 #[cfg(feature = "error_string")]
3023 reason: "extra bytes remain at end of SCTP HEARTBEAT ACK chunk",
3024 })
3025 } else {
3026 Ok(())
3027 }
3028 }
3029 _ => Err(ValidationError {
3030 layer: SctpRef::name(),
3031 class: ValidationErrorClass::InsufficientBytes,
3032 #[cfg(feature = "error_string")]
3033 reason: "insufficient bytes in SCTP HEARTBEAT ACK chunk for header",
3034 }),
3035 }
3036 }
3037
3038 #[inline]
3039 pub fn chunk_type(&self) -> u8 {
3040 self.data[0]
3041 }
3042
3043 #[inline]
3044 pub fn flags_raw(&self) -> u8 {
3045 self.data[1]
3046 }
3047
3048 #[inline]
3049 pub fn unpadded_len(&self) -> u16 {
3050 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
3051 }
3052
3053 #[inline]
3054 pub fn len(&self) -> usize {
3055 utils::padded_length::<4>(self.unpadded_len() as usize)
3056 }
3057
3058 #[inline]
3059 pub fn heartbeat_info(&self) -> HeartbeatInfoRef<'a> {
3060 HeartbeatInfoRef::from_bytes_unchecked(&self.data[4..])
3061 }
3062}
3063
3064#[derive(Clone, Debug)]
3066#[cfg(feature = "alloc")]
3067pub struct AbortChunk {
3068 flags: AbortFlags,
3069 causes: Vec<ErrorCause>,
3070}
3071
3072#[cfg(feature = "alloc")]
3073impl AbortChunk {
3074 #[inline]
3075 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
3076 Self::validate(bytes)?;
3077 Ok(Self::from_bytes_unchecked(bytes))
3078 }
3079
3080 #[inline]
3081 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
3082 Self::from(AbortChunkRef::from_bytes_unchecked(bytes))
3083 }
3084
3085 #[inline]
3086 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
3087 ErrorChunkRef::validate(bytes)
3088 }
3089
3090 #[inline]
3091 pub fn chunk_type(&self) -> u8 {
3092 CHUNK_TYPE_ABORT
3093 }
3094
3095 #[inline]
3096 pub fn flags(&self) -> AbortFlags {
3097 self.flags
3098 }
3099
3100 #[inline]
3101 pub fn set_flags(&mut self, flags: AbortFlags) {
3102 self.flags = flags;
3103 }
3104
3105 #[inline]
3106 pub fn unpadded_len(&self) -> usize {
3107 4 + self.causes.iter().map(|c| c.len()).sum::<usize>()
3108 }
3109
3110 #[inline]
3111 pub fn len(&self) -> usize {
3112 utils::padded_length::<4>(self.unpadded_len())
3113 }
3114
3115 #[inline]
3116 pub fn causes(&self) -> &Vec<ErrorCause> {
3117 &self.causes
3118 }
3119
3120 #[inline]
3121 pub fn set_causes(&mut self) -> &mut Vec<ErrorCause> {
3122 &mut self.causes
3123 }
3124
3125 #[inline]
3126 pub fn to_bytes_extended<T: PacketWritable>(
3127 &self,
3128 writer: &mut PacketWriter<'_, T>,
3129 ) -> Result<(), SerializationError> {
3130 writer.write_slice(&[CHUNK_TYPE_ABORT])?;
3131 writer.write_slice(&[self.flags.bits()])?;
3132 writer.write_slice(
3133 &u16::try_from(self.unpadded_len())
3134 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?
3135 .to_be_bytes(),
3136 )?;
3137 for cause in &self.causes {
3138 cause.to_bytes_extended(writer)?;
3139 }
3140
3141 Ok(())
3142 }
3143}
3144
3145#[cfg(feature = "alloc")]
3146impl From<AbortChunkRef<'_>> for AbortChunk {
3147 #[inline]
3148 fn from(value: AbortChunkRef<'_>) -> Self {
3149 Self::from(&value)
3150 }
3151}
3152
3153#[cfg(feature = "alloc")]
3154impl From<&AbortChunkRef<'_>> for AbortChunk {
3155 fn from(value: &AbortChunkRef<'_>) -> Self {
3156 let mut causes = Vec::new();
3157 let iter = value.error_iter();
3158 for error in iter {
3159 causes.push(error.into());
3160 }
3161
3162 AbortChunk {
3163 flags: value.flags(),
3164 causes,
3165 }
3166 }
3167}
3168
3169#[derive(Clone, Copy, Debug)]
3171pub struct AbortChunkRef<'a> {
3172 data: &'a [u8],
3173}
3174
3175impl<'a> AbortChunkRef<'a> {
3176 #[inline]
3177 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
3178 Self::validate(bytes)?;
3179 Ok(Self::from_bytes_unchecked(bytes))
3180 }
3181
3182 #[inline]
3183 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
3184 AbortChunkRef { data: bytes }
3185 }
3186
3187 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
3188 match (bytes.first(), utils::to_array(bytes, 2)) {
3189 (Some(&chunk_type), Some(len_arr)) => {
3190 let len = u16::from_be_bytes(len_arr) as usize;
3191 if bytes.len() < cmp::max(4, len) {
3192 return Err(ValidationError {
3193 layer: SctpRef::name(),
3194 class: ValidationErrorClass::InsufficientBytes,
3195 #[cfg(feature = "error_string")]
3196 reason:
3197 "insufficient bytes in SCTP ABORT chunk for header + Error Cause fields",
3198 });
3199 }
3200
3201 if chunk_type != CHUNK_TYPE_ABORT {
3202 return Err(ValidationError {
3203 layer: SctpRef::name(),
3204 class: ValidationErrorClass::InvalidValue,
3205 #[cfg(feature = "error_string")]
3206 reason: "invalid Chunk Type field in SCTP ABORT chunk (must be equal to 6)",
3207 });
3208 }
3209
3210 if bytes.len() > 4 {
3211 Err(ValidationError {
3212 layer: SctpRef::name(),
3213 class: ValidationErrorClass::ExcessBytes(bytes.len() - len),
3214 #[cfg(feature = "error_string")]
3215 reason: "extra bytes remain at end of SCTP ABORT chunk",
3216 })
3217 } else {
3218 Ok(())
3219 }
3220 }
3221 _ => Err(ValidationError {
3222 layer: SctpRef::name(),
3223 class: ValidationErrorClass::InsufficientBytes,
3224 #[cfg(feature = "error_string")]
3225 reason: "insufficient bytes in SCTP ABORT chunk for header",
3226 }),
3227 }
3228 }
3229
3230 #[inline]
3231 pub fn chunk_type(&self) -> u8 {
3232 self.data[0]
3233 }
3234
3235 #[inline]
3236 pub fn flags(&self) -> AbortFlags {
3237 AbortFlags::from_bits_truncate(self.flags_raw())
3238 }
3239
3240 #[inline]
3241 pub fn flags_raw(&self) -> u8 {
3242 self.data[1]
3243 }
3244
3245 #[inline]
3246 pub fn unpadded_len(&self) -> u16 {
3247 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
3248 }
3249
3250 #[inline]
3251 pub fn len(&self) -> usize {
3252 utils::padded_length::<4>(self.unpadded_len() as usize)
3253 }
3254
3255 #[inline]
3256 pub fn error_iter(&self) -> ErrorCauseIterRef {
3257 ErrorCauseIterRef {
3258 bytes: &self.data[4..self.unpadded_len() as usize],
3259 }
3260 }
3261}
3262
3263#[derive(Clone, Copy, Debug)]
3264pub struct ErrorCauseIterRef<'a> {
3265 bytes: &'a [u8],
3266}
3267
3268impl<'a> Iterator for ErrorCauseIterRef<'a> {
3269 type Item = ErrorCauseRef<'a>;
3270
3271 fn next(&mut self) -> Option<Self::Item> {
3272 let (err_type, unpadded_len) = match (
3273 utils::get_array(self.bytes, 0).map(|&a| u16::from_be_bytes(a)),
3274 utils::get_array(self.bytes, 2).map(|&a| u16::from_be_bytes(a)),
3275 ) {
3276 (Some(t), Some(l)) => (t, l),
3277 _ => return None,
3278 };
3279
3280 let min_len = match err_type {
3281 ERR_CODE_INVALID_STREAM_ID | ERR_CODE_STALE_COOKIE | ERR_CODE_NO_USER_DATA => 8,
3282 ERR_CODE_MISSING_MAND_PARAM => 8, ERR_CODE_OUT_OF_RESOURCE
3284 | ERR_CODE_UNRESOLVABLE_ADDRESS
3285 | ERR_CODE_UNRECOGNIZED_CHUNK
3286 | ERR_CODE_INVALID_MAND_PARAM
3287 | ERR_CODE_UNRECOGNIZED_PARAMS
3288 | ERR_CODE_COOKIE_RCVD_SHUTTING_DOWN
3289 | ERR_CODE_RESTART_ASSOC_NEW_ADDR
3290 | ERR_CODE_USER_INITIATED_ABORT
3291 | ERR_CODE_PROTOCOL_VIOLATION => 4,
3292 _ => 4,
3293 };
3294
3295 if self.bytes.len() < min_len {
3296 self.bytes = &[]; return None;
3298 }
3299
3300 let len = cmp::max(min_len, utils::padded_length::<4>(unpadded_len as usize));
3301 match (self.bytes.get(..len), self.bytes.get(len..)) {
3302 (Some(err_bytes), Some(rem)) => {
3303 self.bytes = rem;
3304 Some(ErrorCauseRef::from_bytes_unchecked(err_bytes))
3305 }
3306 _ => {
3307 let err_bytes = self.bytes;
3309 self.bytes = &[];
3310 Some(ErrorCauseRef::from_bytes_unchecked(err_bytes))
3311 }
3312 }
3313 }
3314}
3315
3316#[derive(Clone, Debug)]
3317#[cfg(feature = "alloc")]
3318pub enum ErrorCause {
3319 InvalidStreamIdentifier(StreamIdentifierError),
3320
3321 MissingMandatoryParameter(MissingParameterError),
3322
3323 StaleCookie(StaleCookieError),
3324
3325 OutOfResource,
3326
3327 UnresolvableAddress(UnresolvableAddrError),
3328
3329 UnrecognizedChunkType(UnrecognizedChunkError),
3330
3331 UnrecognizedParameters(UnrecognizedParamError),
3332
3333 InvalidMandatoryParameter,
3334
3335 NoUserData(NoUserDataError),
3336
3337 CookieDuringShutdown,
3338
3339 AssociationNewAddress(AssociationNewAddrError),
3340
3341 UserInitiatedAbort(UserInitiatedAbortError),
3342
3343 ProtocolViolation(ProtocolViolationError),
3344
3345 Unknown(GenericParam),
3347}
3348
3349#[cfg(feature = "alloc")]
3350impl ErrorCause {
3351 #[inline]
3352 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
3353 Self::validate(bytes)?;
3354 Ok(Self::from_bytes_unchecked(bytes))
3355 }
3356
3357 #[inline]
3358 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
3359 Self::from(ErrorCauseRef::from_bytes_unchecked(bytes))
3360 }
3361
3362 #[inline]
3363 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
3364 ErrorCauseRef::validate(bytes)
3365 }
3366
3367 pub fn len(&self) -> usize {
3368 match self {
3369 Self::OutOfResource | Self::CookieDuringShutdown | Self::InvalidMandatoryParameter => 4,
3370 Self::InvalidStreamIdentifier(_) => 8,
3371 Self::MissingMandatoryParameter(e) => e.len(),
3372 Self::StaleCookie(_) => 8,
3373 Self::UnresolvableAddress(e) => e.len(),
3374 Self::UnrecognizedChunkType(e) => e.len(),
3375 Self::UnrecognizedParameters(e) => e.len(),
3376 Self::NoUserData(_) => 8,
3377 Self::AssociationNewAddress(e) => e.len(),
3378 Self::UserInitiatedAbort(e) => e.len(),
3379 Self::ProtocolViolation(e) => e.len(),
3380 Self::Unknown(e) => e.len(),
3381 }
3382 }
3383
3384 pub fn to_bytes_extended<T: PacketWritable>(
3385 &self,
3386 writer: &mut PacketWriter<'_, T>,
3387 ) -> Result<(), SerializationError> {
3388 match self {
3389 ErrorCause::InvalidStreamIdentifier(e) => e.to_bytes_extended(writer),
3390 ErrorCause::MissingMandatoryParameter(e) => e.to_bytes_extended(writer),
3391 ErrorCause::StaleCookie(e) => e.to_bytes_extended(writer),
3392 ErrorCause::OutOfResource => {
3393 writer.write_slice(&ERR_CODE_OUT_OF_RESOURCE.to_be_bytes())?;
3394 writer.write_slice(&4u16.to_be_bytes())
3395 }
3396 ErrorCause::UnresolvableAddress(e) => e.to_bytes_extended(writer),
3397 ErrorCause::UnrecognizedChunkType(e) => e.to_bytes_extended(writer),
3398 ErrorCause::InvalidMandatoryParameter => {
3399 writer.write_slice(&ERR_CODE_INVALID_MAND_PARAM.to_be_bytes())?;
3400 writer.write_slice(&4u16.to_be_bytes())
3401 }
3402 ErrorCause::UnrecognizedParameters(e) => e.to_bytes_extended(writer),
3403 ErrorCause::NoUserData(e) => e.to_bytes_extended(writer),
3404 ErrorCause::CookieDuringShutdown => {
3405 writer.write_slice(&ERR_CODE_COOKIE_RCVD_SHUTTING_DOWN.to_be_bytes())?;
3406 writer.write_slice(&4u16.to_be_bytes())
3407 }
3408 ErrorCause::AssociationNewAddress(e) => e.to_bytes_extended(writer),
3409 ErrorCause::UserInitiatedAbort(e) => e.to_bytes_extended(writer),
3410 ErrorCause::ProtocolViolation(e) => e.to_bytes_extended(writer),
3411 ErrorCause::Unknown(e) => e.to_bytes_extended(writer),
3412 }
3413 }
3414}
3415
3416#[cfg(feature = "alloc")]
3417impl From<ErrorCauseRef<'_>> for ErrorCause {
3418 #[inline]
3419 fn from(value: ErrorCauseRef<'_>) -> Self {
3420 ErrorCause::from(&value)
3421 }
3422}
3423
3424#[cfg(feature = "alloc")]
3425impl From<&ErrorCauseRef<'_>> for ErrorCause {
3426 fn from(value: &ErrorCauseRef<'_>) -> Self {
3427 match value {
3428 ErrorCauseRef::InvalidStreamIdentifier(e) => {
3429 ErrorCause::InvalidStreamIdentifier(e.into())
3430 }
3431 ErrorCauseRef::MissingMandatoryParameter(e) => {
3432 ErrorCause::MissingMandatoryParameter(e.into())
3433 }
3434 ErrorCauseRef::StaleCookie(e) => ErrorCause::StaleCookie(e.into()),
3435 ErrorCauseRef::OutOfResource(_) => ErrorCause::OutOfResource,
3436 ErrorCauseRef::UnresolvableAddress(e) => ErrorCause::UnresolvableAddress(e.into()),
3437 ErrorCauseRef::UnrecognizedChunkType(e) => ErrorCause::UnrecognizedChunkType(e.into()),
3438 ErrorCauseRef::InvalidMandatoryParameter(_) => ErrorCause::InvalidMandatoryParameter,
3439 ErrorCauseRef::UnrecognizedParameters(e) => {
3440 ErrorCause::UnrecognizedParameters(e.into())
3441 }
3442 ErrorCauseRef::NoUserData(e) => ErrorCause::NoUserData(e.into()),
3443 ErrorCauseRef::CookieDuringShutdown(_) => ErrorCause::CookieDuringShutdown,
3444 ErrorCauseRef::AssociationNewAddress(e) => ErrorCause::AssociationNewAddress(e.into()),
3445 ErrorCauseRef::UserInitiatedAbort(e) => ErrorCause::UserInitiatedAbort(e.into()),
3446 ErrorCauseRef::ProtocolViolation(e) => ErrorCause::ProtocolViolation(e.into()),
3447 ErrorCauseRef::Unknown(e) => ErrorCause::Unknown(e.into()),
3448 }
3449 }
3450}
3451
3452#[derive(Clone, Copy, Debug)]
3453pub enum ErrorCauseRef<'a> {
3454 InvalidStreamIdentifier(StreamIdentifierErrorRef<'a>),
3455
3456 MissingMandatoryParameter(MissingParameterErrorRef<'a>),
3457
3458 StaleCookie(StaleCookieErrorRef<'a>),
3459
3460 OutOfResource(&'a [u8]),
3461
3462 UnresolvableAddress(UnresolvableAddrErrorRef<'a>),
3463
3464 UnrecognizedChunkType(UnrecognizedChunkErrorRef<'a>),
3465
3466 InvalidMandatoryParameter(&'a [u8]),
3467
3468 UnrecognizedParameters(UnrecognizedParamErrorRef<'a>),
3469
3470 NoUserData(NoUserDataErrorRef<'a>),
3471
3472 CookieDuringShutdown(&'a [u8]),
3473
3474 AssociationNewAddress(AssociationNewAddrErrorRef<'a>),
3475
3476 UserInitiatedAbort(UserInitiatedAbortErrorRef<'a>),
3477
3478 ProtocolViolation(ProtocolViolationErrorRef<'a>),
3479
3480 Unknown(GenericParamRef<'a>),
3482}
3483
3484impl<'a> ErrorCauseRef<'a> {
3485 #[inline]
3486 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
3487 Self::validate(bytes)?;
3488 Ok(Self::from_bytes_unchecked(bytes))
3489 }
3490
3491 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
3492 let cause_code = u16::from_be_bytes(utils::to_array(bytes, 0).unwrap());
3493 match cause_code {
3494 ERR_CODE_INVALID_STREAM_ID => {
3495 Self::InvalidStreamIdentifier(StreamIdentifierErrorRef::from_bytes_unchecked(bytes))
3496 }
3497 ERR_CODE_MISSING_MAND_PARAM => Self::MissingMandatoryParameter(
3498 MissingParameterErrorRef::from_bytes_unchecked(bytes),
3499 ),
3500 ERR_CODE_STALE_COOKIE => {
3501 Self::StaleCookie(StaleCookieErrorRef::from_bytes_unchecked(bytes))
3502 }
3503 ERR_CODE_OUT_OF_RESOURCE => Self::OutOfResource(bytes),
3504 ERR_CODE_UNRESOLVABLE_ADDRESS => {
3505 Self::UnresolvableAddress(UnresolvableAddrErrorRef::from_bytes_unchecked(bytes))
3506 }
3507 ERR_CODE_UNRECOGNIZED_CHUNK => {
3508 Self::UnrecognizedChunkType(UnrecognizedChunkErrorRef::from_bytes_unchecked(bytes))
3509 }
3510 ERR_CODE_INVALID_MAND_PARAM => Self::InvalidMandatoryParameter(bytes),
3511 ERR_CODE_UNRECOGNIZED_PARAMS => {
3512 Self::UnrecognizedParameters(UnrecognizedParamErrorRef::from_bytes_unchecked(bytes))
3513 }
3514 ERR_CODE_NO_USER_DATA => {
3515 Self::NoUserData(NoUserDataErrorRef::from_bytes_unchecked(bytes))
3516 }
3517 ERR_CODE_COOKIE_RCVD_SHUTTING_DOWN => Self::CookieDuringShutdown(bytes),
3518 ERR_CODE_RESTART_ASSOC_NEW_ADDR => {
3519 Self::AssociationNewAddress(AssociationNewAddrErrorRef::from_bytes_unchecked(bytes))
3520 }
3521 ERR_CODE_USER_INITIATED_ABORT => {
3522 Self::UserInitiatedAbort(UserInitiatedAbortErrorRef::from_bytes_unchecked(bytes))
3523 }
3524 ERR_CODE_PROTOCOL_VIOLATION => {
3525 Self::ProtocolViolation(ProtocolViolationErrorRef::from_bytes_unchecked(bytes))
3526 }
3527 _ => Self::Unknown(GenericParamRef::from_bytes_unchecked(bytes)),
3528 }
3529 }
3530
3531 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
3532 let cause_code = u16::from_be_bytes(utils::to_array(bytes, 0).unwrap());
3533 match cause_code {
3534 ERR_CODE_INVALID_STREAM_ID => StreamIdentifierErrorRef::validate(bytes),
3535 ERR_CODE_MISSING_MAND_PARAM => MissingParameterErrorRef::validate(bytes),
3536 ERR_CODE_STALE_COOKIE => StaleCookieErrorRef::validate(bytes),
3537 ERR_CODE_UNRESOLVABLE_ADDRESS => UnresolvableAddrErrorRef::validate(bytes),
3538 ERR_CODE_UNRECOGNIZED_CHUNK => UnrecognizedChunkErrorRef::validate(bytes),
3539 ERR_CODE_UNRECOGNIZED_PARAMS => UnrecognizedParamErrorRef::validate(bytes),
3540 ERR_CODE_NO_USER_DATA => NoUserDataErrorRef::validate(bytes),
3541 ERR_CODE_RESTART_ASSOC_NEW_ADDR => AssociationNewAddrErrorRef::validate(bytes),
3542 ERR_CODE_USER_INITIATED_ABORT => UserInitiatedAbortErrorRef::validate(bytes),
3543 ERR_CODE_PROTOCOL_VIOLATION => ProtocolViolationErrorRef::validate(bytes),
3544 ERR_CODE_OUT_OF_RESOURCE
3545 | ERR_CODE_INVALID_MAND_PARAM
3546 | ERR_CODE_COOKIE_RCVD_SHUTTING_DOWN => match utils::to_array(bytes, 2) {
3547 Some(len_arr) => {
3548 let len = u16::from_be_bytes(len_arr) as usize;
3549
3550 if len != 4 {
3551 return Err(ValidationError {
3552 layer: SctpRef::name(),
3553 class: ValidationErrorClass::InvalidValue,
3554 #[cfg(feature = "error_string")]
3555 reason: "invalid length in SCTP Error Cause (must be equal to 4)",
3556 });
3557 }
3558
3559 if bytes.len() > 4 {
3560 Err(ValidationError {
3561 layer: SctpRef::name(),
3562 class: ValidationErrorClass::ExcessBytes(bytes.len() - 4),
3563 #[cfg(feature = "error_string")]
3564 reason: "extra bytes remain at end of SCTP 4-byte Error Cause",
3565 })
3566 } else {
3567 Ok(())
3568 }
3569 }
3570 _ => Err(ValidationError {
3571 layer: SctpRef::name(),
3572 class: ValidationErrorClass::InsufficientBytes,
3573 #[cfg(feature = "error_string")]
3574 reason: "insufficient bytes in SCTP 4-byte Error Cause for header",
3575 }),
3576 },
3577 _ => match utils::to_array(bytes, 2) {
3578 Some(len_arr) => {
3579 let unpadded_len = u16::from_be_bytes(len_arr) as usize;
3580 let len = utils::padded_length::<4>(unpadded_len);
3581
3582 if bytes.len() < cmp::max(8, len) {
3583 return Err(ValidationError {
3584 layer: SctpRef::name(),
3585 class: ValidationErrorClass::InsufficientBytes,
3586 #[cfg(feature = "error_string")]
3587 reason: "insufficient bytes in SCTP <unknown> Error Cause for header and data field",
3588 });
3589 }
3590
3591 if unpadded_len < 8 {
3592 return Err(ValidationError {
3593 layer: SctpRef::name(),
3594 class: ValidationErrorClass::InvalidValue,
3595 #[cfg(feature = "error_string")]
3596 reason: "invalid length in SCTP <unknown> Error Cause (must be at least 8 bytes)",
3597 });
3598 }
3599
3600 if bytes.len() > len {
3601 Err(ValidationError {
3602 layer: SctpRef::name(),
3603 class: ValidationErrorClass::ExcessBytes(bytes.len() - len),
3604 #[cfg(feature = "error_string")]
3605 reason: "extra bytes remain at end of SCTP <unknown> Error Cause",
3606 })
3607 } else {
3608 Ok(())
3609 }
3610 }
3611 _ => Err(ValidationError {
3612 layer: SctpRef::name(),
3613 class: ValidationErrorClass::InsufficientBytes,
3614 #[cfg(feature = "error_string")]
3615 reason: "insufficient bytes in SCTP <unknown> Error Cause for header",
3616 }),
3617 },
3618 }
3619 }
3620}
3621
3622#[derive(Clone, Debug)]
3623pub struct StreamIdentifierError {
3624 stream_id: u16,
3625 reserved: u16,
3626}
3627
3628impl StreamIdentifierError {
3629 #[inline]
3630 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
3631 Self::validate(bytes)?;
3632 Ok(Self::from_bytes_unchecked(bytes))
3633 }
3634
3635 #[inline]
3636 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
3637 Self::from(StreamIdentifierErrorRef::from_bytes_unchecked(bytes))
3638 }
3639
3640 #[inline]
3641 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
3642 StreamIdentifierErrorRef::validate(bytes)
3643 }
3644
3645 #[inline]
3646 pub fn cause_code(&self) -> u16 {
3647 ERR_CODE_INVALID_STREAM_ID
3648 }
3649
3650 #[inline]
3651 pub fn len(&self) -> usize {
3652 8
3653 }
3654
3655 #[inline]
3656 pub fn stream_id(&self) -> u16 {
3657 self.stream_id
3658 }
3659
3660 #[inline]
3661 pub fn set_stream_id(&mut self, stream_id: u16) {
3662 self.stream_id = stream_id;
3663 }
3664
3665 #[inline]
3666 pub fn reserved(&self) -> u16 {
3667 self.reserved
3668 }
3669
3670 #[inline]
3671 pub fn set_reserved(&mut self, reserved: u16) {
3672 self.reserved = reserved;
3673 }
3674
3675 pub fn to_bytes_extended<T: PacketWritable>(
3676 &self,
3677 writer: &mut PacketWriter<'_, T>,
3678 ) -> Result<(), SerializationError> {
3679 writer.write_slice(&ERR_CODE_INVALID_STREAM_ID.to_be_bytes())?;
3680 writer.write_slice(&8u16.to_be_bytes())?;
3681 writer.write_slice(&self.stream_id.to_be_bytes())?;
3682 writer.write_slice(&self.reserved.to_be_bytes())
3683 }
3684}
3685
3686impl From<StreamIdentifierErrorRef<'_>> for StreamIdentifierError {
3687 #[inline]
3688 fn from(value: StreamIdentifierErrorRef<'_>) -> Self {
3689 Self::from(&value)
3690 }
3691}
3692
3693impl From<&StreamIdentifierErrorRef<'_>> for StreamIdentifierError {
3694 #[inline]
3695 fn from(value: &StreamIdentifierErrorRef<'_>) -> Self {
3696 StreamIdentifierError {
3697 stream_id: value.stream_id(),
3698 reserved: value.reserved(),
3699 }
3700 }
3701}
3702
3703#[derive(Clone, Copy, Debug)]
3704pub struct StreamIdentifierErrorRef<'a> {
3705 data: &'a [u8],
3706}
3707
3708impl<'a> StreamIdentifierErrorRef<'a> {
3709 #[inline]
3710 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
3711 Self::validate(bytes)?;
3712 Ok(Self::from_bytes_unchecked(bytes))
3713 }
3714
3715 #[inline]
3716 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
3717 StreamIdentifierErrorRef { data: bytes }
3718 }
3719
3720 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
3721 match (utils::to_array(bytes, 0), utils::to_array(bytes, 2)) {
3722 (Some(cause_code_arr), Some(len_arr)) => {
3723 let cause_code = u16::from_be_bytes(cause_code_arr);
3724 let len = u16::from_be_bytes(len_arr) as usize;
3725
3726 if bytes.len() < 8 {
3727 return Err(ValidationError {
3728 layer: SctpRef::name(),
3729 class: ValidationErrorClass::InsufficientBytes,
3730 #[cfg(feature = "error_string")]
3731 reason: "insufficient bytes in SCTP Invalid Stream Identifier option for header + Explanation field",
3732 });
3733 }
3734
3735 if cause_code != ERR_CODE_INVALID_STREAM_ID {
3736 return Err(ValidationError {
3737 layer: SctpRef::name(),
3738 class: ValidationErrorClass::InvalidValue,
3739 #[cfg(feature = "error_string")]
3740 reason: "invalid cause code in SCTP Invalid Stream Identifier Option (must be equal to 1)",
3741 });
3742 }
3743
3744 if len != 8 {
3745 return Err(ValidationError {
3746 layer: SctpRef::name(),
3747 class: ValidationErrorClass::InvalidValue,
3748 #[cfg(feature = "error_string")]
3749 reason: "invalid length in SCTP Invalid Stream Identifier Option (must be equal to 8)",
3750 });
3751 }
3752
3753 if bytes.len() > 8 {
3754 Err(ValidationError {
3755 layer: SctpRef::name(),
3756 class: ValidationErrorClass::ExcessBytes(bytes.len() - 8),
3757 #[cfg(feature = "error_string")]
3758 reason:
3759 "extra bytes remain at end of SCTP Invalid Stream Identifier option",
3760 })
3761 } else {
3762 Ok(())
3763 }
3764 }
3765 _ => Err(ValidationError {
3766 layer: SctpRef::name(),
3767 class: ValidationErrorClass::InsufficientBytes,
3768 #[cfg(feature = "error_string")]
3769 reason: "insufficient bytes in SCTP Invalid Stream Identifier option for header",
3770 }),
3771 }
3772 }
3773
3774 #[inline]
3775 pub fn cause_code(&self) -> u16 {
3776 u16::from_be_bytes(utils::to_array(self.data, 0).unwrap())
3777 }
3778
3779 #[inline]
3780 pub fn unpadded_len(&self) -> u16 {
3781 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
3782 }
3783
3784 #[inline]
3785 pub fn len(&self) -> usize {
3786 utils::padded_length::<4>(self.unpadded_len() as usize)
3787 }
3788
3789 #[inline]
3790 pub fn stream_id(&self) -> u16 {
3791 u16::from_be_bytes(utils::to_array(self.data, 4).unwrap())
3792 }
3793
3794 #[inline]
3795 pub fn reserved(&self) -> u16 {
3796 u16::from_be_bytes(utils::to_array(self.data, 4).unwrap())
3797 }
3798}
3799
3800#[derive(Clone, Debug)]
3801#[cfg(feature = "alloc")]
3802pub struct MissingParameterError {
3803 missing_params: Vec<u16>,
3804}
3805
3806#[cfg(feature = "alloc")]
3807impl MissingParameterError {
3808 #[inline]
3809 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
3810 Self::validate(bytes)?;
3811 Ok(Self::from_bytes_unchecked(bytes))
3812 }
3813
3814 #[inline]
3815 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
3816 Self::from(MissingParameterErrorRef::from_bytes_unchecked(bytes))
3817 }
3818
3819 #[inline]
3820 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
3821 MissingParameterErrorRef::validate(bytes)
3822 }
3823
3824 #[inline]
3825 pub fn unpadded_len(&self) -> usize {
3826 8 + (2 * self.missing_params.len())
3827 }
3828
3829 #[inline]
3830 pub fn len(&self) -> usize {
3831 utils::padded_length::<4>(self.unpadded_len())
3832 }
3833
3834 #[inline]
3835 pub fn missing_params(&self) -> &Vec<u16> {
3836 &self.missing_params
3837 }
3838
3839 #[inline]
3840 pub fn missing_params_mut(&mut self) -> &mut Vec<u16> {
3841 &mut self.missing_params
3842 }
3843
3844 pub fn to_bytes_extended<T: PacketWritable>(
3845 &self,
3846 writer: &mut PacketWriter<'_, T>,
3847 ) -> Result<(), SerializationError> {
3848 writer.write_slice(&ERR_CODE_MISSING_MAND_PARAM.to_be_bytes())?;
3849 writer.write_slice(
3850 &u16::try_from(self.unpadded_len())
3851 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?
3852 .to_be_bytes(),
3853 )?;
3854 writer.write_slice(
3855 &u32::try_from(self.missing_params.len())
3856 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?
3857 .to_be_bytes(),
3858 )?;
3859 for param in &self.missing_params {
3860 writer.write_slice(¶m.to_be_bytes())?;
3861 }
3862 if self.missing_params.len() % 4 != 0 {
3863 writer.write_slice(&[0, 0])?;
3864 }
3865 Ok(())
3866 }
3867}
3868
3869#[cfg(feature = "alloc")]
3870impl From<MissingParameterErrorRef<'_>> for MissingParameterError {
3871 #[inline]
3872 fn from(value: MissingParameterErrorRef<'_>) -> Self {
3873 Self::from(&value)
3874 }
3875}
3876
3877#[cfg(feature = "alloc")]
3878impl From<&MissingParameterErrorRef<'_>> for MissingParameterError {
3879 #[inline]
3880 fn from(value: &MissingParameterErrorRef<'_>) -> Self {
3881 MissingParameterError {
3882 missing_params: Vec::from_iter(value.missing_params_iter()),
3883 }
3884 }
3885}
3886
3887#[derive(Clone, Copy, Debug)]
3888pub struct MissingParameterErrorRef<'a> {
3889 data: &'a [u8],
3890}
3891
3892impl<'a> MissingParameterErrorRef<'a> {
3893 #[inline]
3894 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
3895 Self::validate(bytes)?;
3896 Ok(Self::from_bytes_unchecked(bytes))
3897 }
3898
3899 #[inline]
3900 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
3901 MissingParameterErrorRef { data: bytes }
3902 }
3903
3904 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
3905 match (utils::to_array(bytes, 0), utils::to_array(bytes, 2)) {
3906 (Some(cause_code_arr), Some(len_arr)) => {
3907 let cause_code = u16::from_be_bytes(cause_code_arr);
3908 let unpadded_len = u16::from_be_bytes(len_arr) as usize;
3909 let len = utils::padded_length::<4>(unpadded_len);
3910
3911 if bytes.len() < cmp::max(8, len) {
3912 return Err(ValidationError {
3913 layer: SctpRef::name(),
3914 class: ValidationErrorClass::InsufficientBytes,
3915 #[cfg(feature = "error_string")]
3916 reason: "insufficient bytes in SCTP Missing Mandatory Parameter option for header + Missing Parameter fields",
3917 });
3918 }
3919
3920 if cause_code != ERR_CODE_MISSING_MAND_PARAM {
3921 return Err(ValidationError {
3922 layer: SctpRef::name(),
3923 class: ValidationErrorClass::InvalidValue,
3924 #[cfg(feature = "error_string")]
3925 reason: "invalid cause code in SCTP Missing Mandatory Parameter option (must be equal to 2)",
3926 });
3927 }
3928
3929 if unpadded_len < 8 {
3930 return Err(ValidationError {
3931 layer: SctpRef::name(),
3932 class: ValidationErrorClass::InvalidValue,
3933 #[cfg(feature = "error_string")]
3934 reason: "invalid length in SCTP Missing Mandatory Parameter option (must be at least 8 bytes long)",
3935 });
3936 }
3937
3938 if unpadded_len % 2 != 0 {
3939 return Err(ValidationError {
3940 layer: SctpRef::name(),
3941 class: ValidationErrorClass::InvalidValue,
3942 #[cfg(feature = "error_string")]
3943 reason: "invalid length in SCTP Missing Mandatory Parameter option (must be a multiple of 2)",
3944 });
3945 }
3946
3947 for b in bytes.iter().take(len).skip(unpadded_len) {
3948 if *b != 0 {
3949 return Err(ValidationError {
3950 layer: SctpRef::name(),
3951 class: ValidationErrorClass::InvalidValue,
3952 #[cfg(feature = "error_string")]
3953 reason: "invalid nonzero padding values at end of SCTP Missing Mandatory Parameter Option",
3954 });
3955 }
3956 }
3957
3958 if bytes.len() > len {
3959 Err(ValidationError {
3960 layer: SctpRef::name(),
3961 class: ValidationErrorClass::ExcessBytes(bytes.len() - len),
3962 #[cfg(feature = "error_string")]
3963 reason: "extra bytes remain at end of Missing Mandatory Parameter option",
3964 })
3965 } else {
3966 Ok(())
3967 }
3968 }
3969 _ => Err(ValidationError {
3970 layer: SctpRef::name(),
3971 class: ValidationErrorClass::InsufficientBytes,
3972 #[cfg(feature = "error_string")]
3973 reason: "insufficient bytes in SCTP Missing Mandatory Parameter option for header",
3974 }),
3975 }
3976 }
3977
3978 #[inline]
3979 pub fn cause_code(&self) -> u16 {
3980 u16::from_be_bytes(utils::to_array(self.data, 0).unwrap())
3981 }
3982
3983 #[inline]
3984 pub fn unpadded_len(&self) -> u16 {
3985 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
3986 }
3987
3988 #[inline]
3989 pub fn len(&self) -> usize {
3990 utils::padded_length::<4>(self.unpadded_len() as usize)
3991 }
3992
3993 #[inline]
3994 pub fn missing_params_cnt(&self) -> u32 {
3995 u32::from_be_bytes(utils::to_array(self.data, 2).unwrap())
3996 }
3997
3998 #[inline]
3999 pub fn missing_params_iter(&self) -> MissingParameterIterRef<'a> {
4000 MissingParameterIterRef {
4001 data: &self.data[4..cmp::min(
4002 4 + (2 * self.missing_params_cnt() as usize),
4003 self.data.len(),
4004 )],
4005 }
4006 }
4007}
4008
4009#[derive(Clone, Copy, Debug)]
4010pub struct MissingParameterIterRef<'a> {
4011 data: &'a [u8],
4012}
4013
4014impl<'a> Iterator for MissingParameterIterRef<'a> {
4015 type Item = u16;
4016
4017 #[inline]
4018 fn next(&mut self) -> Option<Self::Item> {
4019 match (utils::to_array(self.data, 0), self.data.get(2..)) {
4020 (Some(arr), Some(remaining)) => {
4021 self.data = remaining;
4022 Some(u16::from_be_bytes(arr))
4023 }
4024 _ => None,
4025 }
4026 }
4027}
4028
4029#[derive(Clone, Debug)]
4030#[cfg(feature = "alloc")]
4031pub struct StaleCookieError {
4032 staleness: u32,
4033}
4034
4035#[cfg(feature = "alloc")]
4036impl StaleCookieError {
4037 #[inline]
4038 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
4039 Self::validate(bytes)?;
4040 Ok(Self::from_bytes_unchecked(bytes))
4041 }
4042
4043 #[inline]
4044 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
4045 Self::from(StaleCookieErrorRef::from_bytes_unchecked(bytes))
4046 }
4047
4048 #[inline]
4049 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
4050 StaleCookieErrorRef::validate(bytes)
4051 }
4052
4053 #[inline]
4054 pub fn cause_code(&self) -> u16 {
4055 ERR_CODE_STALE_COOKIE
4056 }
4057
4058 #[inline]
4059 pub fn len(&self) -> usize {
4060 8
4061 }
4062
4063 #[inline]
4064 pub fn staleness(&self) -> u32 {
4065 self.staleness
4066 }
4067
4068 #[inline]
4069 pub fn set_staleness(&mut self, staleness: u32) {
4070 self.staleness = staleness;
4071 }
4072
4073 #[inline]
4074 pub fn to_bytes_extended<T: PacketWritable>(
4075 &self,
4076 writer: &mut PacketWriter<'_, T>,
4077 ) -> Result<(), SerializationError> {
4078 writer.write_slice(&ERR_CODE_STALE_COOKIE.to_be_bytes())?;
4079 writer.write_slice(&8u16.to_be_bytes())?;
4080 writer.write_slice(&self.staleness.to_be_bytes())
4081 }
4082}
4083
4084#[cfg(feature = "alloc")]
4085impl From<StaleCookieErrorRef<'_>> for StaleCookieError {
4086 #[inline]
4087 fn from(value: StaleCookieErrorRef<'_>) -> Self {
4088 Self::from(&value)
4089 }
4090}
4091
4092#[cfg(feature = "alloc")]
4093impl From<&StaleCookieErrorRef<'_>> for StaleCookieError {
4094 #[inline]
4095 fn from(value: &StaleCookieErrorRef<'_>) -> Self {
4096 StaleCookieError {
4097 staleness: value.staleness(),
4098 }
4099 }
4100}
4101
4102#[derive(Clone, Copy, Debug)]
4103pub struct StaleCookieErrorRef<'a> {
4104 data: &'a [u8],
4105}
4106
4107impl<'a> StaleCookieErrorRef<'a> {
4108 #[inline]
4109 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
4110 Self::validate(bytes)?;
4111 Ok(Self::from_bytes_unchecked(bytes))
4112 }
4113
4114 #[inline]
4115 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
4116 StaleCookieErrorRef { data: bytes }
4117 }
4118
4119 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
4120 match (utils::to_array(bytes, 0), utils::to_array(bytes, 2)) {
4121 (Some(cause_code_arr), Some(len_arr)) => {
4122 let cause_code = u16::from_be_bytes(cause_code_arr);
4123 let len = u16::from_be_bytes(len_arr) as usize;
4124
4125 if bytes.len() < 8 {
4126 return Err(ValidationError {
4127 layer: SctpRef::name(),
4128 class: ValidationErrorClass::InsufficientBytes,
4129 #[cfg(feature = "error_string")]
4130 reason: "insufficient bytes in SCTP Stale Cookie option for header + Measure of Staleness field",
4131 });
4132 }
4133
4134 if cause_code != ERR_CODE_STALE_COOKIE {
4135 return Err(ValidationError {
4136 layer: SctpRef::name(),
4137 class: ValidationErrorClass::InvalidValue,
4138 #[cfg(feature = "error_string")]
4139 reason:
4140 "invalid cause code in SCTP Stale Cookie option (must be equal to 3)",
4141 });
4142 }
4143
4144 if len != 8 {
4145 return Err(ValidationError {
4146 layer: SctpRef::name(),
4147 class: ValidationErrorClass::InvalidValue,
4148 #[cfg(feature = "error_string")]
4149 reason: "invalid length in SCTP Stale Cookie option (must be equal to 8)",
4150 });
4151 }
4152
4153 if bytes.len() > 8 {
4154 Err(ValidationError {
4155 layer: SctpRef::name(),
4156 class: ValidationErrorClass::ExcessBytes(bytes.len() - 8),
4157 #[cfg(feature = "error_string")]
4158 reason: "extra bytes remain at end of SCTP Stale Cookie option",
4159 })
4160 } else {
4161 Ok(())
4162 }
4163 }
4164 _ => Err(ValidationError {
4165 layer: SctpRef::name(),
4166 class: ValidationErrorClass::InsufficientBytes,
4167 #[cfg(feature = "error_string")]
4168 reason: "insufficient bytes in SCTP Stale Cookie option for header",
4169 }),
4170 }
4171 }
4172
4173 #[inline]
4174 pub fn cause_code(&self) -> u16 {
4175 u16::from_be_bytes(utils::to_array(self.data, 0).unwrap())
4176 }
4177
4178 #[inline]
4179 pub fn unpadded_len(&self) -> u16 {
4180 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
4181 }
4182
4183 #[inline]
4184 pub fn len(&self) -> usize {
4185 utils::padded_length::<4>(self.unpadded_len() as usize)
4186 }
4187
4188 #[inline]
4189 pub fn staleness(&self) -> u32 {
4190 u32::from_be_bytes(utils::to_array(self.data, 4).unwrap())
4191 }
4192}
4193
4194#[derive(Clone, Debug)]
4195#[cfg(feature = "alloc")]
4196pub struct UnresolvableAddrError {
4197 addr: Vec<u8>,
4198}
4199
4200#[cfg(feature = "alloc")]
4201impl UnresolvableAddrError {
4202 #[inline]
4203 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
4204 Self::validate(bytes)?;
4205 Ok(Self::from_bytes_unchecked(bytes))
4206 }
4207
4208 #[inline]
4209 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
4210 Self::from(UnresolvableAddrErrorRef::from_bytes_unchecked(bytes))
4211 }
4212
4213 #[inline]
4214 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
4215 UnresolvableAddrErrorRef::validate(bytes)
4216 }
4217
4218 #[inline]
4219 pub fn cause_code(&self) -> u16 {
4220 ERR_CODE_UNRESOLVABLE_ADDRESS
4221 }
4222
4223 pub fn unpadded_len(&self) -> usize {
4224 4 + self.addr.len()
4225 }
4226
4227 #[inline]
4228 pub fn len(&self) -> usize {
4229 utils::padded_length::<4>(self.unpadded_len())
4230 }
4231
4232 #[inline]
4233 pub fn addr(&self) -> &Vec<u8> {
4234 &self.addr
4235 }
4236
4237 #[inline]
4238 pub fn addr_mut(&mut self) -> &mut Vec<u8> {
4239 &mut self.addr
4240 }
4241
4242 pub fn to_bytes_extended<T: PacketWritable>(
4243 &self,
4244 writer: &mut PacketWriter<'_, T>,
4245 ) -> Result<(), SerializationError> {
4246 writer.write_slice(&ERR_CODE_UNRESOLVABLE_ADDRESS.to_be_bytes())?;
4247 writer.write_slice(
4248 &u16::try_from(self.unpadded_len())
4249 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?
4250 .to_be_bytes(),
4251 )?;
4252 writer.write_slice(&self.addr)?;
4253 for _ in self.unpadded_len()..self.len() {
4254 writer.write_slice(&[0])?;
4255 }
4256
4257 Ok(())
4258 }
4259}
4260
4261#[cfg(feature = "alloc")]
4262impl From<UnresolvableAddrErrorRef<'_>> for UnresolvableAddrError {
4263 #[inline]
4264 fn from(value: UnresolvableAddrErrorRef<'_>) -> Self {
4265 Self::from(&value)
4266 }
4267}
4268
4269#[cfg(feature = "alloc")]
4270impl From<&UnresolvableAddrErrorRef<'_>> for UnresolvableAddrError {
4271 #[inline]
4272 fn from(value: &UnresolvableAddrErrorRef<'_>) -> Self {
4273 UnresolvableAddrError {
4274 addr: Vec::from(value.addr()),
4275 }
4276 }
4277}
4278
4279#[derive(Clone, Copy, Debug)]
4280pub struct UnresolvableAddrErrorRef<'a> {
4281 data: &'a [u8],
4282}
4283
4284impl<'a> UnresolvableAddrErrorRef<'a> {
4285 #[inline]
4286 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
4287 Self::validate(bytes)?;
4288 Ok(Self::from_bytes_unchecked(bytes))
4289 }
4290
4291 #[inline]
4292 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
4293 UnresolvableAddrErrorRef { data: bytes }
4294 }
4295
4296 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
4297 match (utils::to_array(bytes, 0), utils::to_array(bytes, 2)) {
4298 (Some(cause_code_arr), Some(len_arr)) => {
4299 let cause_code = u16::from_be_bytes(cause_code_arr);
4300 let unpadded_len = u16::from_be_bytes(len_arr) as usize;
4301 let len = utils::padded_length::<4>(unpadded_len);
4302
4303 if bytes.len() < cmp::max(4, len) {
4304 return Err(ValidationError {
4305 layer: SctpRef::name(),
4306 class: ValidationErrorClass::InsufficientBytes,
4307 #[cfg(feature = "error_string")]
4308 reason: "insufficient bytes in SCTP Unresolvable Address option for header + Unresolvable Address field",
4309 });
4310 }
4311
4312 if cause_code != ERR_CODE_UNRESOLVABLE_ADDRESS {
4313 return Err(ValidationError {
4314 layer: SctpRef::name(),
4315 class: ValidationErrorClass::InvalidValue,
4316 #[cfg(feature = "error_string")]
4317 reason: "invalid cause code in SCTP Unresolvable Address option (must be equal to 5)",
4318 });
4319 }
4320
4321 if unpadded_len < 4 {
4322 return Err(ValidationError {
4323 layer: SctpRef::name(),
4324 class: ValidationErrorClass::InvalidValue,
4325 #[cfg(feature = "error_string")]
4326 reason: "invalid length in SCTP Unresolvable Address option (must be at least 4 bytes long)",
4327 });
4328 }
4329
4330 for b in bytes.iter().take(len).skip(unpadded_len) {
4331 if *b != 0 {
4332 return Err(ValidationError {
4333 layer: SctpRef::name(),
4334 class: ValidationErrorClass::InvalidValue,
4335 #[cfg(feature = "error_string")]
4336 reason: "invalid nonzero padding values at end of SCTP Unresolvable Address 4ption",
4337 });
4338 }
4339 }
4340
4341 if bytes.len() > len {
4342 Err(ValidationError {
4343 layer: SctpRef::name(),
4344 class: ValidationErrorClass::ExcessBytes(bytes.len() - len),
4345 #[cfg(feature = "error_string")]
4346 reason: "extra bytes remain at end of SCTP Unresolvable Address option",
4347 })
4348 } else {
4349 Ok(())
4350 }
4351 }
4352 _ => Err(ValidationError {
4353 layer: SctpRef::name(),
4354 class: ValidationErrorClass::InsufficientBytes,
4355 #[cfg(feature = "error_string")]
4356 reason: "insufficient bytes in SCTP Unresolvable Address option for header",
4357 }),
4358 }
4359 }
4360
4361 #[inline]
4362 pub fn cause_code(&self) -> u16 {
4363 u16::from_be_bytes(utils::to_array(self.data, 0).unwrap())
4364 }
4365
4366 #[inline]
4367 pub fn unpadded_len(&self) -> u16 {
4368 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
4369 }
4370
4371 #[inline]
4372 pub fn len(&self) -> usize {
4373 utils::padded_length::<4>(self.unpadded_len() as usize)
4374 }
4375
4376 #[inline]
4377 pub fn addr(&self) -> &[u8] {
4378 &self.data[4..self.unpadded_len() as usize]
4379 }
4380}
4381
4382#[derive(Clone, Debug)]
4383#[cfg(feature = "alloc")]
4384pub struct UnrecognizedChunkError {
4385 chunk: Vec<u8>,
4386}
4387
4388#[cfg(feature = "alloc")]
4389impl UnrecognizedChunkError {
4390 #[inline]
4391 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
4392 Self::validate(bytes)?;
4393 Ok(Self::from_bytes_unchecked(bytes))
4394 }
4395
4396 #[inline]
4397 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
4398 Self::from(UnrecognizedChunkErrorRef::from_bytes_unchecked(bytes))
4399 }
4400
4401 #[inline]
4402 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
4403 UnrecognizedChunkErrorRef::validate(bytes)
4404 }
4405
4406 #[inline]
4407 pub fn cause_code(&self) -> u16 {
4408 ERR_CODE_UNRECOGNIZED_CHUNK
4409 }
4410
4411 #[inline]
4412 pub fn unpadded_len(&self) -> usize {
4413 4 + self.chunk.len()
4414 }
4415
4416 #[inline]
4417 pub fn len(&self) -> usize {
4418 utils::padded_length::<4>(self.unpadded_len())
4419 }
4420
4421 #[inline]
4422 pub fn chunk(&self) -> &Vec<u8> {
4423 &self.chunk
4424 }
4425
4426 #[inline]
4427 pub fn chunk_mut(&mut self) -> &mut Vec<u8> {
4428 &mut self.chunk
4429 }
4430
4431 #[inline]
4432 pub fn to_bytes_extended<T: PacketWritable>(
4433 &self,
4434 writer: &mut PacketWriter<'_, T>,
4435 ) -> Result<(), SerializationError> {
4436 writer.write_slice(&ERR_CODE_STALE_COOKIE.to_be_bytes())?;
4437 writer.write_slice(&8u16.to_be_bytes())?;
4438 writer.write_slice(&self.chunk)
4439 }
4440}
4441
4442#[cfg(feature = "alloc")]
4443impl From<UnrecognizedChunkErrorRef<'_>> for UnrecognizedChunkError {
4444 #[inline]
4445 fn from(value: UnrecognizedChunkErrorRef<'_>) -> Self {
4446 Self::from(&value)
4447 }
4448}
4449
4450#[cfg(feature = "alloc")]
4451impl From<&UnrecognizedChunkErrorRef<'_>> for UnrecognizedChunkError {
4452 #[inline]
4453 fn from(value: &UnrecognizedChunkErrorRef<'_>) -> Self {
4454 UnrecognizedChunkError {
4455 chunk: Vec::from(value.chunk()),
4456 }
4457 }
4458}
4459
4460#[derive(Clone, Copy, Debug)]
4461pub struct UnrecognizedChunkErrorRef<'a> {
4462 data: &'a [u8],
4463}
4464
4465impl<'a> UnrecognizedChunkErrorRef<'a> {
4466 #[inline]
4467 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
4468 Self::validate(bytes)?;
4469 Ok(Self::from_bytes_unchecked(bytes))
4470 }
4471
4472 #[inline]
4473 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
4474 UnrecognizedChunkErrorRef { data: bytes }
4475 }
4476
4477 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
4478 match (utils::to_array(bytes, 0), utils::to_array(bytes, 2)) {
4479 (Some(cause_code_arr), Some(len_arr)) => {
4480 let cause_code = u16::from_be_bytes(cause_code_arr);
4481 let len = u16::from_be_bytes(len_arr) as usize;
4482
4483 if bytes.len() < cmp::max(8, len) {
4484 return Err(ValidationError {
4485 layer: SctpRef::name(),
4486 class: ValidationErrorClass::InsufficientBytes,
4487 #[cfg(feature = "error_string")]
4488 reason: "insufficient bytes in SCTP Unrecognized Chunk option for header + Unrecognized Chunk field",
4489 });
4490 }
4491
4492 if cause_code != ERR_CODE_UNRECOGNIZED_CHUNK {
4493 return Err(ValidationError {
4494 layer: SctpRef::name(),
4495 class: ValidationErrorClass::InvalidValue,
4496 #[cfg(feature = "error_string")]
4497 reason: "invalid cause code in SCTP Unrecognized Chunk option (must be equal to 6)",
4498 });
4499 }
4500
4501 if bytes.len() > 8 {
4502 Err(ValidationError {
4503 layer: SctpRef::name(),
4504 class: ValidationErrorClass::ExcessBytes(bytes.len() - len),
4505 #[cfg(feature = "error_string")]
4506 reason: "extra bytes remain at end of SCTP Unrecognized Chunk option",
4507 })
4508 } else {
4509 Ok(())
4510 }
4511 }
4512 _ => Err(ValidationError {
4513 layer: SctpRef::name(),
4514 class: ValidationErrorClass::InsufficientBytes,
4515 #[cfg(feature = "error_string")]
4516 reason: "insufficient bytes in SCTP Unrecognized Chunk option for header",
4517 }),
4518 }
4519 }
4520
4521 #[inline]
4522 pub fn cause_code(&self) -> u16 {
4523 u16::from_be_bytes(utils::to_array(self.data, 0).unwrap())
4524 }
4525
4526 #[inline]
4527 pub fn unpadded_len(&self) -> u16 {
4528 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
4529 }
4530
4531 #[inline]
4532 pub fn len(&self) -> usize {
4533 utils::padded_length::<4>(self.unpadded_len() as usize)
4534 }
4535
4536 #[inline]
4537 pub fn chunk(&self) -> &[u8] {
4538 &self.data[8..self.unpadded_len() as usize]
4539 }
4540}
4541
4542#[derive(Clone, Debug)]
4543#[cfg(feature = "alloc")]
4544pub struct UnrecognizedParamError {
4545 params: Vec<GenericParam>,
4546}
4547
4548#[cfg(feature = "alloc")]
4549impl UnrecognizedParamError {
4550 #[inline]
4551 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
4552 Self::validate(bytes)?;
4553 Ok(Self::from_bytes_unchecked(bytes))
4554 }
4555
4556 #[inline]
4557 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
4558 Self::from(UnrecognizedParamErrorRef::from_bytes_unchecked(bytes))
4559 }
4560
4561 #[inline]
4562 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
4563 UnrecognizedParamErrorRef::validate(bytes)
4564 }
4565
4566 #[inline]
4567 pub fn cause_code(&self) -> u16 {
4568 ERR_CODE_UNRECOGNIZED_PARAMS
4569 }
4570
4571 #[inline]
4572 pub fn unpadded_len(&self) -> usize {
4573 4 + self.params.iter().map(|p| p.len()).sum::<usize>()
4574 }
4575
4576 #[inline]
4577 pub fn len(&self) -> usize {
4578 utils::padded_length::<4>(self.unpadded_len())
4579 }
4580
4581 #[inline]
4582 pub fn params(&self) -> &Vec<GenericParam> {
4583 &self.params
4584 }
4585
4586 #[inline]
4587 pub fn params_mut(&mut self) -> &mut Vec<GenericParam> {
4588 &mut self.params
4589 }
4590
4591 pub fn to_bytes_extended<T: PacketWritable>(
4592 &self,
4593 writer: &mut PacketWriter<'_, T>,
4594 ) -> Result<(), SerializationError> {
4595 writer.write_slice(&ERR_CODE_UNRECOGNIZED_PARAMS.to_be_bytes())?;
4596 writer.write_slice(
4597 &u16::try_from(self.unpadded_len())
4598 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?
4599 .to_be_bytes(),
4600 )?;
4601 for param in self.params.iter() {
4602 param.to_bytes_extended(writer)?;
4603 }
4604
4605 Ok(())
4606 }
4607}
4608
4609#[cfg(feature = "alloc")]
4610impl From<UnrecognizedParamErrorRef<'_>> for UnrecognizedParamError {
4611 #[inline]
4612 fn from(value: UnrecognizedParamErrorRef<'_>) -> Self {
4613 Self::from(&value)
4614 }
4615}
4616
4617#[cfg(feature = "alloc")]
4618impl From<&UnrecognizedParamErrorRef<'_>> for UnrecognizedParamError {
4619 fn from(value: &UnrecognizedParamErrorRef<'_>) -> Self {
4620 let mut params = Vec::new();
4621 let iter = value.params_iter();
4622 for param in iter {
4623 params.push(param.into());
4624 }
4625
4626 UnrecognizedParamError { params }
4627 }
4628}
4629
4630#[derive(Clone, Copy, Debug)]
4631pub struct UnrecognizedParamErrorRef<'a> {
4632 data: &'a [u8],
4633}
4634
4635impl<'a> UnrecognizedParamErrorRef<'a> {
4636 #[inline]
4637 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
4638 Self::validate(bytes)?;
4639 Ok(Self::from_bytes_unchecked(bytes))
4640 }
4641
4642 #[inline]
4643 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
4644 UnrecognizedParamErrorRef { data: bytes }
4645 }
4646
4647 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
4648 match (utils::to_array(bytes, 0), utils::to_array(bytes, 2)) {
4649 (Some(cause_code_arr), Some(len_arr)) => {
4650 let cause_code = u16::from_be_bytes(cause_code_arr);
4651 let len = u16::from_be_bytes(len_arr) as usize;
4652
4653 if bytes.len() < cmp::max(4, len) {
4654 return Err(ValidationError {
4655 layer: SctpRef::name(),
4656 class: ValidationErrorClass::InsufficientBytes,
4657 #[cfg(feature = "error_string")]
4658 reason: "insufficient bytes in SCTP Unrecognized Parameters Option for header and Unrecognized Chunk field",
4659 });
4660 }
4661
4662 if cause_code != ERR_CODE_UNRECOGNIZED_PARAMS {
4663 return Err(ValidationError {
4664 layer: SctpRef::name(),
4665 class: ValidationErrorClass::InvalidValue,
4666 #[cfg(feature = "error_string")]
4667 reason: "invalid cause code in SCTP Unrecognized Parameters option (must be equal to 8)",
4668 });
4669 }
4670
4671 if bytes.len() > len {
4672 Err(ValidationError {
4673 layer: SctpRef::name(),
4674 class: ValidationErrorClass::ExcessBytes(bytes.len() - len),
4675 #[cfg(feature = "error_string")]
4676 reason: "extra bytes remain at end of SCTP Unrecognized Parameters option",
4677 })
4678 } else {
4679 Ok(())
4680 }
4681 }
4682 _ => Err(ValidationError {
4683 layer: SctpRef::name(),
4684 class: ValidationErrorClass::InsufficientBytes,
4685 #[cfg(feature = "error_string")]
4686 reason: "insufficient bytes in SCTP Unrecognized Parameters option for header",
4687 }),
4688 }
4689 }
4690
4691 #[inline]
4692 pub fn cause_code(&self) -> u16 {
4693 u16::from_be_bytes(utils::to_array(self.data, 0).unwrap())
4694 }
4695
4696 #[inline]
4697 pub fn unpadded_len(&self) -> u16 {
4698 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
4699 }
4700
4701 #[inline]
4702 pub fn len(&self) -> usize {
4703 utils::padded_length::<4>(self.unpadded_len() as usize)
4704 }
4705
4706 #[inline]
4707 pub fn params_iter(&self) -> ParamsIterRef<'a> {
4708 ParamsIterRef { bytes: self.data }
4709 }
4710}
4711
4712#[derive(Clone, Copy, Debug)]
4713pub struct ParamsIterRef<'a> {
4714 bytes: &'a [u8],
4715}
4716
4717impl<'a> Iterator for ParamsIterRef<'a> {
4718 type Item = GenericParamRef<'a>;
4719
4720 fn next(&mut self) -> Option<Self::Item> {
4721 match utils::to_array(self.bytes, 2) {
4722 Some(unpadded_len_arr) => {
4723 let unpadded_len = cmp::max(4, u16::from_be_bytes(unpadded_len_arr));
4724 let len = utils::padded_length::<4>(unpadded_len as usize);
4725 match (self.bytes.get(..len), self.bytes.get(len..)) {
4726 (Some(param), Some(remaining)) => {
4727 self.bytes = remaining;
4728 Some(GenericParamRef::from_bytes_unchecked(param))
4729 }
4730 _ => {
4731 let param = GenericParamRef::from_bytes_unchecked(self.bytes);
4732 self.bytes = &[];
4733 Some(param)
4734 }
4735 }
4736 }
4737 None => None,
4738 }
4739 }
4740}
4741
4742#[derive(Clone, Debug)]
4743pub struct NoUserDataError {
4744 tsn: u32,
4745}
4746
4747impl NoUserDataError {
4748 #[inline]
4749 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
4750 Self::validate(bytes)?;
4751 Ok(Self::from_bytes_unchecked(bytes))
4752 }
4753
4754 #[inline]
4755 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
4756 Self::from(NoUserDataErrorRef::from_bytes_unchecked(bytes))
4757 }
4758
4759 #[inline]
4760 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
4761 NoUserDataErrorRef::validate(bytes)
4762 }
4763
4764 #[inline]
4765 pub fn cause_code(&self) -> u16 {
4766 ERR_CODE_NO_USER_DATA
4767 }
4768
4769 #[inline]
4770 pub fn len(&self) -> usize {
4771 8
4772 }
4773
4774 #[inline]
4775 pub fn tsn(&self) -> u32 {
4776 self.tsn
4777 }
4778
4779 #[inline]
4780 pub fn set_tsn(&mut self, tsn: u32) {
4781 self.tsn = tsn;
4782 }
4783
4784 pub fn to_bytes_extended<T: PacketWritable>(
4785 &self,
4786 writer: &mut PacketWriter<'_, T>,
4787 ) -> Result<(), SerializationError> {
4788 writer.write_slice(&ERR_CODE_NO_USER_DATA.to_be_bytes())?;
4789 writer.write_slice(&8u16.to_be_bytes())?;
4790 writer.write_slice(&self.tsn.to_be_bytes())
4791 }
4792}
4793
4794impl From<NoUserDataErrorRef<'_>> for NoUserDataError {
4795 #[inline]
4796 fn from(value: NoUserDataErrorRef<'_>) -> Self {
4797 Self::from(&value)
4798 }
4799}
4800
4801impl From<&NoUserDataErrorRef<'_>> for NoUserDataError {
4802 #[inline]
4803 fn from(value: &NoUserDataErrorRef<'_>) -> Self {
4804 NoUserDataError { tsn: value.tsn() }
4805 }
4806}
4807
4808#[derive(Clone, Copy, Debug)]
4809pub struct NoUserDataErrorRef<'a> {
4810 data: &'a [u8],
4811}
4812
4813impl<'a> NoUserDataErrorRef<'a> {
4814 #[inline]
4815 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
4816 Self::validate(bytes)?;
4817 Ok(Self::from_bytes_unchecked(bytes))
4818 }
4819
4820 #[inline]
4821 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
4822 NoUserDataErrorRef { data: bytes }
4823 }
4824
4825 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
4826 match (utils::to_array(bytes, 0), utils::to_array(bytes, 2)) {
4827 (Some(cause_code_arr), Some(len_arr)) => {
4828 let cause_code = u16::from_be_bytes(cause_code_arr);
4829 let len = u16::from_be_bytes(len_arr) as usize;
4830
4831 if bytes.len() < 8 {
4832 return Err(ValidationError {
4833 layer: SctpRef::name(),
4834 class: ValidationErrorClass::InsufficientBytes,
4835 #[cfg(feature = "error_string")]
4836 reason: "insufficient bytes in SCTP No User Data option for header and explanation field",
4837 });
4838 }
4839
4840 if cause_code != ERR_CODE_NO_USER_DATA {
4841 return Err(ValidationError {
4842 layer: SctpRef::name(),
4843 class: ValidationErrorClass::InvalidValue,
4844 #[cfg(feature = "error_string")]
4845 reason:
4846 "invalid cause code in SCTP No User Data option (must be equal to 9)",
4847 });
4848 }
4849
4850 if len != 8 {
4851 return Err(ValidationError {
4852 layer: SctpRef::name(),
4853 class: ValidationErrorClass::InvalidValue,
4854 #[cfg(feature = "error_string")]
4855 reason: "invalid length in SCTP No User Data option (must be equal to 8)",
4856 });
4857 }
4858
4859 if bytes.len() > 8 {
4860 Err(ValidationError {
4861 layer: SctpRef::name(),
4862 class: ValidationErrorClass::ExcessBytes(bytes.len() - 8),
4863 #[cfg(feature = "error_string")]
4864 reason: "extra bytes remain at end of SCTP No User Data option",
4865 })
4866 } else {
4867 Ok(())
4868 }
4869 }
4870 _ => Err(ValidationError {
4871 layer: SctpRef::name(),
4872 class: ValidationErrorClass::InsufficientBytes,
4873 #[cfg(feature = "error_string")]
4874 reason: "insufficient bytes in SCTP No User Data option for header",
4875 }),
4876 }
4877 }
4878
4879 #[inline]
4880 pub fn cause_code(&self) -> u16 {
4881 u16::from_be_bytes(utils::to_array(self.data, 0).unwrap())
4882 }
4883
4884 #[inline]
4885 pub fn unpadded_len(&self) -> u16 {
4886 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
4887 }
4888
4889 #[inline]
4890 pub fn len(&self) -> usize {
4891 utils::padded_length::<4>(self.unpadded_len() as usize)
4892 }
4893
4894 #[inline]
4895 pub fn tsn(&self) -> u32 {
4896 u32::from_be_bytes(utils::to_array(self.data, 4).unwrap())
4897 }
4898}
4899
4900#[derive(Clone, Debug)]
4901#[cfg(feature = "alloc")]
4902pub struct AssociationNewAddrError {
4903 tlvs: Vec<GenericParam>,
4904}
4905
4906#[cfg(feature = "alloc")]
4907impl AssociationNewAddrError {
4908 #[inline]
4909 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
4910 Self::validate(bytes)?;
4911 Ok(Self::from_bytes_unchecked(bytes))
4912 }
4913
4914 #[inline]
4915 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
4916 Self::from(AssociationNewAddrErrorRef::from_bytes_unchecked(bytes))
4917 }
4918
4919 #[inline]
4920 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
4921 AssociationNewAddrErrorRef::validate(bytes)
4922 }
4923
4924 #[inline]
4925 pub fn cause_code(&self) -> u16 {
4926 ERR_CODE_RESTART_ASSOC_NEW_ADDR
4927 }
4928
4929 #[inline]
4930 pub fn unpadded_len(&self) -> usize {
4931 4 + self.tlvs.iter().map(|p| p.len()).sum::<usize>()
4932 }
4933
4934 #[inline]
4935 pub fn len(&self) -> usize {
4936 utils::padded_length::<4>(self.unpadded_len())
4937 }
4938
4939 #[inline]
4940 pub fn params(&self) -> &Vec<GenericParam> {
4941 &self.tlvs
4942 }
4943
4944 #[inline]
4945 pub fn params_mut(&mut self) -> &mut Vec<GenericParam> {
4946 &mut self.tlvs
4947 }
4948
4949 pub fn to_bytes_extended<T: PacketWritable>(
4950 &self,
4951 writer: &mut PacketWriter<'_, T>,
4952 ) -> Result<(), SerializationError> {
4953 writer.write_slice(&ERR_CODE_RESTART_ASSOC_NEW_ADDR.to_be_bytes())?;
4954 writer.write_slice(
4955 &u16::try_from(self.unpadded_len())
4956 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?
4957 .to_be_bytes(),
4958 )?;
4959 for tlv in self.tlvs.iter() {
4960 tlv.to_bytes_extended(writer)?;
4961 }
4962
4963 Ok(())
4964 }
4965}
4966
4967#[cfg(feature = "alloc")]
4968impl From<AssociationNewAddrErrorRef<'_>> for AssociationNewAddrError {
4969 #[inline]
4970 fn from(value: AssociationNewAddrErrorRef<'_>) -> Self {
4971 Self::from(&value)
4972 }
4973}
4974
4975#[cfg(feature = "alloc")]
4976impl From<&AssociationNewAddrErrorRef<'_>> for AssociationNewAddrError {
4977 #[inline]
4978 fn from(value: &AssociationNewAddrErrorRef<'_>) -> Self {
4979 let mut tlvs = Vec::new();
4980 let iter = value.params_iter();
4981 for param in iter {
4982 tlvs.push(param.into());
4983 }
4984
4985 AssociationNewAddrError { tlvs }
4986 }
4987}
4988
4989#[derive(Clone, Copy, Debug)]
4990pub struct AssociationNewAddrErrorRef<'a> {
4991 data: &'a [u8],
4992}
4993
4994impl<'a> AssociationNewAddrErrorRef<'a> {
4995 #[inline]
4996 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
4997 Self::validate(bytes)?;
4998 Ok(Self::from_bytes_unchecked(bytes))
4999 }
5000
5001 #[inline]
5002 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
5003 AssociationNewAddrErrorRef { data: bytes }
5004 }
5005
5006 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
5007 match (utils::to_array(bytes, 0), utils::to_array(bytes, 2)) {
5008 (Some(cause_code_arr), Some(len_arr)) => {
5009 let cause_code = u16::from_be_bytes(cause_code_arr);
5010 let len = u16::from_be_bytes(len_arr) as usize;
5011
5012 if bytes.len() < cmp::max(4, len) {
5013 return Err(ValidationError {
5014 layer: SctpRef::name(),
5015 class: ValidationErrorClass::InsufficientBytes,
5016 #[cfg(feature = "error_string")]
5017 reason: "insufficient bytes in SCTP Restart of Association with New Address option for header + New Address TLVs field",
5018 })
5019 }
5020
5021 if cause_code != ERR_CODE_RESTART_ASSOC_NEW_ADDR {
5022 return Err(ValidationError {
5023 layer: SctpRef::name(),
5024 class: ValidationErrorClass::InvalidValue,
5025 #[cfg(feature = "error_string")]
5026 reason: "invalid cause code in SCTP Restart of Association with New Address option (must be equal to 11)",
5027 })
5028 }
5029
5030 if bytes.len() > len {
5031 Err(ValidationError {
5032 layer: SctpRef::name(),
5033 class: ValidationErrorClass::ExcessBytes(bytes.len() - len),
5034 #[cfg(feature = "error_string")]
5035 reason: "extra bytes remain at end of SCTP Restart of Association with New Address option",
5036 })
5037 } else {
5038 Ok(())
5039 }
5040 },
5041 _ => Err(ValidationError {
5042 layer: SctpRef::name(),
5043 class: ValidationErrorClass::InsufficientBytes,
5044 #[cfg(feature = "error_string")]
5045 reason: "insufficient bytes in SCTP Restart of Association with New Address option for header"
5046 })
5047 }
5048 }
5049
5050 #[inline]
5051 pub fn cause_code(&self) -> u16 {
5052 u16::from_be_bytes(utils::to_array(self.data, 0).unwrap())
5053 }
5054
5055 #[inline]
5056 pub fn unpadded_len(&self) -> u16 {
5057 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
5058 }
5059
5060 #[inline]
5061 pub fn len(&self) -> usize {
5062 utils::padded_length::<4>(self.unpadded_len() as usize)
5063 }
5064
5065 #[inline]
5066 pub fn params_iter(&self) -> ParamsIterRef<'a> {
5067 ParamsIterRef { bytes: self.data }
5068 }
5069}
5070
5071#[derive(Clone, Debug)]
5072#[cfg(feature = "alloc")]
5073pub struct UserInitiatedAbortError {
5074 reason: Vec<u8>,
5075}
5076
5077#[cfg(feature = "alloc")]
5078impl UserInitiatedAbortError {
5079 #[inline]
5080 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
5081 Self::validate(bytes)?;
5082 Ok(Self::from_bytes_unchecked(bytes))
5083 }
5084
5085 #[inline]
5086 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
5087 Self::from(UserInitiatedAbortErrorRef::from_bytes_unchecked(bytes))
5088 }
5089
5090 #[inline]
5091 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
5092 UserInitiatedAbortErrorRef::validate(bytes)
5093 }
5094
5095 #[inline]
5096 pub fn cause_code(&self) -> u16 {
5097 ERR_CODE_USER_INITIATED_ABORT
5098 }
5099
5100 #[inline]
5101 pub fn unpadded_len(&self) -> usize {
5102 4 + self.reason.len()
5103 }
5104
5105 #[inline]
5106 pub fn len(&self) -> usize {
5107 utils::padded_length::<4>(self.unpadded_len())
5108 }
5109
5110 #[inline]
5111 pub fn reason(&self) -> &Vec<u8> {
5112 &self.reason
5113 }
5114
5115 #[inline]
5116 pub fn reason_mut(&mut self) -> &mut Vec<u8> {
5117 &mut self.reason
5118 }
5119
5120 pub fn to_bytes_extended<T: PacketWritable>(
5121 &self,
5122 writer: &mut PacketWriter<'_, T>,
5123 ) -> Result<(), SerializationError> {
5124 writer.write_slice(&ERR_CODE_USER_INITIATED_ABORT.to_be_bytes())?;
5125 writer.write_slice(
5126 &u16::try_from(self.unpadded_len())
5127 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?
5128 .to_be_bytes(),
5129 )?;
5130 writer.write_slice(&self.reason)?;
5131 for _ in self.unpadded_len()..self.len() {
5132 writer.write_slice(&[0])?;
5133 }
5134
5135 Ok(())
5136 }
5137}
5138
5139#[cfg(feature = "alloc")]
5140impl From<UserInitiatedAbortErrorRef<'_>> for UserInitiatedAbortError {
5141 #[inline]
5142 fn from(value: UserInitiatedAbortErrorRef<'_>) -> Self {
5143 Self::from(&value)
5144 }
5145}
5146
5147#[cfg(feature = "alloc")]
5148impl From<&UserInitiatedAbortErrorRef<'_>> for UserInitiatedAbortError {
5149 #[inline]
5150 fn from(value: &UserInitiatedAbortErrorRef<'_>) -> Self {
5151 UserInitiatedAbortError {
5152 reason: Vec::from(value.reason()),
5153 }
5154 }
5155}
5156
5157#[derive(Clone, Copy, Debug)]
5158pub struct UserInitiatedAbortErrorRef<'a> {
5159 data: &'a [u8],
5160}
5161
5162impl<'a> UserInitiatedAbortErrorRef<'a> {
5163 #[inline]
5164 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
5165 Self::validate(bytes)?;
5166 Ok(Self::from_bytes_unchecked(bytes))
5167 }
5168
5169 #[inline]
5170 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
5171 UserInitiatedAbortErrorRef { data: bytes }
5172 }
5173
5174 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
5175 match (utils::to_array(bytes, 0), utils::to_array(bytes, 2)) {
5176 (Some(cause_code_arr), Some(len_arr)) => {
5177 let cause_code = u16::from_be_bytes(cause_code_arr);
5178 let len = u16::from_be_bytes(len_arr) as usize;
5179
5180 if bytes.len() < cmp::max(4, len) {
5181 return Err(ValidationError {
5182 layer: SctpRef::name(),
5183 class: ValidationErrorClass::InsufficientBytes,
5184 #[cfg(feature = "error_string")]
5185 reason: "insufficient bytes in SCTP User-Initiated Abort option for header + Reason field",
5186 });
5187 }
5188
5189 if cause_code != ERR_CODE_USER_INITIATED_ABORT {
5190 return Err(ValidationError {
5191 layer: SctpRef::name(),
5192 class: ValidationErrorClass::InvalidValue,
5193 #[cfg(feature = "error_string")]
5194 reason: "invalid cause code in SCTP User-Initiated Abort option (must be equal to 12)",
5195 });
5196 }
5197
5198 if bytes.len() > len {
5199 Err(ValidationError {
5200 layer: SctpRef::name(),
5201 class: ValidationErrorClass::ExcessBytes(bytes.len() - len),
5202 #[cfg(feature = "error_string")]
5203 reason: "extra bytes remain at end of SCTP User-Initiated Abort option",
5204 })
5205 } else {
5206 Ok(())
5207 }
5208 }
5209 _ => Err(ValidationError {
5210 layer: SctpRef::name(),
5211 class: ValidationErrorClass::InsufficientBytes,
5212 #[cfg(feature = "error_string")]
5213 reason: "insufficient bytes in SCTP User-Initiated Abort option for header",
5214 }),
5215 }
5216 }
5217
5218 #[inline]
5219 pub fn cause_code(&self) -> u16 {
5220 u16::from_be_bytes(utils::to_array(self.data, 0).unwrap())
5221 }
5222
5223 #[inline]
5224 pub fn unpadded_len(&self) -> u16 {
5225 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
5226 }
5227
5228 #[inline]
5229 pub fn len(&self) -> usize {
5230 utils::padded_length::<4>(self.unpadded_len() as usize)
5231 }
5232
5233 #[inline]
5234 pub fn reason(&self) -> &[u8] {
5235 &self.data[8..self.unpadded_len() as usize]
5236 }
5237}
5238
5239#[derive(Clone, Debug)]
5240#[cfg(feature = "alloc")]
5241pub struct ProtocolViolationError {
5242 information: Vec<u8>,
5243}
5244
5245#[cfg(feature = "alloc")]
5246impl ProtocolViolationError {
5247 #[inline]
5248 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
5249 Self::validate(bytes)?;
5250 Ok(Self::from_bytes_unchecked(bytes))
5251 }
5252
5253 #[inline]
5254 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
5255 Self::from(ProtocolViolationErrorRef::from_bytes_unchecked(bytes))
5256 }
5257
5258 #[inline]
5259 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
5260 ProtocolViolationErrorRef::validate(bytes)
5261 }
5262
5263 #[inline]
5264 pub fn cause_code(&self) -> u16 {
5265 ERR_CODE_PROTOCOL_VIOLATION
5266 }
5267
5268 #[inline]
5269 pub fn unpadded_len(&self) -> usize {
5270 4 + self.information.len()
5271 }
5272
5273 #[inline]
5274 pub fn len(&self) -> usize {
5275 utils::padded_length::<4>(self.unpadded_len())
5276 }
5277
5278 #[inline]
5279 pub fn information(&self) -> &Vec<u8> {
5280 &self.information
5281 }
5282
5283 #[inline]
5284 pub fn information_mut(&mut self) -> &mut Vec<u8> {
5285 &mut self.information
5286 }
5287
5288 pub fn to_bytes_extended<T: PacketWritable>(
5289 &self,
5290 writer: &mut PacketWriter<'_, T>,
5291 ) -> Result<(), SerializationError> {
5292 writer.write_slice(&ERR_CODE_PROTOCOL_VIOLATION.to_be_bytes())?;
5293 writer.write_slice(
5294 &u16::try_from(self.unpadded_len())
5295 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?
5296 .to_be_bytes(),
5297 )?;
5298 writer.write_slice(&self.information)?;
5299 for _ in self.unpadded_len()..self.len() {
5300 writer.write_slice(&[0])?;
5301 }
5302
5303 Ok(())
5304 }
5305}
5306
5307#[cfg(feature = "alloc")]
5308impl From<ProtocolViolationErrorRef<'_>> for ProtocolViolationError {
5309 #[inline]
5310 fn from(value: ProtocolViolationErrorRef<'_>) -> Self {
5311 Self::from(&value)
5312 }
5313}
5314
5315#[cfg(feature = "alloc")]
5316impl From<&ProtocolViolationErrorRef<'_>> for ProtocolViolationError {
5317 #[inline]
5318 fn from(value: &ProtocolViolationErrorRef<'_>) -> Self {
5319 ProtocolViolationError {
5320 information: Vec::from(value.information()),
5321 }
5322 }
5323}
5324
5325#[derive(Clone, Copy, Debug)]
5326pub struct ProtocolViolationErrorRef<'a> {
5327 data: &'a [u8],
5328}
5329
5330impl<'a> ProtocolViolationErrorRef<'a> {
5331 #[inline]
5332 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
5333 Self::validate(bytes)?;
5334 Ok(Self::from_bytes_unchecked(bytes))
5335 }
5336
5337 #[inline]
5338 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
5339 ProtocolViolationErrorRef { data: bytes }
5340 }
5341
5342 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
5343 match (utils::to_array(bytes, 0), utils::to_array(bytes, 2)) {
5344 (Some(cause_code_arr), Some(len_arr)) => {
5345 let cause_code = u16::from_be_bytes(cause_code_arr);
5346 let len = u16::from_be_bytes(len_arr) as usize;
5347
5348 if bytes.len() < cmp::max(8, len) {
5349 return Err(ValidationError {
5350 layer: SctpRef::name(),
5351 class: ValidationErrorClass::InsufficientBytes,
5352 #[cfg(feature = "error_string")]
5353 reason: "insufficient bytes in SCTP Protocol Violation option for header + Additional Information field",
5354 });
5355 }
5356
5357 if cause_code != ERR_CODE_PROTOCOL_VIOLATION {
5358 return Err(ValidationError {
5359 layer: SctpRef::name(),
5360 class: ValidationErrorClass::InvalidValue,
5361 #[cfg(feature = "error_string")]
5362 reason: "invalid cause code in SCTP Protocol Violation option (must be equal to 13)",
5363 });
5364 }
5365
5366 if bytes.len() > len {
5367 Err(ValidationError {
5368 layer: SctpRef::name(),
5369 class: ValidationErrorClass::ExcessBytes(bytes.len() - len),
5370 #[cfg(feature = "error_string")]
5371 reason: "extra bytes remain at end of SCTP Protocol Violation option",
5372 })
5373 } else {
5374 Ok(())
5375 }
5376 }
5377 _ => Err(ValidationError {
5378 layer: SctpRef::name(),
5379 class: ValidationErrorClass::InsufficientBytes,
5380 #[cfg(feature = "error_string")]
5381 reason: "insufficient bytes in SCTP Protocol Violation option for header",
5382 }),
5383 }
5384 }
5385
5386 #[inline]
5387 pub fn cause_code(&self) -> u16 {
5388 u16::from_be_bytes(utils::to_array(self.data, 0).unwrap())
5389 }
5390
5391 #[inline]
5392 pub fn unpadded_len(&self) -> u16 {
5393 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
5394 }
5395
5396 #[inline]
5397 pub fn len(&self) -> usize {
5398 utils::padded_length::<4>(self.unpadded_len() as usize)
5399 }
5400
5401 #[inline]
5402 pub fn information(&self) -> &[u8] {
5403 &self.data[8..self.unpadded_len() as usize]
5404 }
5405}
5406
5407#[derive(Clone, Debug)]
5422#[cfg(feature = "alloc")]
5423pub struct GenericParam {
5424 param_type: u16,
5425 value: Vec<u8>,
5426}
5427
5428#[cfg(feature = "alloc")]
5429impl GenericParam {
5430 #[inline]
5431 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
5432 Self::validate(bytes)?;
5433 Ok(Self::from_bytes_unchecked(bytes))
5434 }
5435
5436 #[inline]
5437 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
5438 Self::from(GenericParamRef::from_bytes_unchecked(bytes))
5439 }
5440
5441 #[inline]
5442 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
5443 GenericParamRef::validate(bytes)
5444 }
5445
5446 #[inline]
5447 pub fn param_type(&self) -> u16 {
5448 self.param_type
5449 }
5450
5451 #[inline]
5452 pub fn set_param_type(&mut self, param_type: u16) {
5453 self.param_type = param_type;
5454 }
5455
5456 #[inline]
5457 pub fn unpadded_len(&self) -> usize {
5458 4 + self.value.len()
5459 }
5460
5461 #[inline]
5462 pub fn len(&self) -> usize {
5463 utils::padded_length::<4>(self.unpadded_len())
5464 }
5465
5466 #[inline]
5467 pub fn value(&self) -> &Vec<u8> {
5468 &self.value
5469 }
5470
5471 #[inline]
5472 pub fn value_mut(&mut self) -> &mut Vec<u8> {
5473 &mut self.value
5474 }
5475
5476 pub fn to_bytes_extended<T: PacketWritable>(
5477 &self,
5478 writer: &mut PacketWriter<'_, T>,
5479 ) -> Result<(), SerializationError> {
5480 writer.write_slice(&self.param_type.to_be_bytes())?;
5481 writer.write_slice(
5482 &u16::try_from(self.unpadded_len())
5483 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?
5484 .to_be_bytes(),
5485 )?;
5486 writer.write_slice(&self.value)?;
5487 for _ in self.unpadded_len()..self.len() {
5488 writer.write_slice(&[0])?;
5489 }
5490
5491 Ok(())
5492 }
5493}
5494
5495#[cfg(feature = "alloc")]
5496impl From<GenericParamRef<'_>> for GenericParam {
5497 #[inline]
5498 fn from(value: GenericParamRef<'_>) -> Self {
5499 Self::from(&value)
5500 }
5501}
5502
5503#[cfg(feature = "alloc")]
5504impl From<&GenericParamRef<'_>> for GenericParam {
5505 #[inline]
5506 fn from(value: &GenericParamRef<'_>) -> Self {
5507 GenericParam {
5508 param_type: value.param_type(),
5509 value: Vec::from(value.value()),
5510 }
5511 }
5512}
5513
5514#[derive(Clone, Copy, Debug)]
5530pub struct GenericParamRef<'a> {
5531 data: &'a [u8],
5532}
5533
5534impl<'a> GenericParamRef<'a> {
5535 #[inline]
5536 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
5537 Self::validate(bytes)?;
5538 Ok(Self::from_bytes_unchecked(bytes))
5539 }
5540
5541 #[inline]
5542 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
5543 GenericParamRef { data: bytes }
5544 }
5545
5546 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
5547 match utils::to_array(bytes, 2) {
5548 Some(len_arr) => {
5549 let unpadded_len = u16::from_be_bytes(len_arr) as usize;
5550 let len = utils::padded_length::<4>(unpadded_len);
5551
5552 if bytes.len() < cmp::max(4, len) {
5553 return Err(ValidationError {
5554 layer: SctpRef::name(),
5555 class: ValidationErrorClass::InsufficientBytes,
5556 #[cfg(feature = "error_string")]
5557 reason: "insufficient bytes in SCTP Parameter for header + Value field",
5558 });
5559 }
5560
5561 if unpadded_len < 4 {
5562 return Err(ValidationError {
5563 layer: SctpRef::name(),
5564 class: ValidationErrorClass::InvalidValue,
5565 #[cfg(feature = "error_string")]
5566 reason: "invalid length in SCTP Parameter (must be at least 4 bytes long)",
5567 });
5568 }
5569
5570 for b in bytes.iter().take(len).skip(unpadded_len) {
5571 if *b != 0 {
5572 return Err(ValidationError {
5573 layer: SctpRef::name(),
5574 class: ValidationErrorClass::InvalidValue,
5575 #[cfg(feature = "error_string")]
5576 reason: "invalid nonzero padding values at end of SCTP Parameter",
5577 });
5578 }
5579 }
5580
5581 if bytes.len() > len {
5582 Err(ValidationError {
5583 layer: SctpRef::name(),
5584 class: ValidationErrorClass::ExcessBytes(bytes.len() - len),
5585 #[cfg(feature = "error_string")]
5586 reason: "extra bytes remain at end of SCTP Parameter",
5587 })
5588 } else {
5589 Ok(())
5590 }
5591 }
5592 _ => Err(ValidationError {
5593 layer: SctpRef::name(),
5594 class: ValidationErrorClass::InsufficientBytes,
5595 #[cfg(feature = "error_string")]
5596 reason: "insufficient bytes in SCTP Parameter for header",
5597 }),
5598 }
5599 }
5600
5601 #[inline]
5602 pub fn param_type(&self) -> u16 {
5603 u16::from_be_bytes(utils::to_array(self.data, 0).unwrap())
5604 }
5605
5606 #[inline]
5607 pub fn unpadded_len(&self) -> u16 {
5608 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
5609 }
5610
5611 #[inline]
5612 pub fn len(&self) -> usize {
5613 utils::padded_length::<4>(self.unpadded_len() as usize)
5614 }
5615
5616 #[inline]
5617 pub fn value(&self) -> &[u8] {
5618 &self.data[4..self.unpadded_len() as usize]
5619 }
5620}
5621
5622bitflags! {
5623 #[derive(Clone, Copy, Debug, Default)]
5624 pub struct AbortFlags: u8 {
5625 const T = 0b00000001;
5626 }
5627}
5628
5629#[derive(Clone, Debug)]
5630pub struct ShutdownChunk {
5631 flags: u8,
5632 cum_tsn_ack: u32,
5633}
5634
5635impl ShutdownChunk {
5636 #[inline]
5637 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
5638 Self::validate(bytes)?;
5639 Ok(Self::from_bytes_unchecked(bytes))
5640 }
5641
5642 #[inline]
5643 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
5644 Self::from(ShutdownChunkRef::from_bytes_unchecked(bytes))
5645 }
5646
5647 #[inline]
5648 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
5649 ShutdownChunkRef::validate(bytes)
5650 }
5651
5652 #[inline]
5653 pub fn chunk_type(&self) -> u8 {
5654 CHUNK_TYPE_SHUTDOWN
5655 }
5656
5657 #[inline]
5658 pub fn flags_raw(&self) -> u8 {
5659 self.flags
5660 }
5661
5662 #[inline]
5663 pub fn set_flags_raw(&mut self, flags: u8) {
5664 self.flags = flags;
5665 }
5666
5667 #[inline]
5668 pub fn len(&self) -> usize {
5669 8
5670 }
5671
5672 #[inline]
5673 pub fn cum_tsn_ack(&self) -> u32 {
5674 self.cum_tsn_ack
5675 }
5676
5677 #[inline]
5678 pub fn set_cum_tsn_ack(&mut self, ack: u32) {
5679 self.cum_tsn_ack = ack;
5680 }
5681
5682 pub fn to_bytes_extended<T: PacketWritable>(
5683 &self,
5684 writer: &mut PacketWriter<'_, T>,
5685 ) -> Result<(), SerializationError> {
5686 writer.write_slice(&[CHUNK_TYPE_SHUTDOWN, self.flags])?;
5687 writer.write_slice(&8u16.to_be_bytes())?;
5688 writer.write_slice(&self.cum_tsn_ack.to_be_bytes())
5689 }
5690}
5691
5692impl From<ShutdownChunkRef<'_>> for ShutdownChunk {
5693 #[inline]
5694 fn from(value: ShutdownChunkRef<'_>) -> Self {
5695 Self::from(&value)
5696 }
5697}
5698
5699impl From<&ShutdownChunkRef<'_>> for ShutdownChunk {
5700 #[inline]
5701 fn from(value: &ShutdownChunkRef<'_>) -> Self {
5702 ShutdownChunk {
5703 flags: value.flags(),
5704 cum_tsn_ack: value.cum_tsn_ack(),
5705 }
5706 }
5707}
5708
5709#[derive(Clone, Copy, Debug)]
5710pub struct ShutdownChunkRef<'a> {
5711 data: &'a [u8],
5712}
5713
5714impl<'a> ShutdownChunkRef<'a> {
5715 #[inline]
5716 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
5717 Self::validate(bytes)?;
5718 Ok(Self::from_bytes_unchecked(bytes))
5719 }
5720
5721 #[inline]
5722 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
5723 ShutdownChunkRef { data: bytes }
5724 }
5725
5726 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
5727 match (bytes.first(), utils::to_array(bytes, 2)) {
5728 (Some(&chunk_type), Some(len_arr)) => {
5729 let len = u16::from_be_bytes(len_arr) as usize;
5730
5731 if bytes.len() < 8 {
5732 return Err(ValidationError {
5733 layer: SctpRef::name(),
5734 class: ValidationErrorClass::InsufficientBytes,
5735 #[cfg(feature = "error_string")]
5736 reason: "insufficient bytes in SCTP SHUTDOWN chunk for header + Cumulative TSN Ack field",
5737 });
5738 }
5739
5740 if chunk_type != CHUNK_TYPE_SHUTDOWN {
5741 return Err(ValidationError {
5742 layer: SctpRef::name(),
5743 class: ValidationErrorClass::InvalidValue,
5744 #[cfg(feature = "error_string")]
5745 reason:
5746 "invalid Chunk Type field in SCTP SHUTDOWN chunk (must be equal to 7)",
5747 });
5748 }
5749
5750 if len != 8 {
5751 return Err(ValidationError {
5752 layer: SctpRef::name(),
5753 class: ValidationErrorClass::InvalidValue,
5754 #[cfg(feature = "error_string")]
5755 reason: "invalid length in SCTP SHUTDOWN chunk (must be equal to 8)",
5756 });
5757 }
5758
5759 if bytes.len() > 8 {
5760 Err(ValidationError {
5761 layer: SctpRef::name(),
5762 class: ValidationErrorClass::ExcessBytes(bytes.len() - 8),
5763 #[cfg(feature = "error_string")]
5764 reason: "extra bytes remain at end of SCTP SHUTDOWN chunk",
5765 })
5766 } else {
5767 Ok(())
5768 }
5769 }
5770 _ => Err(ValidationError {
5771 layer: SctpRef::name(),
5772 class: ValidationErrorClass::InsufficientBytes,
5773 #[cfg(feature = "error_string")]
5774 reason: "insufficient bytes in SCTP SHUTDOWN chunk for header",
5775 }),
5776 }
5777 }
5778
5779 #[inline]
5780 pub fn chunk_type(&self) -> u8 {
5781 self.data[0]
5782 }
5783
5784 #[inline]
5785 pub fn flags(&self) -> u8 {
5786 self.data[1]
5787 }
5788
5789 #[inline]
5790 pub fn unpadded_len(&self) -> u16 {
5791 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
5792 }
5793
5794 #[inline]
5795 pub fn len(&self) -> usize {
5796 utils::padded_length::<4>(self.unpadded_len() as usize)
5797 }
5798
5799 #[inline]
5800 pub fn cum_tsn_ack(&self) -> u32 {
5801 u32::from_be_bytes(utils::to_array(self.data, 4).unwrap())
5802 }
5803}
5804
5805#[derive(Clone, Debug)]
5806pub struct ShutdownAckChunk {
5807 flags: u8,
5808}
5809
5810impl ShutdownAckChunk {
5811 #[inline]
5812 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
5813 Self::validate(bytes)?;
5814 Ok(Self::from_bytes_unchecked(bytes))
5815 }
5816
5817 #[inline]
5818 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
5819 Self::from(ShutdownAckChunkRef::from_bytes_unchecked(bytes))
5820 }
5821
5822 #[inline]
5823 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
5824 ShutdownAckChunkRef::validate(bytes)
5825 }
5826
5827 #[inline]
5828 pub fn chunk_type(&self) -> u8 {
5829 CHUNK_TYPE_SHUTDOWN_ACK
5830 }
5831
5832 #[inline]
5833 pub fn flags_raw(&self) -> u8 {
5834 self.flags
5835 }
5836
5837 #[inline]
5838 pub fn set_flags_raw(&mut self, flags: u8) {
5839 self.flags = flags;
5840 }
5841
5842 #[inline]
5843 pub fn len(&self) -> usize {
5844 4
5845 }
5846
5847 pub fn to_bytes_extended<T: PacketWritable>(
5848 &self,
5849 writer: &mut PacketWriter<'_, T>,
5850 ) -> Result<(), SerializationError> {
5851 writer.write_slice(&[CHUNK_TYPE_SHUTDOWN_ACK, self.flags])?;
5852 writer.write_slice(&4u16.to_be_bytes())
5853 }
5854}
5855
5856impl From<ShutdownAckChunkRef<'_>> for ShutdownAckChunk {
5857 #[inline]
5858 fn from(value: ShutdownAckChunkRef<'_>) -> Self {
5859 Self::from(&value)
5860 }
5861}
5862
5863impl From<&ShutdownAckChunkRef<'_>> for ShutdownAckChunk {
5864 #[inline]
5865 fn from(value: &ShutdownAckChunkRef<'_>) -> Self {
5866 ShutdownAckChunk {
5867 flags: value.flags(),
5868 }
5869 }
5870}
5871
5872#[derive(Clone, Copy, Debug)]
5873pub struct ShutdownAckChunkRef<'a> {
5874 data: &'a [u8],
5875}
5876
5877impl<'a> ShutdownAckChunkRef<'a> {
5878 #[inline]
5879 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
5880 Self::validate(bytes)?;
5881 Ok(Self::from_bytes_unchecked(bytes))
5882 }
5883
5884 #[inline]
5885 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
5886 ShutdownAckChunkRef { data: bytes }
5887 }
5888
5889 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
5890 match (bytes.first(), utils::to_array(bytes, 2)) {
5891 (Some(&chunk_type), Some(len_arr)) => {
5892 let len = u16::from_be_bytes(len_arr) as usize;
5893 if chunk_type != CHUNK_TYPE_SHUTDOWN_ACK {
5894 return Err(ValidationError {
5895 layer: SctpRef::name(),
5896 class: ValidationErrorClass::InvalidValue,
5897 #[cfg(feature = "error_string")]
5898 reason: "invalid Chunk Type field in SCTP SHUTDOWN ACK chunk (must be equal to 8)",
5899 });
5900 }
5901
5902 if len != 4 {
5903 return Err(ValidationError {
5904 layer: SctpRef::name(),
5905 class: ValidationErrorClass::InvalidValue,
5906 #[cfg(feature = "error_string")]
5907 reason: "invalid length in SCTP SHUTDOWN ACK chunk (must be equal to 4)",
5908 });
5909 }
5910
5911 if bytes.len() > 4 {
5912 Err(ValidationError {
5913 layer: SctpRef::name(),
5914 class: ValidationErrorClass::ExcessBytes(bytes.len() - 4),
5915 #[cfg(feature = "error_string")]
5916 reason: "extra bytes remain at end of SCTP SHUTDOWN ACK chunk",
5917 })
5918 } else {
5919 Ok(())
5920 }
5921 }
5922 _ => Err(ValidationError {
5923 layer: SctpRef::name(),
5924 class: ValidationErrorClass::InsufficientBytes,
5925 #[cfg(feature = "error_string")]
5926 reason: "insufficient bytes in SCTP SHUTDOWN ACK chunk for header",
5927 }),
5928 }
5929 }
5930
5931 #[inline]
5932 pub fn chunk_type(&self) -> u8 {
5933 self.data[0]
5934 }
5935
5936 #[inline]
5937 pub fn flags(&self) -> u8 {
5938 self.data[1]
5939 }
5940
5941 #[inline]
5942 pub fn unpadded_len(&self) -> u16 {
5943 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
5944 }
5945
5946 #[inline]
5947 pub fn len(&self) -> usize {
5948 utils::padded_length::<4>(self.unpadded_len() as usize)
5949 }
5950}
5951
5952#[derive(Clone, Debug)]
5953#[cfg(feature = "alloc")]
5954pub struct ErrorChunk {
5955 flags: u8,
5956 causes: Vec<ErrorCause>,
5957}
5958
5959#[cfg(feature = "alloc")]
5960impl ErrorChunk {
5961 #[inline]
5962 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
5963 Self::validate(bytes)?;
5964 Ok(Self::from_bytes_unchecked(bytes))
5965 }
5966
5967 #[inline]
5968 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
5969 Self::from(ErrorChunkRef::from_bytes_unchecked(bytes))
5970 }
5971
5972 #[inline]
5973 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
5974 ErrorChunkRef::validate(bytes)
5975 }
5976
5977 #[inline]
5978 pub fn chunk_type(&self) -> u8 {
5979 CHUNK_TYPE_ERROR
5980 }
5981
5982 #[inline]
5983 pub fn flags_raw(&self) -> u8 {
5984 self.flags
5985 }
5986
5987 #[inline]
5988 pub fn set_flags_raw(&mut self, flags: u8) {
5989 self.flags = flags;
5990 }
5991
5992 #[inline]
5993 pub fn unpadded_len(&self) -> usize {
5994 4 + self.causes.iter().map(|c| c.len()).sum::<usize>()
5995 }
5996
5997 #[inline]
5998 pub fn len(&self) -> usize {
5999 self.unpadded_len()
6000 }
6001
6002 #[inline]
6003 pub fn causes(&self) -> &Vec<ErrorCause> {
6004 &self.causes
6005 }
6006
6007 #[inline]
6008 pub fn set_causes(&mut self) -> &mut Vec<ErrorCause> {
6009 &mut self.causes
6010 }
6011
6012 pub fn to_bytes_extended<T: PacketWritable>(
6013 &self,
6014 writer: &mut PacketWriter<'_, T>,
6015 ) -> Result<(), SerializationError> {
6016 writer.write_slice(&[CHUNK_TYPE_ERROR, self.flags])?;
6017 writer.write_slice(
6018 &u16::try_from(self.unpadded_len())
6019 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?
6020 .to_be_bytes(),
6021 )?;
6022 for cause in &self.causes {
6023 cause.to_bytes_extended(writer)?
6024 }
6025
6026 Ok(())
6027 }
6028}
6029
6030#[cfg(feature = "alloc")]
6031impl From<ErrorChunkRef<'_>> for ErrorChunk {
6032 #[inline]
6033 fn from(value: ErrorChunkRef<'_>) -> Self {
6034 Self::from(&value)
6035 }
6036}
6037
6038#[cfg(feature = "alloc")]
6039impl From<&ErrorChunkRef<'_>> for ErrorChunk {
6040 fn from(value: &ErrorChunkRef<'_>) -> Self {
6041 let mut causes = Vec::new();
6042 let iter = value.error_iter();
6043 for error in iter {
6044 causes.push(error.into());
6045 }
6046
6047 ErrorChunk {
6048 flags: value.flags_raw(),
6049 causes,
6050 }
6051 }
6052}
6053
6054#[derive(Clone, Copy, Debug)]
6055pub struct ErrorChunkRef<'a> {
6056 data: &'a [u8],
6057}
6058
6059impl<'a> ErrorChunkRef<'a> {
6060 #[inline]
6061 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
6062 Self::validate(bytes)?;
6063 Ok(Self::from_bytes_unchecked(bytes))
6064 }
6065
6066 #[inline]
6067 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
6068 ErrorChunkRef { data: bytes }
6069 }
6070
6071 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
6072 match (bytes.first(), utils::to_array(bytes, 2)) {
6073 (Some(&chunk_type), Some(len_arr)) => {
6074 let len = u16::from_be_bytes(len_arr) as usize;
6075 if bytes.len() < cmp::max(4, len) {
6076 return Err(ValidationError {
6077 layer: SctpRef::name(),
6078 class: ValidationErrorClass::InsufficientBytes,
6079 #[cfg(feature = "error_string")]
6080 reason:
6081 "insufficient bytes in SCTP ERROR chunk for header + Error Causes field",
6082 });
6083 }
6084
6085 if chunk_type != CHUNK_TYPE_ERROR {
6086 return Err(ValidationError {
6087 layer: SctpRef::name(),
6088 class: ValidationErrorClass::InvalidValue,
6089 #[cfg(feature = "error_string")]
6090 reason: "invalid Chunk Type field in SCTP ERROR chunk (must be equal to 9)",
6091 });
6092 }
6093
6094 if bytes.len() > len {
6095 Err(ValidationError {
6096 layer: SctpRef::name(),
6097 class: ValidationErrorClass::ExcessBytes(bytes.len() - len),
6098 #[cfg(feature = "error_string")]
6099 reason: "extra bytes remain at end of SCTP ERROR chunk",
6100 })
6101 } else {
6102 Ok(())
6103 }
6104 }
6105 _ => Err(ValidationError {
6106 layer: SctpRef::name(),
6107 class: ValidationErrorClass::InsufficientBytes,
6108 #[cfg(feature = "error_string")]
6109 reason: "insufficient bytes in SCTP ERROR chunk for header",
6110 }),
6111 }
6112 }
6113
6114 #[inline]
6115 pub fn chunk_type(&self) -> u8 {
6116 self.data[0]
6117 }
6118
6119 #[inline]
6120 pub fn flags_raw(&self) -> u8 {
6121 self.data[0]
6122 }
6123
6124 #[inline]
6125 pub fn unpadded_len(&self) -> u16 {
6126 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
6127 }
6128
6129 #[inline]
6130 pub fn len(&self) -> usize {
6131 utils::padded_length::<4>(self.unpadded_len() as usize)
6132 }
6133
6134 #[inline]
6135 pub fn error_iter(&self) -> ErrorCauseIterRef {
6136 ErrorCauseIterRef {
6137 bytes: &self.data[4..self.unpadded_len() as usize],
6138 }
6139 }
6140}
6141
6142#[derive(Clone, Debug)]
6143#[cfg(feature = "alloc")]
6144pub struct CookieEchoChunk {
6145 flags: u8,
6146 cookie: Vec<u8>,
6147}
6148
6149#[cfg(feature = "alloc")]
6150impl CookieEchoChunk {
6151 #[inline]
6152 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
6153 Self::validate(bytes)?;
6154 Ok(Self::from_bytes_unchecked(bytes))
6155 }
6156
6157 #[inline]
6158 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
6159 Self::from(CookieEchoChunkRef::from_bytes_unchecked(bytes))
6160 }
6161
6162 #[inline]
6163 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
6164 CookieEchoChunkRef::validate(bytes)
6165 }
6166
6167 #[inline]
6168 pub fn chunk_type(&self) -> u8 {
6169 CHUNK_TYPE_COOKIE_ECHO
6170 }
6171
6172 #[inline]
6173 pub fn flags_raw(&self) -> u8 {
6174 self.flags
6175 }
6176
6177 #[inline]
6178 pub fn set_flags_raw(&mut self, flags: u8) {
6179 self.flags = flags;
6180 }
6181
6182 #[inline]
6183 pub fn unpadded_len(&self) -> usize {
6184 4 + self.cookie.len()
6185 }
6186
6187 #[inline]
6188 pub fn len(&self) -> usize {
6189 utils::padded_length::<4>(self.unpadded_len())
6190 }
6191
6192 #[inline]
6193 pub fn cookie(&self) -> &Vec<u8> {
6194 &self.cookie
6195 }
6196
6197 #[inline]
6198 pub fn cookie_mut(&mut self) -> &mut Vec<u8> {
6199 &mut self.cookie
6200 }
6201
6202 pub fn to_bytes_extended<T: PacketWritable>(
6203 &self,
6204 writer: &mut PacketWriter<'_, T>,
6205 ) -> Result<(), SerializationError> {
6206 writer.write_slice(&[CHUNK_TYPE_COOKIE_ECHO, self.flags])?;
6207 writer.write_slice(
6208 &u16::try_from(self.unpadded_len())
6209 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?
6210 .to_be_bytes(),
6211 )?;
6212 writer.write_slice(&self.cookie)?;
6213 for _ in self.unpadded_len()..self.len() {
6214 writer.write_slice(&[0])?;
6215 }
6216
6217 Ok(())
6218 }
6219}
6220
6221#[cfg(feature = "alloc")]
6222impl From<CookieEchoChunkRef<'_>> for CookieEchoChunk {
6223 #[inline]
6224 fn from(value: CookieEchoChunkRef<'_>) -> Self {
6225 Self::from(&value)
6226 }
6227}
6228
6229#[cfg(feature = "alloc")]
6230impl From<&CookieEchoChunkRef<'_>> for CookieEchoChunk {
6231 #[inline]
6232 fn from(value: &CookieEchoChunkRef<'_>) -> Self {
6233 CookieEchoChunk {
6234 flags: value.flags_raw(),
6235 cookie: Vec::from(value.cookie()),
6236 }
6237 }
6238}
6239
6240#[derive(Clone, Copy, Debug)]
6241pub struct CookieEchoChunkRef<'a> {
6242 data: &'a [u8],
6243}
6244
6245impl<'a> CookieEchoChunkRef<'a> {
6246 #[inline]
6247 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
6248 Self::validate(bytes)?;
6249 Ok(Self::from_bytes_unchecked(bytes))
6250 }
6251
6252 #[inline]
6253 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
6254 CookieEchoChunkRef { data: bytes }
6255 }
6256
6257 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
6258 match (bytes.first(), utils::to_array(bytes, 2)) {
6259 (Some(&chunk_type), Some(len_arr)) => {
6260 let unpadded_len = u16::from_be_bytes(len_arr) as usize;
6261 let len = utils::padded_length::<4>(unpadded_len);
6262
6263 if bytes.len() < cmp::max(4, len) {
6264 return Err(ValidationError {
6265 layer: SctpRef::name(),
6266 class: ValidationErrorClass::InsufficientBytes,
6267 #[cfg(feature = "error_string")]
6268 reason:
6269 "insufficient bytes in SCTP COOKIE ECHO chunk for header + Cookie field",
6270 });
6271 }
6272
6273 if unpadded_len < 4 {
6274 return Err(ValidationError {
6275 layer: SctpRef::name(),
6276 class: ValidationErrorClass::InvalidValue,
6277 #[cfg(feature = "error_string")]
6278 reason: "invalid length in SCTP COOKIE ECHO chunk (must be at least 4 octets long)",
6279 });
6280 }
6281
6282 if chunk_type != CHUNK_TYPE_COOKIE_ECHO {
6283 return Err(ValidationError {
6284 layer: SctpRef::name(),
6285 class: ValidationErrorClass::InvalidValue,
6286 #[cfg(feature = "error_string")]
6287 reason: "invalid Chunk Type field in SCTP COOKIE ECHO chunk (must be equal to 10)",
6288 });
6289 }
6290
6291 for b in bytes.iter().take(len).skip(unpadded_len) {
6292 if *b != 0 {
6293 return Err(ValidationError {
6294 layer: SctpRef::name(),
6295 class: ValidationErrorClass::InvalidValue,
6296 #[cfg(feature = "error_string")]
6297 reason:
6298 "invalid nonzero padding values at end of SCTP COOKIE ECHO chunk",
6299 });
6300 }
6301 }
6302
6303 if bytes.len() > len {
6304 Err(ValidationError {
6305 layer: SctpRef::name(),
6306 class: ValidationErrorClass::ExcessBytes(bytes.len() - len),
6307 #[cfg(feature = "error_string")]
6308 reason: "extra bytes remain at end of SCTP COOKIE ECHO hunk",
6309 })
6310 } else {
6311 Ok(())
6312 }
6313 }
6314 _ => Err(ValidationError {
6315 layer: SctpRef::name(),
6316 class: ValidationErrorClass::InsufficientBytes,
6317 #[cfg(feature = "error_string")]
6318 reason: "insufficient bytes in SCTP COOKIE ECHO chunk for header",
6319 }),
6320 }
6321 }
6322
6323 #[inline]
6324 pub fn chunk_type(&self) -> u8 {
6325 self.data[0]
6326 }
6327
6328 #[inline]
6329 pub fn flags_raw(&self) -> u8 {
6330 self.data[1]
6331 }
6332
6333 #[inline]
6334 pub fn unpadded_len(&self) -> u16 {
6335 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
6336 }
6337
6338 #[inline]
6339 pub fn len(&self) -> usize {
6340 utils::padded_length::<4>(self.unpadded_len() as usize)
6341 }
6342
6343 #[inline]
6344 pub fn cookie(&self) -> &[u8] {
6345 &self.data[4..self.unpadded_len() as usize]
6346 }
6347}
6348
6349#[derive(Clone, Debug)]
6350#[cfg(feature = "alloc")]
6351pub struct CookieAckChunk {
6352 flags: u8,
6353}
6354
6355#[cfg(feature = "alloc")]
6356impl CookieAckChunk {
6357 #[inline]
6358 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
6359 Self::validate(bytes)?;
6360 Ok(Self::from_bytes_unchecked(bytes))
6361 }
6362
6363 #[inline]
6364 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
6365 Self::from(CookieAckChunkRef::from_bytes_unchecked(bytes))
6366 }
6367
6368 #[inline]
6369 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
6370 CookieAckChunkRef::validate(bytes)
6371 }
6372
6373 #[inline]
6374 pub fn chunk_type(&self) -> u8 {
6375 CHUNK_TYPE_COOKIE_ACK
6376 }
6377
6378 #[inline]
6379 pub fn flags_raw(&self) -> u8 {
6380 self.flags
6381 }
6382
6383 #[inline]
6384 pub fn set_flags_raw(&mut self, flags: u8) {
6385 self.flags = flags;
6386 }
6387
6388 #[inline]
6389 pub fn len(&self) -> usize {
6390 4
6391 }
6392
6393 #[inline]
6394 pub fn to_bytes_extended<T: PacketWritable>(
6395 &self,
6396 writer: &mut PacketWriter<'_, T>,
6397 ) -> Result<(), SerializationError> {
6398 writer.write_slice(&[CHUNK_TYPE_COOKIE_ACK, self.flags])?;
6399 writer.write_slice(&4u16.to_be_bytes())
6400 }
6401}
6402
6403#[cfg(feature = "alloc")]
6404impl From<CookieAckChunkRef<'_>> for CookieAckChunk {
6405 #[inline]
6406 fn from(value: CookieAckChunkRef<'_>) -> Self {
6407 Self::from(&value)
6408 }
6409}
6410
6411#[cfg(feature = "alloc")]
6412impl From<&CookieAckChunkRef<'_>> for CookieAckChunk {
6413 #[inline]
6414 fn from(value: &CookieAckChunkRef<'_>) -> Self {
6415 CookieAckChunk {
6416 flags: value.flags(),
6417 }
6418 }
6419}
6420
6421#[derive(Clone, Copy, Debug)]
6422pub struct CookieAckChunkRef<'a> {
6423 data: &'a [u8],
6424}
6425
6426impl<'a> CookieAckChunkRef<'a> {
6427 #[inline]
6428 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
6429 Self::validate(bytes)?;
6430 Ok(Self::from_bytes_unchecked(bytes))
6431 }
6432
6433 #[inline]
6434 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
6435 CookieAckChunkRef { data: bytes }
6436 }
6437
6438 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
6439 match (bytes.first(), utils::to_array(bytes, 2)) {
6440 (Some(&chunk_type), Some(len_arr)) => {
6441 let len = u16::from_be_bytes(len_arr) as usize;
6442 if chunk_type != CHUNK_TYPE_COOKIE_ACK {
6443 return Err(ValidationError {
6444 layer: SctpRef::name(),
6445 class: ValidationErrorClass::InvalidValue,
6446 #[cfg(feature = "error_string")]
6447 reason:
6448 "invalid Chunk Type field in SCTP COOKIE ACK chunk (must be equal to 11)",
6449 });
6450 }
6451
6452 if len != 4 {
6453 return Err(ValidationError {
6454 layer: SctpRef::name(),
6455 class: ValidationErrorClass::InvalidValue,
6456 #[cfg(feature = "error_string")]
6457 reason: "invalid length in SCTP COOKIE_ACK chunk (must be equal to 4)",
6458 });
6459 }
6460
6461 if bytes.len() > 4 {
6462 Err(ValidationError {
6463 layer: SctpRef::name(),
6464 class: ValidationErrorClass::ExcessBytes(bytes.len() - 4),
6465 #[cfg(feature = "error_string")]
6466 reason: "extra bytes remain at end of SCTP COOKIE ACK chunk",
6467 })
6468 } else {
6469 Ok(())
6470 }
6471 }
6472 _ => Err(ValidationError {
6473 layer: SctpRef::name(),
6474 class: ValidationErrorClass::InsufficientBytes,
6475 #[cfg(feature = "error_string")]
6476 reason: "insufficient bytes in SCTP COOKIE ACK chunk for header",
6477 }),
6478 }
6479 }
6480
6481 #[inline]
6482 pub fn chunk_type(&self) -> u8 {
6483 self.data[0]
6484 }
6485
6486 #[inline]
6487 pub fn flags(&self) -> u8 {
6488 self.data[1]
6489 }
6490
6491 #[inline]
6492 pub fn unpadded_len(&self) -> u16 {
6493 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
6494 }
6495
6496 #[inline]
6497 pub fn len(&self) -> usize {
6498 utils::padded_length::<4>(self.unpadded_len() as usize)
6499 }
6500}
6501
6502#[derive(Clone, Debug)]
6503#[cfg(feature = "alloc")]
6504pub struct ShutdownCompleteChunk {
6505 flags: ShutdownCompleteFlags,
6506}
6507
6508#[cfg(feature = "alloc")]
6509impl ShutdownCompleteChunk {
6510 #[inline]
6511 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
6512 Self::validate(bytes)?;
6513 Ok(Self::from_bytes_unchecked(bytes))
6514 }
6515
6516 #[inline]
6517 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
6518 Self::from(ShutdownCompleteChunkRef::from_bytes_unchecked(bytes))
6519 }
6520
6521 #[inline]
6522 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
6523 ShutdownCompleteChunkRef::validate(bytes)
6524 }
6525
6526 #[inline]
6527 pub fn chunk_type(&self) -> u8 {
6528 CHUNK_TYPE_SHUTDOWN_COMPLETE
6529 }
6530
6531 #[inline]
6532 pub fn flags(&self) -> ShutdownCompleteFlags {
6533 self.flags
6534 }
6535
6536 #[inline]
6537 pub fn set_flags(&mut self, flags: ShutdownCompleteFlags) {
6538 self.flags = flags;
6539 }
6540
6541 #[inline]
6542 pub fn len(&self) -> usize {
6543 4
6544 }
6545
6546 #[inline]
6547 pub fn to_bytes_extended<T: PacketWritable>(
6548 &self,
6549 writer: &mut PacketWriter<'_, T>,
6550 ) -> Result<(), SerializationError> {
6551 writer.write_slice(&[CHUNK_TYPE_SHUTDOWN_COMPLETE, self.flags.bits()])?;
6552 writer.write_slice(&4u16.to_be_bytes())
6553 }
6554}
6555
6556#[cfg(feature = "alloc")]
6557impl From<ShutdownCompleteChunkRef<'_>> for ShutdownCompleteChunk {
6558 #[inline]
6559 fn from(value: ShutdownCompleteChunkRef<'_>) -> Self {
6560 Self::from(&value)
6561 }
6562}
6563
6564#[cfg(feature = "alloc")]
6565impl From<&ShutdownCompleteChunkRef<'_>> for ShutdownCompleteChunk {
6566 #[inline]
6567 fn from(value: &ShutdownCompleteChunkRef<'_>) -> Self {
6568 ShutdownCompleteChunk {
6569 flags: value.flags(),
6570 }
6571 }
6572}
6573
6574#[derive(Clone, Copy, Debug)]
6575pub struct ShutdownCompleteChunkRef<'a> {
6576 data: &'a [u8],
6577}
6578
6579impl<'a> ShutdownCompleteChunkRef<'a> {
6580 #[inline]
6581 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
6582 Self::validate(bytes)?;
6583 Ok(Self::from_bytes_unchecked(bytes))
6584 }
6585
6586 #[inline]
6587 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
6588 ShutdownCompleteChunkRef { data: bytes }
6589 }
6590
6591 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
6592 match (bytes.first(), utils::to_array(bytes, 2)) {
6593 (Some(&chunk_type), Some(len_arr)) => {
6594 let len = u16::from_be_bytes(len_arr) as usize;
6595 if chunk_type != CHUNK_TYPE_SHUTDOWN_COMPLETE {
6596 return Err(ValidationError {
6597 layer: SctpRef::name(),
6598 class: ValidationErrorClass::InvalidValue,
6599 #[cfg(feature = "error_string")]
6600 reason: "invalid Chunk Type field in SCTP SHUTDOWN COMPLETE chunk (must be equal to 14)",
6601 });
6602 }
6603
6604 if len != 4 {
6605 return Err(ValidationError {
6606 layer: SctpRef::name(),
6607 class: ValidationErrorClass::InvalidValue,
6608 #[cfg(feature = "error_string")]
6609 reason:
6610 "invalid length in SCTP SHUTDOWN COMPLETE chunk (must be equal to 4)",
6611 });
6612 }
6613
6614 if bytes.len() > 4 {
6615 Err(ValidationError {
6616 layer: SctpRef::name(),
6617 class: ValidationErrorClass::ExcessBytes(bytes.len() - 4),
6618 #[cfg(feature = "error_string")]
6619 reason: "extra bytes remain at end of SCTP SHUTDOWN COMPLETE chunk",
6620 })
6621 } else {
6622 Ok(())
6623 }
6624 }
6625 _ => Err(ValidationError {
6626 layer: SctpRef::name(),
6627 class: ValidationErrorClass::InsufficientBytes,
6628 #[cfg(feature = "error_string")]
6629 reason: "insufficient bytes in SCTP SHUTDOWN COMPLETE chunk for header",
6630 }),
6631 }
6632 }
6633
6634 #[inline]
6635 pub fn chunk_type(&self) -> u8 {
6636 self.data[0]
6637 }
6638
6639 #[inline]
6640 pub fn flags(&self) -> ShutdownCompleteFlags {
6641 ShutdownCompleteFlags::from_bits_truncate(self.data[1])
6642 }
6643
6644 #[inline]
6645 pub fn unpadded_len(&self) -> u16 {
6646 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
6647 }
6648
6649 #[inline]
6650 pub fn len(&self) -> usize {
6651 utils::padded_length::<4>(self.unpadded_len() as usize)
6652 }
6653}
6654
6655bitflags! {
6656 #[derive(Clone, Copy, Debug, Default)]
6657 pub struct ShutdownCompleteFlags: u8 {
6658 const T = 0b00000001;
6659 }
6660}
6661
6662#[derive(Clone, Debug)]
6677#[cfg(feature = "alloc")]
6678pub struct UnknownChunk {
6679 chunk_type: u8,
6680 flags: u8,
6681 value: Vec<u8>,
6682}
6683
6684#[cfg(feature = "alloc")]
6685impl UnknownChunk {
6686 #[inline]
6687 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
6688 Self::validate(bytes)?;
6689 Ok(Self::from_bytes_unchecked(bytes))
6690 }
6691
6692 #[inline]
6693 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
6694 Self::from(UnknownChunkRef::from_bytes_unchecked(bytes))
6695 }
6696
6697 #[inline]
6698 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
6699 UnknownChunkRef::validate(bytes)
6700 }
6701
6702 #[inline]
6703 pub fn chunk_type(&self) -> u8 {
6704 self.chunk_type
6705 }
6706
6707 #[inline]
6708 pub fn flags_raw(&self) -> u8 {
6709 self.flags
6710 }
6711
6712 #[inline]
6713 pub fn set_flags_raw(&mut self, flags: u8) {
6714 self.flags = flags;
6715 }
6716
6717 #[inline]
6718 pub fn unpadded_len(&self) -> usize {
6719 self.value.len() + 4
6720 }
6721
6722 #[inline]
6723 pub fn len(&self) -> usize {
6724 utils::padded_length::<4>(self.unpadded_len())
6725 }
6726
6727 #[inline]
6728 pub fn value(&self) -> &Vec<u8> {
6729 &self.value
6730 }
6731
6732 #[inline]
6733 pub fn value_mut(&mut self) -> &mut Vec<u8> {
6734 &mut self.value
6735 }
6736
6737 pub fn to_bytes_extended<T: PacketWritable>(
6738 &self,
6739 writer: &mut PacketWriter<'_, T>,
6740 ) -> Result<(), SerializationError> {
6741 writer.write_slice(&[self.chunk_type, self.flags])?;
6742 writer.write_slice(
6743 &u16::try_from(self.unpadded_len())
6744 .map_err(|_| SerializationError::length_encoding(SctpRef::name()))?
6745 .to_be_bytes(),
6746 )?;
6747 writer.write_slice(&self.value)?;
6748
6749 for _ in self.unpadded_len()..self.len() {
6750 writer.write_slice(&[0])?;
6751 }
6752
6753 Ok(())
6754 }
6755}
6756
6757#[cfg(feature = "alloc")]
6758impl From<UnknownChunkRef<'_>> for UnknownChunk {
6759 #[inline]
6760 fn from(value: UnknownChunkRef<'_>) -> Self {
6761 Self::from(&value)
6762 }
6763}
6764
6765#[cfg(feature = "alloc")]
6766impl From<&UnknownChunkRef<'_>> for UnknownChunk {
6767 #[inline]
6768 fn from(value: &UnknownChunkRef<'_>) -> Self {
6769 UnknownChunk {
6770 chunk_type: value.chunk_type(),
6771 flags: value.flags_raw(),
6772 value: Vec::from(value.value()),
6773 }
6774 }
6775}
6776
6777#[derive(Clone, Copy, Debug)]
6792pub struct UnknownChunkRef<'a> {
6793 data: &'a [u8],
6794}
6795
6796impl<'a> UnknownChunkRef<'a> {
6797 #[inline]
6798 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
6799 Self::validate(bytes)?;
6800 Ok(Self::from_bytes_unchecked(bytes))
6801 }
6802
6803 #[inline]
6804 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
6805 UnknownChunkRef { data: bytes }
6806 }
6807
6808 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
6809 match utils::to_array(bytes, 2) {
6810 Some(len_arr) => {
6811 let unpadded_len = u16::from_be_bytes(len_arr) as usize;
6812 let len = utils::padded_length::<4>(unpadded_len);
6813
6814 if bytes.len() < cmp::max(4, len) {
6815 return Err(ValidationError {
6816 layer: SctpRef::name(),
6817 class: ValidationErrorClass::InsufficientBytes,
6818 #[cfg(feature = "error_string")]
6819 reason: "insufficient bytes in SCTP <unknown> chunk for header/Value field",
6820 });
6821 }
6822
6823 if unpadded_len < 4 {
6824 return Err(ValidationError {
6825 layer: SctpRef::name(),
6826 class: ValidationErrorClass::InvalidValue,
6827 #[cfg(feature = "error_string")]
6828 reason:
6829 "invalid length in SCTP <unknown> chunk (must be at least 4 bytes long)",
6830 });
6831 }
6832
6833 for b in bytes.iter().take(len).skip(unpadded_len) {
6834 if *b != 0 {
6835 return Err(ValidationError {
6836 layer: SctpRef::name(),
6837 class: ValidationErrorClass::InvalidValue,
6838 #[cfg(feature = "error_string")]
6839 reason: "invalid nonzero padding values at end of SCTP <unknown> chunk",
6840 });
6841 }
6842 }
6843
6844 if bytes.len() > len {
6845 Err(ValidationError {
6846 layer: SctpRef::name(),
6847 class: ValidationErrorClass::ExcessBytes(bytes.len() - len),
6848 #[cfg(feature = "error_string")]
6849 reason: "extra bytes remain at end of SCTP <unknown> chunk",
6850 })
6851 } else {
6852 Ok(())
6853 }
6854 }
6855 _ => Err(ValidationError {
6856 layer: SctpRef::name(),
6857 class: ValidationErrorClass::InsufficientBytes,
6858 #[cfg(feature = "error_string")]
6859 reason: "insufficient bytes in SCTP <unknown> chunk for header",
6860 }),
6861 }
6862 }
6863
6864 #[inline]
6865 pub fn chunk_type(&self) -> u8 {
6866 self.data[0]
6867 }
6868
6869 #[inline]
6870 pub fn flags_raw(&self) -> u8 {
6871 self.data[1]
6872 }
6873
6874 #[inline]
6875 pub fn unpadded_len(&self) -> u16 {
6876 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
6877 }
6878
6879 #[inline]
6880 pub fn len(&self) -> usize {
6881 utils::padded_length::<4>(self.unpadded_len() as usize)
6882 }
6883
6884 #[inline]
6885 pub fn value(&self) -> &[u8] {
6886 &self.data[4..self.unpadded_len() as usize]
6887 }
6888}
6889
6890#[derive(Clone, Debug, Layer, StatelessLayer)]
6911#[metadata_type(SctpDataChunkMetadata)]
6912#[ref_type(SctpDataChunkRef)]
6913#[cfg(feature = "alloc")]
6914pub struct SctpDataChunk {
6915 flags: DataChunkFlags,
6916 tsn: u32,
6917 stream_id: u16,
6918 stream_seq: u16,
6919 proto_id: u32,
6920 payload: Option<Box<dyn LayerObject>>,
6921}
6922
6923#[cfg(feature = "alloc")]
6924impl SctpDataChunk {
6925 #[inline]
6928 pub fn from_bytes(bytes: &[u8]) -> Result<Self, ValidationError> {
6929 Self::validate(bytes)?;
6930 Ok(Self::from_bytes_unchecked(bytes))
6931 }
6932
6933 #[inline]
6940 pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
6941 Self::from(SctpDataChunkRef::from_bytes_unchecked(bytes))
6942 }
6943
6944 #[inline]
6949 pub fn validate(bytes: &[u8]) -> Result<(), ValidationError> {
6950 SctpDataChunkRef::validate(bytes)
6951 }
6952
6953 #[inline]
6955 pub fn chunk_type(&self) -> u8 {
6956 CHUNK_TYPE_DATA
6957 }
6958
6959 #[inline]
6961 pub fn flags(&self) -> DataChunkFlags {
6962 self.flags
6963 }
6964
6965 #[inline]
6967 pub fn set_flags(&mut self, flags: DataChunkFlags) {
6968 self.flags = flags;
6969 }
6970
6971 #[inline]
6973 pub fn unpadded_len(&self) -> usize {
6974 16 + match &self.payload {
6976 Some(p) => p.len(),
6977 None => 0,
6978 }
6979 }
6980
6981 #[inline]
6983 pub fn len(&self) -> usize {
6984 utils::padded_length::<4>(self.unpadded_len())
6985 }
6986
6987 #[inline]
6989 pub fn tsn(&self) -> u32 {
6990 self.tsn
6991 }
6992
6993 #[inline]
6995 pub fn set_tsn(&mut self, tsn: u32) {
6996 self.tsn = tsn;
6997 }
6998
6999 #[inline]
7001 pub fn stream_id(&self) -> u16 {
7002 self.stream_id
7003 }
7004
7005 #[inline]
7007 pub fn set_stream_id(&mut self, stream_id: u16) {
7008 self.stream_id = stream_id;
7009 }
7010
7011 #[inline]
7013 pub fn stream_seq(&self) -> u16 {
7014 self.stream_seq
7015 }
7016
7017 #[inline]
7019 pub fn set_stream_seq(&mut self, stream_seq: u16) {
7020 self.stream_seq = stream_seq;
7021 }
7022
7023 #[inline]
7025 pub fn proto_id(&self) -> u32 {
7026 self.proto_id
7027 }
7028
7029 #[inline]
7031 pub fn set_proto_id(&mut self, proto_id: u32) {
7032 self.proto_id = proto_id;
7033 }
7034}
7035
7036#[cfg(feature = "alloc")]
7037impl LayerLength for SctpDataChunk {
7038 #[inline]
7039 fn len(&self) -> usize {
7040 16 + match &self.payload {
7041 Some(p) => utils::padded_length::<4>(p.len()),
7042 None => 0,
7043 }
7044 }
7045}
7046
7047#[allow(unused_variables)]
7048#[cfg(feature = "alloc")]
7049impl LayerObject for SctpDataChunk {
7050 fn can_add_payload_default(&self, payload: &dyn LayerObject) -> bool {
7051 true }
7053
7054 #[inline]
7055 fn add_payload_unchecked(&mut self, payload: Box<dyn LayerObject>) {
7056 self.payload = Some(payload);
7057 }
7058
7059 #[inline]
7060 fn payloads(&self) -> &[Box<dyn LayerObject>] {
7061 match &self.payload {
7062 Some(p) => slice::from_ref(p),
7063 None => &[],
7064 }
7065 }
7066
7067 fn payloads_mut(&mut self) -> &mut [Box<dyn LayerObject>] {
7068 match &mut self.payload {
7069 Some(p) => slice::from_mut(p),
7070 None => &mut [],
7071 }
7072 }
7073
7074 fn remove_payload_at(&mut self, index: usize) -> Option<Box<dyn LayerObject>> {
7075 if index == 0 {
7076 let mut ret = None;
7077 mem::swap(&mut ret, &mut self.payload);
7078 ret
7079 } else {
7080 None
7081 }
7082 }
7083}
7084
7085#[cfg(feature = "alloc")]
7086impl ToBytes for SctpDataChunk {
7087 fn to_bytes_checksummed(
7088 &self,
7089 writer: &mut PacketWriter<'_, Vec<u8>>,
7090 _prev: Option<(LayerId, usize)>,
7091 ) -> Result<(), SerializationError> {
7092 let start = writer.len();
7093 writer.update_layer::<SctpDataChunk>();
7094 writer.write_slice(&[0, self.flags.bits()])?; writer.write_slice(
7096 &u16::try_from(self.unpadded_len())
7097 .map_err(|_| SerializationError::length_encoding(SctpDataChunk::name()))?
7098 .to_be_bytes(),
7099 )?;
7100 writer.write_slice(&self.tsn.to_be_bytes())?;
7101 writer.write_slice(&self.stream_id.to_be_bytes())?;
7102 writer.write_slice(&self.stream_seq.to_be_bytes())?;
7103 writer.write_slice(&self.proto_id.to_be_bytes())?;
7104 if let Some(p) = &self.payload {
7105 p.to_bytes_checksummed(writer, Some((SctpDataChunk::layer_id(), start)))?;
7106 }
7107
7108 for _ in self.unpadded_len() as usize..self.len() {
7109 writer.write_slice(&[0])?;
7110 }
7111
7112 Ok(())
7113 }
7114}
7115
7116#[doc(hidden)]
7117#[cfg(feature = "alloc")]
7118impl FromBytesCurrent for SctpDataChunk {
7119 fn from_bytes_current_layer_unchecked(bytes: &[u8]) -> Self {
7120 let data = SctpDataChunkRef::from_bytes_unchecked(bytes);
7121 SctpDataChunk {
7122 flags: data.flags(),
7123 tsn: data.tsn(),
7124 stream_id: data.stream_id(),
7125 stream_seq: data.stream_seq(),
7126 proto_id: data.proto_id(),
7127 payload: None,
7128 }
7129 }
7130
7131 #[inline]
7132 fn payload_from_bytes_unchecked_default(&mut self, bytes: &[u8]) {
7133 let data = SctpDataChunkRef::from_bytes_unchecked(bytes);
7134 self.payload = Some(Box::new(Raw::from_bytes_unchecked(data.user_data())));
7135 }
7136}
7137
7138#[derive(Clone, Copy, Debug, LayerRef, StatelessLayer)]
7159#[owned_type(SctpDataChunk)]
7160#[metadata_type(SctpDataChunkMetadata)]
7161pub struct SctpDataChunkRef<'a> {
7162 #[data_field]
7163 data: &'a [u8],
7164}
7165
7166impl<'a> SctpDataChunkRef<'a> {
7167 #[inline]
7170 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, ValidationError> {
7171 Self::validate(bytes)?;
7172 Ok(Self::from_bytes_unchecked(bytes))
7173 }
7174
7175 #[inline]
7183 pub fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
7184 SctpDataChunkRef { data: bytes }
7185 }
7186
7187 #[inline]
7189 pub fn chunk_type(&self) -> u8 {
7190 self.data[0]
7191 }
7192
7193 #[inline]
7195 pub fn flags(&self) -> DataChunkFlags {
7196 DataChunkFlags::from_bits_truncate(self.data[1])
7197 }
7198
7199 #[inline]
7201 pub fn chunk_len(&self) -> u16 {
7202 u16::from_be_bytes(utils::to_array(self.data, 2).unwrap())
7203 }
7204
7205 #[inline]
7207 pub fn chunk_len_padded(&self) -> usize {
7208 utils::padded_length::<4>(self.chunk_len() as usize)
7209 }
7210
7211 #[inline]
7213 pub fn tsn(&self) -> u32 {
7214 u32::from_be_bytes(utils::to_array(self.data, 4).unwrap())
7215 }
7216
7217 #[inline]
7219 pub fn stream_id(&self) -> u16 {
7220 u16::from_be_bytes(utils::to_array(self.data, 8).unwrap())
7221 }
7222
7223 #[inline]
7225 pub fn stream_seq(&self) -> u16 {
7226 u16::from_be_bytes(utils::to_array(self.data, 10).unwrap())
7227 }
7228
7229 #[inline]
7231 pub fn proto_id(&self) -> u32 {
7232 u32::from_be_bytes(utils::to_array(self.data, 12).unwrap())
7233 }
7234
7235 #[inline]
7237 pub fn user_data(&self) -> &[u8] {
7238 self.data.get(16..self.chunk_len() as usize).unwrap()
7239 }
7240
7241 #[inline]
7243 pub fn padding(&self) -> &[u8] {
7244 &self.data[self.chunk_len() as usize..self.chunk_len_padded()]
7245 }
7246}
7247
7248impl LayerOffset for SctpDataChunkRef<'_> {
7249 #[inline]
7250 fn payload_byte_index_default(bytes: &[u8], _layer_type: LayerId) -> Option<usize> {
7251 if bytes.len() > 16 {
7252 Some(16)
7253 } else {
7254 None
7255 }
7256 }
7257}
7258
7259impl Validate for SctpDataChunkRef<'_> {
7260 fn validate_current_layer(curr_layer: &[u8]) -> Result<(), ValidationError> {
7261 let len = match utils::to_array(curr_layer, 2) {
7262 None => {
7263 return Err(ValidationError {
7264 layer: Self::name(),
7265 class: ValidationErrorClass::InsufficientBytes,
7266 #[cfg(feature = "error_string")]
7267 reason: "SCTP DATA chunk must have a minimum of 16 bytes for its header",
7268 })
7269 }
7270 Some(arr) => u16::from_be_bytes(arr) as usize,
7271 };
7272
7273 let payload_type = curr_layer[0]; if payload_type != 0 {
7275 return Err(ValidationError {
7276 layer: Self::name(),
7277 class: ValidationErrorClass::InvalidValue,
7278 #[cfg(feature = "error_string")]
7279 reason: "invalid Chunk Type field in SCTP DATA chunk (must be equal to 0)",
7280 });
7281 }
7282
7283 if len < 17 {
7284 return Err(ValidationError {
7285 layer: Self::name(),
7286 class: ValidationErrorClass::InvalidValue,
7287 #[cfg(feature = "error_string")]
7288 reason: "packet length field had invalid value (insufficient length to cover packet header and at least one byte of data) for SCTP DATA chunk",
7289 });
7290 }
7291
7292 Ok(())
7293 }
7294
7295 #[inline]
7296 fn validate_payload_default(curr_layer: &[u8]) -> Result<(), ValidationError> {
7297 let data = SctpDataChunkRef::from_bytes_unchecked(curr_layer);
7298 let padded_len = data.chunk_len_padded();
7299 if padded_len > curr_layer.len() {
7300 return Err(ValidationError {
7301 layer: Self::name(),
7302 class: ValidationErrorClass::InsufficientBytes,
7303 #[cfg(feature = "error_string")]
7304 reason: "insufficient bytes for User Data portion of SCTP DATA chunk",
7305 });
7306 }
7307
7308 let len = data.chunk_len() as usize;
7309
7310 for b in curr_layer.iter().take(padded_len).skip(len) {
7313 if *b != 0 {
7314 return Err(ValidationError {
7315 layer: Self::name(),
7316 class: ValidationErrorClass::UnusualPadding,
7317 #[cfg(feature = "error_string")]
7318 reason: "padding at end of SCTP DATA chunk had a non-zero value",
7319 });
7320 }
7321 }
7322
7323 if padded_len < curr_layer.len() {
7324 Err(ValidationError {
7325 layer: Self::name(),
7326 class: ValidationErrorClass::ExcessBytes(curr_layer.len() - padded_len),
7327 #[cfg(feature = "error_string")]
7328 reason: "SCTP DATA chunk had additional trailing bytes at the end of its data",
7329 })
7330 } else {
7331 Ok(())
7332 }
7333 }
7334}
7335
7336bitflags! {
7337 #[derive(Clone, Copy, Debug, Default)]
7339 pub struct DataChunkFlags: u8 {
7340 const R1 = 0b10000000;
7341 const R2 = 0b01000000;
7342 const R3 = 0b00100000;
7343 const R4 = 0b00010000;
7344 const IMMEDIATE = 0b00001000;
7345 const UNORDERED = 0b00000100;
7346 const BEGIN_FRAGMENT = 0b00000010;
7347 const END_FRAGMENT = 0b00000001;
7348 }
7349}
7350
7351impl From<u8> for DataChunkFlags {
7352 fn from(value: u8) -> Self {
7353 DataChunkFlags::from_bits_truncate(value)
7354 }
7355}