c_its_parser/transport/
decode.rs1use etherparse::PacketHeaders;
2use nom::bytes::streaming::take;
3use nom::combinator::{into, map_res};
4use nom::error::{ErrorKind, FromExternalError, ParseError};
5use nom::sequence::pair;
6
7#[derive(Debug, PartialEq)]
8pub enum DecodeError<I> {
9 IntegerError(alloc::string::String),
10 IPv6Parsing(alloc::string::String),
11 Nom(I, ErrorKind),
12 #[cfg(feature = "json")]
13 Json(alloc::string::String),
14}
15
16impl<I> ParseError<I> for DecodeError<I> {
17 fn from_error_kind(input: I, kind: ErrorKind) -> Self {
18 DecodeError::Nom(input, kind)
19 }
20
21 fn append(_: I, _: ErrorKind, other: Self) -> Self {
22 other
23 }
24}
25
26impl<I, E> FromExternalError<I, E> for DecodeError<I> {
27 fn from_external_error(input: I, kind: ErrorKind, _: E) -> Self {
28 DecodeError::Nom(input, kind)
29 }
30}
31
32pub type IResult<I, T> = nom::IResult<I, T, DecodeError<I>>;
33
34pub trait Decode: Sized {
35 fn decode(input: &[u8]) -> IResult<&[u8], Self>;
51}
52
53impl Decode for super::BasicTransportAHeader {
54 fn decode(input: &[u8]) -> IResult<&[u8], Self> {
55 into(pair(u16_from_be_bytes, u16_from_be_bytes))(input)
56 }
57}
58
59impl From<(u16, u16)> for super::BasicTransportAHeader {
60 fn from(value: (u16, u16)) -> Self {
61 Self {
62 destination_port: value.0,
63 source_port: value.1,
64 }
65 }
66}
67
68impl super::BasicTransportAHeader {
69 #[cfg(feature = "json")]
70 pub fn decode_from_json(input: &str) -> Result<Self, DecodeError<&str>> {
75 serde_json::from_str(input)
76 .map_err(|e| DecodeError::Json(alloc::format!("Error encoding to JSON: {e:?}")))
77 }
78}
79
80impl Decode for super::BasicTransportBHeader {
81 fn decode(input: &[u8]) -> IResult<&[u8], Self> {
82 into(pair(u16_from_be_bytes, u16_from_be_bytes))(input)
83 }
84}
85
86impl From<(u16, u16)> for super::BasicTransportBHeader {
87 fn from(value: (u16, u16)) -> Self {
88 Self {
89 destination_port: value.0,
90 destination_port_info: value.1,
91 }
92 }
93}
94
95impl super::BasicTransportBHeader {
96 #[cfg(feature = "json")]
97 pub fn decode_from_json(input: &str) -> Result<Self, DecodeError<&str>> {
102 serde_json::from_str(input)
103 .map_err(|e| DecodeError::Json(alloc::format!("Error encoding to JSON: {e:?}")))
104 }
105}
106
107fn u16_from_be_bytes(input: &[u8]) -> IResult<&[u8], u16> {
108 map_res(take(2usize), |slice: &[u8]| {
109 slice.try_into().map(u16::from_be_bytes).map_err(|e| {
110 DecodeError::IntegerError::<&[u8]>(alloc::format!(
111 "Failed to construct integer from bytes: {e:?}"
112 ))
113 })
114 })(input)
115}
116
117impl Decode for super::IPv6Header {
118 fn decode(input: &[u8]) -> IResult<&[u8], Self> {
119 etherparse::PacketHeaders::from_ip_slice(input)
120 .map(|headers| {
121 let first_after_headers = headers
122 .net
123 .as_ref()
124 .map_or(0, etherparse::NetHeaders::header_len)
125 + headers
126 .link
127 .as_ref()
128 .map_or(0, etherparse::LinkHeader::header_len)
129 + headers
130 .transport
131 .as_ref()
132 .map_or(0, etherparse::TransportHeader::header_len)
133 + headers
134 .link_exts
135 .first()
136 .map_or(0, etherparse::LinkExtHeader::header_len);
137 (
138 &input[first_after_headers..],
139 super::IPv6Header::from(headers),
140 )
141 })
142 .map_err(|e| {
143 nom::Err::Error(DecodeError::IPv6Parsing(alloc::format!(
144 "Error parsing IPv6 Header: {e:?}"
145 )))
146 })
147 }
148}
149
150impl From<PacketHeaders<'_>> for super::IPv6Header {
151 fn from(value: PacketHeaders<'_>) -> Self {
152 Self {
153 ip: value.net,
154 link: value.link,
155 transport: value.transport,
156 link_ext: value.link_exts.first().cloned(),
157 }
158 }
159}
160
161#[cfg(test)]
162mod tests {}