Skip to content
File

Blob: firmware/vendor/str0m/src/sctp/dcep.rs

rust123 lines
1use std::str::from_utf8;
2 
3use sctp_proto::ReliabilityType;
4 
5use super::SctpError as Error;
6 
7// 0 1 2 3
8// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
9// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
10// | Message Type | Channel Type | Priority |
11// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
12// | Reliability Parameter |
13// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
14// | Label Length | Protocol Length |
15// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16// \ /
17// | Label |
18// / \
19// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
20// \ /
21// | Protocol |
22// / \
23// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24 
25/// Data channel establishment protocol.
26/// RFC 8832
27#[derive(Clone, Debug)]
28pub struct DcepOpen {
29 pub unordered: bool,
30 pub channel_type: ReliabilityType,
31 pub priority: u16,
32 pub reliability_parameter: u32,
33 pub label: String,
34 pub protocol: String,
35}
36 
37impl TryFrom<&[u8]> for DcepOpen {
38 type Error = Error;
39 
40 fn try_from(buf: &[u8]) -> Result<Self, Self::Error> {
41 if buf.len() < 12 {
42 return Err(Error::DcepOpenTooSmall);
43 }
44 
45 if buf[0] != 0x03 {
46 return Err(Error::DcepIncorrectMessageType);
47 }
48 
49 let unordered = buf[1] & 0x80 > 0;
50 let channel_type: ReliabilityType = (buf[1] & 0x7f).into();
51 let priority = u16::from_be_bytes([buf[2], buf[3]]);
52 let reliability_parameter = u32::from_be_bytes([buf[4], buf[5], buf[6], buf[7]]);
53 let len_label = u16::from_be_bytes([buf[8], buf[9]]) as usize;
54 let len_proto = u16::from_be_bytes([buf[10], buf[11]]) as usize;
55 
56 if buf.len() < 12 + len_label + len_proto {
57 return Err(Error::DcepOpenTooSmall);
58 }
59 
60 let buf = &buf[12..];
61 let label = from_utf8(&buf[0..len_label])
62 .map_err(|_| Error::DcepBadUtf8)?
63 .to_string();
64 
65 let buf = &buf[len_label..];
66 let protocol = from_utf8(&buf[0..len_proto])
67 .map_err(|_| Error::DcepBadUtf8)?
68 .to_string();
69 
70 Ok(DcepOpen {
71 unordered,
72 channel_type,
73 priority,
74 reliability_parameter,
75 label,
76 protocol,
77 })
78 }
79}
80 
81impl DcepOpen {
82 pub fn marshal_to(&self, buf: &mut [u8]) -> usize {
83 buf[0] = 0x03;
84 buf[1] = (self.channel_type as u8) | if self.unordered { 0x80 } else { 0x00 };
85 buf[2..4].copy_from_slice(&self.priority.to_be_bytes());
86 buf[4..8].copy_from_slice(&self.reliability_parameter.to_be_bytes());
87 let bytes_label = self.label.as_bytes();
88 let bytes_proto = self.protocol.as_bytes();
89 buf[8..10].copy_from_slice(&(bytes_label.len() as u16).to_be_bytes());
90 buf[10..12].copy_from_slice(&(bytes_proto.len() as u16).to_be_bytes());
91 let buf = &mut buf[12..];
92 buf[..bytes_label.len()].copy_from_slice(bytes_label);
93 let buf = &mut buf[bytes_label.len()..];
94 buf[..bytes_proto.len()].copy_from_slice(bytes_proto);
95 12 + bytes_label.len() + bytes_proto.len()
96 }
97}
98 
99pub struct DcepAck;
100 
101impl TryFrom<&[u8]> for DcepAck {
102 type Error = Error;
103 
104 fn try_from(buf: &[u8]) -> Result<Self, Self::Error> {
105 if buf.is_empty() {
106 return Err(Error::DcepOpenTooSmall);
107 }
108 
109 if buf[0] != 0x02 {
110 return Err(Error::DcepIncorrectMessageType);
111 }
112 
113 Ok(DcepAck)
114 }
115}
116 
117impl DcepAck {
118 pub fn marshal_to(&self, buf: &mut [u8]) -> usize {
119 buf[0] = 0x02;
120 1
121 }
122}