Skip to main content

etherparse/transport/icmpv6/
parameter_problem_code.rs

1use super::*;
2
3/// Code values for ICMPv6 parameter problem messages.
4///
5/// Source: <https://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xhtml#icmpv6-parameters-codes-5>
6#[derive(Clone, Copy, Debug, PartialEq, Eq, Ord, PartialOrd, Hash)]
7pub enum ParameterProblemCode {
8    /// Erroneous header field encountered (from [RFC 4443](https://tools.ietf.org/html/rfc4443))
9    ErroneousHeaderField = 0,
10    /// Unrecognized Next Header type encountered (from [RFC 4443](https://tools.ietf.org/html/rfc4443))
11    UnrecognizedNextHeader = 1,
12    /// Unrecognized IPv6 option encountered (from [RFC 4443](https://tools.ietf.org/html/rfc4443))
13    UnrecognizedIpv6Option = 2,
14    /// IPv6 First Fragment has incomplete IPv6 Header Chain (from [RFC 7112](https://tools.ietf.org/html/rfc7112))
15    Ipv6FirstFragmentIncompleteHeaderChain = 3,
16    /// SR Upper-layer Header Error (from [RFC 8754](https://tools.ietf.org/html/rfc8754)).
17    SrUpperLayerHeaderError = 4,
18    /// Unrecognized Next Header type encountered by intermediate node (from [RFC 8883](https://tools.ietf.org/html/rfc8883))
19    UnrecognizedNextHeaderByIntermediateNode = 5,
20    /// Extension header too big (from [RFC 8883](https://tools.ietf.org/html/rfc8883))
21    ExtensionHeaderTooBig = 6,
22    /// Extension header chain too long (from [RFC 8883](https://tools.ietf.org/html/rfc8883))
23    ExtensionHeaderChainTooLong = 7,
24    /// Too many extension headers (from [RFC 8883](https://tools.ietf.org/html/rfc8883))
25    TooManyExtensionHeaders = 8,
26    /// Too many options in extension header (from [RFC 8883](https://tools.ietf.org/html/rfc8883))
27    TooManyOptionsInExtensionHeader = 9,
28    /// Option too big (from [RFC 8883](https://tools.ietf.org/html/rfc8883))
29    OptionTooBig = 10,
30}
31
32impl ParameterProblemCode {
33    /// Tries to convert a code [`u8`] value to a [`ParameterProblemCode`] value.
34    ///
35    /// Returns [`None`] in case the code value is not known as a parameter problem code.
36    pub fn from_u8(code_u8: u8) -> Option<ParameterProblemCode> {
37        use ParameterProblemCode::*;
38        match code_u8 {
39            CODE_PARAM_PROBLEM_ERR_HEADER_FIELD => Some(ErroneousHeaderField),
40            CODE_PARAM_PROBLEM_UNRECOG_NEXT_HEADER => Some(UnrecognizedNextHeader),
41            CODE_PARAM_PROBLEM_UNRECOG_IPV6_OPTION => Some(UnrecognizedIpv6Option),
42            CODE_PARAM_PROBLEM_IPV6_FIRST_FRAG_INCOMP_HEADER_CHAIN => {
43                Some(Ipv6FirstFragmentIncompleteHeaderChain)
44            }
45            CODE_PARAM_PROBLEM_SR_UPPER_LAYER_HEADER_ERROR => Some(SrUpperLayerHeaderError),
46            CODE_PARAM_PROBLEM_UNRECOG_NEXT_HEADER_BY_INTERMEDIATE_NODE => {
47                Some(UnrecognizedNextHeaderByIntermediateNode)
48            }
49            CODE_PARAM_PROBLEM_EXT_HEADER_TOO_BIG => Some(ExtensionHeaderTooBig),
50            CODE_PARAM_PROBLEM_EXT_HEADER_CHAIN_TOO_LONG => Some(ExtensionHeaderChainTooLong),
51            CODE_PARAM_PROBLEM_TOO_MANY_EXT_HEADERS => Some(TooManyExtensionHeaders),
52            CODE_PARAM_PROBLEM_TOO_MANY_OPTIONS_EXT_HEADER => Some(TooManyOptionsInExtensionHeader),
53            CODE_PARAM_PROBLEM_OPTION_TOO_BIG => Some(OptionTooBig),
54            _ => None,
55        }
56    }
57
58    /// Returns the [`u8`] value of the code.
59    #[inline]
60    pub fn code_u8(&self) -> u8 {
61        *self as u8
62    }
63}
64
65#[cfg(test)]
66pub(crate) mod parameter_problem_code_test_consts {
67    use super::*;
68    use ParameterProblemCode::*;
69
70    pub const VALID_VALUES: [(ParameterProblemCode, u8); 11] = [
71        (ErroneousHeaderField, CODE_PARAM_PROBLEM_ERR_HEADER_FIELD),
72        (
73            UnrecognizedNextHeader,
74            CODE_PARAM_PROBLEM_UNRECOG_NEXT_HEADER,
75        ),
76        (
77            UnrecognizedIpv6Option,
78            CODE_PARAM_PROBLEM_UNRECOG_IPV6_OPTION,
79        ),
80        (
81            Ipv6FirstFragmentIncompleteHeaderChain,
82            CODE_PARAM_PROBLEM_IPV6_FIRST_FRAG_INCOMP_HEADER_CHAIN,
83        ),
84        (
85            SrUpperLayerHeaderError,
86            CODE_PARAM_PROBLEM_SR_UPPER_LAYER_HEADER_ERROR,
87        ),
88        (
89            UnrecognizedNextHeaderByIntermediateNode,
90            CODE_PARAM_PROBLEM_UNRECOG_NEXT_HEADER_BY_INTERMEDIATE_NODE,
91        ),
92        (ExtensionHeaderTooBig, CODE_PARAM_PROBLEM_EXT_HEADER_TOO_BIG),
93        (
94            ExtensionHeaderChainTooLong,
95            CODE_PARAM_PROBLEM_EXT_HEADER_CHAIN_TOO_LONG,
96        ),
97        (
98            TooManyExtensionHeaders,
99            CODE_PARAM_PROBLEM_TOO_MANY_EXT_HEADERS,
100        ),
101        (
102            TooManyOptionsInExtensionHeader,
103            CODE_PARAM_PROBLEM_TOO_MANY_OPTIONS_EXT_HEADER,
104        ),
105        (OptionTooBig, CODE_PARAM_PROBLEM_OPTION_TOO_BIG),
106    ];
107}
108
109#[cfg(test)]
110mod test {
111    use super::{parameter_problem_code_test_consts::*, ParameterProblemCode::*, *};
112    use alloc::format;
113
114    #[test]
115    fn from_u8() {
116        for t in VALID_VALUES {
117            assert_eq!(Some(t.0), ParameterProblemCode::from_u8(t.1));
118        }
119
120        for code_u8 in 11..=u8::MAX {
121            assert_eq!(None, ParameterProblemCode::from_u8(code_u8));
122        }
123    }
124
125    #[test]
126    fn code_u8() {
127        for t in VALID_VALUES {
128            assert_eq!(t.0.code_u8(), t.1);
129        }
130    }
131    #[test]
132    fn clone_eq() {
133        for (value, _) in VALID_VALUES {
134            assert_eq!(value.clone(), value);
135        }
136    }
137
138    #[test]
139    fn debug() {
140        let tests = [
141            (ErroneousHeaderField, "ErroneousHeaderField"),
142            (UnrecognizedNextHeader, "UnrecognizedNextHeader"),
143            (UnrecognizedIpv6Option, "UnrecognizedIpv6Option"),
144            (UnrecognizedNextHeader, "UnrecognizedNextHeader"),
145            (UnrecognizedIpv6Option, "UnrecognizedIpv6Option"),
146            (
147                Ipv6FirstFragmentIncompleteHeaderChain,
148                "Ipv6FirstFragmentIncompleteHeaderChain",
149            ),
150            (SrUpperLayerHeaderError, "SrUpperLayerHeaderError"),
151            (
152                UnrecognizedNextHeaderByIntermediateNode,
153                "UnrecognizedNextHeaderByIntermediateNode",
154            ),
155            (ExtensionHeaderTooBig, "ExtensionHeaderTooBig"),
156            (ExtensionHeaderChainTooLong, "ExtensionHeaderChainTooLong"),
157            (TooManyExtensionHeaders, "TooManyExtensionHeaders"),
158            (
159                TooManyOptionsInExtensionHeader,
160                "TooManyOptionsInExtensionHeader",
161            ),
162            (OptionTooBig, "OptionTooBig"),
163        ];
164        for test in tests {
165            assert_eq!(format!("{:?}", test.0), test.1);
166        }
167    }
168}