1 use 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)] 7 pub 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 32 impl 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. from_u8(code_u8: u8) -> Option<ParameterProblemCode>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] code_u8(&self) -> u860 pub fn code_u8(&self) -> u8 { 61 *self as u8 62 } 63 } 64 65 #[cfg(test)] 66 pub(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)] 110 mod test { 111 use super::{parameter_problem_code_test_consts::*, ParameterProblemCode::*, *}; 112 use alloc::format; 113 114 #[test] from_u8()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] code_u8()126 fn code_u8() { 127 for t in VALID_VALUES { 128 assert_eq!(t.0.code_u8(), t.1); 129 } 130 } 131 #[test] clone_eq()132 fn clone_eq() { 133 for (value, _) in VALID_VALUES { 134 assert_eq!(value.clone(), value); 135 } 136 } 137 138 #[test] debug()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 } 169