etherparse/net/
ip_number_impl.rs

1/// This type has been deprecated please use [IpNumber] instead.
2///
3/// IPv6 headers have a field called `traffic_class` which has nothing
4/// to do this enum. This unlucky coincedence got even the developer
5/// of this library confused enough to write that the next header number
6/// should be written into the `traffic_class` field instead of the
7/// `next_header` field.
8///
9/// To avoid such confusions in the future the enum has been renamed
10/// to [IpNumber], which also closer to the name
11/// "Assigned Internet Protocol Numbers" used on iana.org .
12#[deprecated(since = "0.10.1", note = "Please use the type IpNumber instead")]
13pub type IpTrafficClass = IpNumber;
14
15/// Identifiers for the next_header field in ipv6 headers and protocol field in ipv4 headers.
16///
17/// You can access the underlying `u8` value by using `.0` and any `u8`
18/// can be converted to an `IpNumber`:
19///
20/// ```
21/// use etherparse::IpNumber;
22///
23/// assert_eq!(IpNumber::TCP.0, 6);
24/// assert_eq!(IpNumber::TCP, IpNumber(6));
25///
26/// // convert to IpNumber using the from & into trait
27/// let ip_num: IpNumber = 6.into();
28/// assert_eq!(IpNumber::TCP, ip_num);
29///
30/// // convert to u8 using the from & into trait
31/// let num: u8 = IpNumber::TCP.into();
32/// assert_eq!(6, num);
33/// ```
34///
35/// The constants are also defined in the `ip_number` module so they can
36/// be used without the need to write `IpNumber::` in front of them:
37///
38/// ```
39/// use etherparse::{ip_number::TCP, IpNumber};
40///
41/// assert_eq!(TCP, IpNumber::TCP);
42/// ```
43///
44/// The list original values were copied from
45/// <https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml>
46#[derive(PartialEq, Eq, Clone, Copy, Hash, Ord, PartialOrd)]
47pub struct IpNumber(pub u8);
48
49impl IpNumber {
50    /// IPv6 Hop-by-Hop Option \[[RFC8200](https://datatracker.ietf.org/doc/html/rfc8200)\]
51    pub const IPV6_HEADER_HOP_BY_HOP: IpNumber = Self(0);
52    /// Internet Control Message \[[RFC792](https://datatracker.ietf.org/doc/html/rfc792)\]
53    pub const ICMP: IpNumber = Self(1);
54    /// Internet Group Management \[[RFC1112](https://datatracker.ietf.org/doc/html/rfc1112)\]
55    pub const IGMP: IpNumber = Self(2);
56    /// Gateway-to-Gateway \[[RFC823](https://datatracker.ietf.org/doc/html/rfc823)\]
57    pub const GGP: IpNumber = Self(3);
58    /// IPv4 encapsulation \[[RFC2003](https://datatracker.ietf.org/doc/html/rfc2003)\]
59    pub const IPV4: IpNumber = Self(4);
60    /// Stream \[[RFC1190](https://datatracker.ietf.org/doc/html/rfc1190)\] \[[RFC1819](https://datatracker.ietf.org/doc/html/rfc1819)\]
61    pub const STREAM: IpNumber = Self(5);
62    /// Transmission Control \[[RFC793](https://datatracker.ietf.org/doc/html/rfc793)\]
63    pub const TCP: IpNumber = Self(6);
64    /// CBT \[Tony_Ballardie\]
65    pub const CBT: IpNumber = Self(7);
66    /// Exterior Gateway Protocol \[[RFC888](https://datatracker.ietf.org/doc/html/rfc888)\] \[David_Mills\]
67    pub const EGP: IpNumber = Self(8);
68    /// any private interior gateway (used by Cisco for their IGRP) \[Internet_Assigned_Numbers_Authority\]
69    pub const IGP: IpNumber = Self(9);
70    /// BBN RCC Monitoring \[Steve_Chipman\]
71    pub const BBN_RCC_MON: IpNumber = Self(10);
72    /// Network Voice Protocol \[[RFC741](https://datatracker.ietf.org/doc/html/rfc741)\]\[Steve_Casner\]
73    pub const NVP_II: IpNumber = Self(11);
74    /// PUP
75    pub const PUP: IpNumber = Self(12);
76    /// ARGUS (deprecated) \[Robert_W_Scheifler\]
77    pub const ARGUS: IpNumber = Self(13);
78    /// EMCON \[mystery contact\]
79    pub const EMCON: IpNumber = Self(14);
80    /// Cross Net Debugger \[Haverty, J., "XNET Formats for Internet Protocol Version 4", IEN 158, October 1980.\]\[Jack_Haverty\]
81    pub const XNET: IpNumber = Self(15);
82    /// Chaos \[J_Noel_Chiappa\]
83    pub const CHAOS: IpNumber = Self(16);
84    /// User Datagram \[[RFC768](https://datatracker.ietf.org/doc/html/rfc768)\]\[Jon_Postel\]
85    pub const UDP: IpNumber = Self(17);
86    /// Multiplexing \[Cohen, D. and J. Postel, "Multiplexing Protocol", IEN 90, USC/Information Sciences Institute, May 1979.\]\[Jon_Postel\]
87    pub const MUX: IpNumber = Self(18);
88    /// DCN Measurement Subsystems \[David_Mills\]
89    pub const DCN_MEAS: IpNumber = Self(19);
90    /// Host Monitoring \[[RFC869](https://datatracker.ietf.org/doc/html/rfc869)\]\[Bob_Hinden\]
91    pub const HMP: IpNumber = Self(20);
92    /// Packet Radio Measurement \[Zaw_Sing_Su\]
93    pub const PRM: IpNumber = Self(21);
94    /// XEROX NS IDP
95    pub const XNS_IDP: IpNumber = Self(22);
96    /// Trunk-1 \[Barry_Boehm\]
97    pub const TRUNK1: IpNumber = Self(23);
98    /// Trunk-2 \[Barry_Boehm\]
99    pub const TRUNK2: IpNumber = Self(24);
100    /// Leaf-1 \[Barry_Boehm\]
101    pub const LEAF1: IpNumber = Self(25);
102    /// Leaf-2 \[Barry_Boehm\]
103    pub const LEAF2: IpNumber = Self(26);
104    /// Reliable Data Protocol \[[RFC908](https://datatracker.ietf.org/doc/html/rfc908)\] \[Bob_Hinden\]
105    pub const RDP: IpNumber = Self(27);
106    /// Internet Reliable Transaction \[[RFC938](https://datatracker.ietf.org/doc/html/rfc938)\] \[Trudy_Miller\]
107    pub const IRTP: IpNumber = Self(28);
108    /// ISO Transport Protocol Class 4 \[[RFC905](https://datatracker.ietf.org/doc/html/rfc905)\] \[mystery contact\]
109    pub const ISO_TP4: IpNumber = Self(29);
110    /// Bulk Data Transfer Protocol \[[RFC969](https://datatracker.ietf.org/doc/html/rfc969)\] \[David_Clark\]
111    pub const NET_BLT: IpNumber = Self(30);
112    /// MFE Network Services Protocol \[Shuttleworth, B., "A Documentary of MFENet, a National Computer Network", UCRL-52317, Lawrence Livermore Labs, Livermore, California, June 1977.\] \[Barry_Howard\]
113    pub const MFE_NSP: IpNumber = Self(31);
114    /// MERIT Internodal Protocol \[Hans_Werner_Braun\]
115    pub const MERIT_INP: IpNumber = Self(32);
116    /// Datagram Congestion Control Protocol \[[RFC4340](https://datatracker.ietf.org/doc/html/rfc4340)\]
117    pub const DCCP: IpNumber = Self(33);
118    /// Third Party Connect Protocol \[Stuart_A_Friedberg\]
119    pub const THIRD_PARTY_CONNECT_PROTOCOL: IpNumber = Self(34);
120    /// Inter-Domain Policy Routing Protocol \[Martha_Steenstrup\]
121    pub const IDPR: IpNumber = Self(35);
122    /// XTP \[Greg_Chesson\]
123    pub const XTP: IpNumber = Self(36);
124    /// Datagram Delivery Protocol \[Wesley_Craig\]
125    pub const DDP: IpNumber = Self(37);
126    /// IDPR Control Message Transport Proto \[Martha_Steenstrup\]
127    pub const IDPR_CMTP: IpNumber = Self(38);
128    /// TP++ Transport Protocol \[Dirk_Fromhein\]
129    pub const TP_PLUS_PLUS: IpNumber = Self(39);
130    /// IL Transport Protocol \[Dave_Presotto\]
131    pub const IL: IpNumber = Self(40);
132    /// IPv6 encapsulation \[[RFC2473](https://datatracker.ietf.org/doc/html/rfc2473)\]
133    pub const IPV6: IpNumber = Self(41);
134    /// Source Demand Routing Protocol \[Deborah_Estrin\]
135    pub const SDRP: IpNumber = Self(42);
136    /// Routing Header for IPv6 \[Steve_Deering\]
137    pub const IPV6_ROUTE_HEADER: IpNumber = Self(43);
138    /// Fragment Header for IPv6 \[Steve_Deering\]
139    pub const IPV6_FRAGMENTATION_HEADER: IpNumber = Self(44);
140    /// Inter-Domain Routing Protocol \[Sue_Hares\]
141    pub const IDRP: IpNumber = Self(45);
142    /// Reservation Protocol \[[RFC2205](https://datatracker.ietf.org/doc/html/rfc2205)\]\[[RFC3209](https://datatracker.ietf.org/doc/html/rfc3209)\]\[Bob_Braden\]
143    pub const RSVP: IpNumber = Self(46);
144    /// Generic Routing Encapsulation \[[RFC2784](https://datatracker.ietf.org/doc/html/rfc2784)\]\[Tony_Li\]
145    pub const GRE: IpNumber = Self(47);
146    /// Dynamic Source Routing Protocol \[[RFC4728](https://datatracker.ietf.org/doc/html/rfc4728)\]
147    pub const DSR: IpNumber = Self(48);
148    /// BNA \[Gary Salamon\]
149    pub const BNA: IpNumber = Self(49);
150    /// Encapsulating Security Payload \[[RFC4303](https://datatracker.ietf.org/doc/html/rfc4303)\]
151    pub const ENCAPSULATING_SECURITY_PAYLOAD: IpNumber = Self(50);
152    /// Authentication Header \[[RFC4302](https://datatracker.ietf.org/doc/html/rfc4302)\]
153    pub const AUTHENTICATION_HEADER: IpNumber = Self(51);
154    /// Integrated Net Layer Security  TUBA \[K_Robert_Glenn\]
155    pub const INLSP: IpNumber = Self(52);
156    /// IP with Encryption (deprecated) \[John_Ioannidis\]
157    pub const SWIPE: IpNumber = Self(53);
158    /// NBMA Address Resolution Protocol \[[RFC1735](https://datatracker.ietf.org/doc/html/rfc1735)\]
159    pub const NARP: IpNumber = Self(54);
160    /// IP Mobility \[Charlie_Perkins\]
161    pub const MOBILE: IpNumber = Self(55);
162    /// Transport Layer Security Protocol using Kryptonet key management \[Christer_Oberg\]
163    pub const TLSP: IpNumber = Self(56);
164    /// SKIP \[Tom_Markson\]
165    pub const SKIP: IpNumber = Self(57);
166    /// ICMP for IPv6 \[[RFC8200](https://datatracker.ietf.org/doc/html/rfc8200)\]
167    pub const IPV6_ICMP: IpNumber = Self(58);
168    /// No Next Header for IPv6 \[[RFC8200](https://datatracker.ietf.org/doc/html/rfc8200)\]
169    pub const IPV6_NO_NEXT_HEADER: IpNumber = Self(59);
170    /// Destination Options for IPv6 \[[RFC8200](https://datatracker.ietf.org/doc/html/rfc8200)\]
171    pub const IPV6_DESTINATION_OPTIONS: IpNumber = Self(60);
172    /// any host internal protocol \[Internet_Assigned_Numbers_Authority\]
173    pub const ANY_HOST_INTERNAL_PROTOCOL: IpNumber = Self(61);
174    /// CFTP \[Forsdick, H., "CFTP", Network Message, Bolt Beranek and Newman, January 1982.\]\[Harry_Forsdick\]
175    pub const CFTP: IpNumber = Self(62);
176    /// any local network \[Internet_Assigned_Numbers_Authority\]
177    pub const ANY_LOCAL_NETWORK: IpNumber = Self(63);
178    /// SATNET and Backroom EXPAK \[Steven_Blumenthal\]
179    pub const SAT_EXPAK: IpNumber = Self(64);
180    /// Kryptolan \[Paul Liu\]
181    pub const KRYTOLAN: IpNumber = Self(65);
182    /// MIT Remote Virtual Disk Protocol \[Michael_Greenwald\]
183    pub const RVD: IpNumber = Self(66);
184    /// Internet Pluribus Packet Core \[Steven_Blumenthal\]
185    pub const IPPC: IpNumber = Self(67);
186    /// any distributed file system \[Internet_Assigned_Numbers_Authority\]
187    pub const ANY_DISTRIBUTED_FILE_SYSTEM: IpNumber = Self(68);
188    /// SATNET Monitoring \[Steven_Blumenthal\]
189    pub const SAT_MON: IpNumber = Self(69);
190    /// VISA Protocol \[Gene_Tsudik\]
191    pub const VISA: IpNumber = Self(70);
192    /// Internet Packet Core Utility \[Steven_Blumenthal\]
193    pub const IPCV: IpNumber = Self(71);
194    /// Computer Protocol Network Executive \[David Mittnacht\]
195    pub const CPNX: IpNumber = Self(72);
196    /// Computer Protocol Heart Beat \[David Mittnacht\]
197    pub const CPHB: IpNumber = Self(73);
198    /// Wang Span Network \[Victor Dafoulas\]
199    pub const WSN: IpNumber = Self(74);
200    /// Packet Video Protocol \[Steve_Casner\]
201    pub const PVP: IpNumber = Self(75);
202    /// Backroom SATNET Monitoring \[Steven_Blumenthal\]
203    pub const BR_SAT_MON: IpNumber = Self(76);
204    /// SUN ND PROTOCOL-Temporary \[William_Melohn\]
205    pub const SUN_ND: IpNumber = Self(77);
206    /// WIDEBAND Monitoring \[Steven_Blumenthal\]
207    pub const WB_MON: IpNumber = Self(78);
208    /// WIDEBAND EXPAK \[Steven_Blumenthal\]
209    pub const WB_EXPAK: IpNumber = Self(79);
210    /// ISO Internet Protocol \[Marshall_T_Rose\]
211    pub const ISO_IP: IpNumber = Self(80);
212    /// VMTP \[Dave_Cheriton\]
213    pub const VMTP: IpNumber = Self(81);
214    /// SECURE-VMTP \[Dave_Cheriton\]
215    pub const SECURE_VMTP: IpNumber = Self(82);
216    /// VINES \[Brian Horn\]
217    pub const VINES: IpNumber = Self(83);
218    /// Transaction Transport Protocol or Internet Protocol Traffic Manager \[Jim_Stevens\]
219    pub const TTP_OR_IPTM: IpNumber = Self(84);
220    /// NSFNET-IGP \[Hans_Werner_Braun\]
221    pub const NSFNET_IGP: IpNumber = Self(85);
222    /// Dissimilar Gateway Protocol \[M/A-COM Government Systems, "Dissimilar Gateway Protocol Specification, Draft Version", Contract no. CS901145, November 16, 1987.\]\[Mike_Little\]
223    pub const DGP: IpNumber = Self(86);
224    /// TCF \[Guillermo_A_Loyola\]
225    pub const TCF: IpNumber = Self(87);
226    /// EIGRP \[[RFC7868](https://datatracker.ietf.org/doc/html/rfc7868)\]
227    pub const EIGRP: IpNumber = Self(88);
228    /// OSPFIGP \[[RFC1583](https://datatracker.ietf.org/doc/html/rfc1583)\]\[[RFC2328](https://datatracker.ietf.org/doc/html/rfc2328)\]\[[RFC5340](https://datatracker.ietf.org/doc/html/rfc5340)\]\[John_Moy\]
229    pub const OSPFIGP: IpNumber = Self(89);
230    /// Sprite RPC Protocol \[Welch, B., "The Sprite Remote Procedure Call System", Technical Report, UCB/Computer Science Dept., 86/302, University of California at Berkeley, June 1986.\]\[Bruce Willins\]
231    pub const SPRITE_RPC: IpNumber = Self(90);
232    /// Locus Address Resolution Protocol \[Brian Horn\]
233    pub const LARP: IpNumber = Self(91);
234    /// Multicast Transport Protocol \[Susie_Armstrong\]
235    pub const MTP: IpNumber = Self(92);
236    /// AX.25 Frames \[Brian_Kantor\]
237    pub const AX25: IpNumber = Self(93);
238    /// IP-within-IP Encapsulation Protocol \[John_Ioannidis\]
239    pub const IPIP: IpNumber = Self(94);
240    /// Mobile Internetworking Control Pro. (deprecated) \[John_Ioannidis\]
241    pub const MICP: IpNumber = Self(95);
242    /// Semaphore Communications Sec. Pro. \[Howard_Hart\]
243    pub const SCC_SP: IpNumber = Self(96);
244    /// Ethernet-within-IP Encapsulation \[[RFC3378](https://datatracker.ietf.org/doc/html/rfc3378)\]
245    pub const ETHER_IP: IpNumber = Self(97);
246    /// Encapsulation Header \[[RFC1241](https://datatracker.ietf.org/doc/html/rfc1241)\]\[Robert_Woodburn\]
247    pub const ENCAP: IpNumber = Self(98);
248    /// GMTP \[\[RXB5\]\]
249    pub const GMTP: IpNumber = Self(100);
250    /// Ipsilon Flow Management Protocol \[Bob_Hinden\]\[November 1995, 1997.\]
251    pub const IFMP: IpNumber = Self(101);
252    /// PNNI over IP \[Ross_Callon\]
253    pub const PNNI: IpNumber = Self(102);
254    /// Protocol Independent Multicast \[[RFC7761](https://datatracker.ietf.org/doc/html/rfc7761)\]\[Dino_Farinacci\]
255    pub const PIM: IpNumber = Self(103);
256    /// ARIS \[Nancy_Feldman\]
257    pub const ARIS: IpNumber = Self(104);
258    /// SCPS \[Robert_Durst\]
259    pub const SCPS: IpNumber = Self(105);
260    /// QNX \[Michael_Hunter\]
261    pub const QNX: IpNumber = Self(106);
262    /// Active Networks \[Bob_Braden\]
263    pub const ACTIVE_NETWORKS: IpNumber = Self(107);
264    /// IP Payload Compression Protocol \[[RFC2393](https://datatracker.ietf.org/doc/html/rfc2393)\]
265    pub const IP_COMP: IpNumber = Self(108);
266    /// Sitara Networks Protocol \[Manickam_R_Sridhar\]
267    pub const SITRA_NETWORKS_PROTOCOL: IpNumber = Self(109);
268    /// Compaq Peer Protocol \[Victor_Volpe\]
269    pub const COMPAQ_PEER: IpNumber = Self(110);
270    /// IPX in IP \[CJ_Lee\]
271    pub const IPX_IN_IP: IpNumber = Self(111);
272    /// Virtual Router Redundancy Protocol \[[RFC5798](https://datatracker.ietf.org/doc/html/rfc5798)\]
273    pub const VRRP: IpNumber = Self(112);
274    /// PGM Reliable Transport Protocol \[Tony_Speakman\]
275    pub const PGM: IpNumber = Self(113);
276    /// any 0-hop protocol \[Internet_Assigned_Numbers_Authority\]
277    pub const ANY_ZERO_HOP_PROTOCOL: IpNumber = Self(114);
278    /// Layer Two Tunneling Protocol \[[RFC3931](https://datatracker.ietf.org/doc/html/rfc3931)\]\[Bernard_Aboba\]
279    pub const LAYER2_TUNNELING_PROTOCOL: IpNumber = Self(115);
280    /// D-II Data Exchange (DDX) \[John_Worley\]
281    pub const DDX: IpNumber = Self(116);
282    /// Interactive Agent Transfer Protocol \[John_Murphy\]
283    pub const IATP: IpNumber = Self(117);
284    /// Schedule Transfer Protocol \[Jean_Michel_Pittet\]
285    pub const STP: IpNumber = Self(118);
286    /// SpectraLink Radio Protocol \[Mark_Hamilton\]
287    pub const SRP: IpNumber = Self(119);
288    /// UTI \[Peter_Lothberg\]
289    pub const UTI: IpNumber = Self(120);
290    /// Simple Message Protocol \[Leif_Ekblad\]
291    pub const SIMPLE_MESSAGE_PROTOCOL: IpNumber = Self(121);
292    /// Simple Multicast Protocol (deprecated) \[Jon_Crowcroft\]\[draft-perlman-simple-multicast\]
293    pub const SM: IpNumber = Self(122);
294    /// Performance Transparency Protocol \[Michael_Welzl\]
295    pub const PTP: IpNumber = Self(123);
296    /// ISIS over IPv4 \[Tony_Przygienda\]
297    pub const ISIS_OVER_IPV4: IpNumber = Self(124);
298    /// FIRE \[Criag_Partridge\]
299    pub const FIRE: IpNumber = Self(125);
300    /// Combat Radio Transport Protocol \[Robert_Sautter\]
301    pub const CRTP: IpNumber = Self(126);
302    /// Combat Radio User Datagram \[Robert_Sautter\]
303    pub const CRUDP: IpNumber = Self(127);
304    /// SSCOPMCE \[Kurt_Waber\]
305    pub const SSCOPMCE: IpNumber = Self(128);
306    /// IPLT \[\[Hollbach\]\]
307    pub const IPLT: IpNumber = Self(129);
308    /// Secure Packet Shield \[Bill_McIntosh\]
309    pub const SPS: IpNumber = Self(130);
310    /// Private IP Encapsulation within IP \[Bernhard_Petri\]
311    pub const PIPE: IpNumber = Self(131);
312    /// Stream Control Transmission Protocol \[Randall_R_Stewart\]
313    pub const SCTP: IpNumber = Self(132);
314    /// Fibre Channel \[Murali_Rajagopal\]\[[RFC6172](https://datatracker.ietf.org/doc/html/rfc6172)\]
315    pub const FC: IpNumber = Self(133);
316    /// RSVP-E2E-IGNORE \[[RFC3175](https://datatracker.ietf.org/doc/html/rfc3175)\]
317    pub const RSVP_E2E_IGNORE: IpNumber = Self(134);
318    /// MobilityHeader \[[RFC6275](https://datatracker.ietf.org/doc/html/rfc6275)\]
319    pub const MOBILITY_HEADER: IpNumber = Self(135);
320    /// UDPLite \[[RFC3828](https://datatracker.ietf.org/doc/html/rfc3828)\]
321    pub const UDP_LITE: IpNumber = Self(136);
322    /// \[[RFC4023](https://datatracker.ietf.org/doc/html/rfc4023)\]
323    pub const MPLS_IN_IP: IpNumber = Self(137);
324    /// MANET Protocols \[[RFC5498](https://datatracker.ietf.org/doc/html/rfc5498)\]
325    pub const MANET: IpNumber = Self(138);
326    /// Host Identity Protocol \[[RFC7401](https://datatracker.ietf.org/doc/html/rfc7401)\]
327    pub const HIP: IpNumber = Self(139);
328    /// Shim6 Protocol \[[RFC5533](https://datatracker.ietf.org/doc/html/rfc5533)\]
329    pub const SHIM6: IpNumber = Self(140);
330    /// Wrapped Encapsulating Security Payload \[[RFC5840](https://datatracker.ietf.org/doc/html/rfc5840)\]
331    pub const WESP: IpNumber = Self(141);
332    /// Robust Header Compression \[[RFC5858](https://datatracker.ietf.org/doc/html/rfc5858)\]
333    pub const ROHC: IpNumber = Self(142);
334    /// Use for experimentation and testing
335    pub const EXPERIMENTAL_AND_TESTING_0: IpNumber = Self(253);
336    /// Use for experimentation and testing
337    pub const EXPERIMENTAL_AND_TESTING_1: IpNumber = Self(254);
338}
339
340impl IpNumber {
341    /// Returns true if the given number is the internet number of an IPV6 extension header.
342    pub fn is_ipv6_ext_header_value(self) -> bool {
343        use crate::ip_number::*;
344        matches!(
345            self,
346            IPV6_HOP_BY_HOP
347                | IPV6_ROUTE
348                | IPV6_FRAG
349                | ENCAP_SEC
350                | AUTH
351                | IPV6_DEST_OPTIONS
352                | MOBILITY
353                | HIP
354                | SHIM6
355                | EXP0
356                | EXP1
357        )
358    }
359
360    /// Returns the "keyword" string if known. Usually this is the abbreviation of the protocol.
361    ///
362    /// # Example
363    ///
364    /// ```
365    /// use etherparse::IpNumber;
366    ///
367    /// assert_eq!(IpNumber::UDP.keyword_str(), Some("UDP"));
368    ///
369    /// // Unassigned values return None
370    /// assert_eq!(IpNumber(145).keyword_str(), None);
371    /// ```
372    ///
373    /// # Data Source
374    ///
375    /// The strings were copied from <https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml>
376    /// on 2023-04-11.
377    pub fn keyword_str(self) -> Option<&'static str> {
378        // auto generated from CSV
379        // https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
380        // on 2023-04-11.
381        match self.0 {
382            0 => Some("HOPOPT"),
383            1 => Some("ICMP"),
384            2 => Some("IGMP"),
385            3 => Some("GGP"),
386            4 => Some("IPv4"),
387            5 => Some("ST"),
388            6 => Some("TCP"),
389            7 => Some("CBT"),
390            8 => Some("EGP"),
391            9 => Some("IGP"),
392            10 => Some("BBN-RCC-MON"),
393            11 => Some("NVP-II"),
394            12 => Some("PUP"),
395            13 => Some("ARGUS (deprecated)"),
396            14 => Some("EMCON"),
397            15 => Some("XNET"),
398            16 => Some("CHAOS"),
399            17 => Some("UDP"),
400            18 => Some("MUX"),
401            19 => Some("DCN-MEAS"),
402            20 => Some("HMP"),
403            21 => Some("PRM"),
404            22 => Some("XNS-IDP"),
405            23 => Some("TRUNK-1"),
406            24 => Some("TRUNK-2"),
407            25 => Some("LEAF-1"),
408            26 => Some("LEAF-2"),
409            27 => Some("RDP"),
410            28 => Some("IRTP"),
411            29 => Some("ISO-TP4"),
412            30 => Some("NETBLT"),
413            31 => Some("MFE-NSP"),
414            32 => Some("MERIT-INP"),
415            33 => Some("DCCP"),
416            34 => Some("3PC"),
417            35 => Some("IDPR"),
418            36 => Some("XTP"),
419            37 => Some("DDP"),
420            38 => Some("IDPR-CMTP"),
421            39 => Some("TP++"),
422            40 => Some("IL"),
423            41 => Some("IPv6"),
424            42 => Some("SDRP"),
425            43 => Some("IPv6-Route"),
426            44 => Some("IPv6-Frag"),
427            45 => Some("IDRP"),
428            46 => Some("RSVP"),
429            47 => Some("GRE"),
430            48 => Some("DSR"),
431            49 => Some("BNA"),
432            50 => Some("ESP"),
433            51 => Some("AH"),
434            52 => Some("I-NLSP"),
435            53 => Some("SWIPE (deprecated)"),
436            54 => Some("NARP"),
437            55 => Some("MOBILE"),
438            56 => Some("TLSP"),
439            57 => Some("SKIP"),
440            58 => Some("IPv6-ICMP"),
441            59 => Some("IPv6-NoNxt"),
442            60 => Some("IPv6-Opts"),
443            61 => None,
444            62 => Some("CFTP"),
445            63 => None,
446            64 => Some("SAT-EXPAK"),
447            65 => Some("KRYPTOLAN"),
448            66 => Some("RVD"),
449            67 => Some("IPPC"),
450            68 => None,
451            69 => Some("SAT-MON"),
452            70 => Some("VISA"),
453            71 => Some("IPCV"),
454            72 => Some("CPNX"),
455            73 => Some("CPHB"),
456            74 => Some("WSN"),
457            75 => Some("PVP"),
458            76 => Some("BR-SAT-MON"),
459            77 => Some("SUN-ND"),
460            78 => Some("WB-MON"),
461            79 => Some("WB-EXPAK"),
462            80 => Some("ISO-IP"),
463            81 => Some("VMTP"),
464            82 => Some("SECURE-VMTP"),
465            83 => Some("VINES"),
466            84 => Some("IPTM"),
467            85 => Some("NSFNET-IGP"),
468            86 => Some("DGP"),
469            87 => Some("TCF"),
470            88 => Some("EIGRP"),
471            89 => Some("OSPFIGP"),
472            90 => Some("Sprite-RPC"),
473            91 => Some("LARP"),
474            92 => Some("MTP"),
475            93 => Some("AX.25"),
476            94 => Some("IPIP"),
477            95 => Some("MICP (deprecated)"),
478            96 => Some("SCC-SP"),
479            97 => Some("ETHERIP"),
480            98 => Some("ENCAP"),
481            99 => None,
482            100 => Some("GMTP"),
483            101 => Some("IFMP"),
484            102 => Some("PNNI"),
485            103 => Some("PIM"),
486            104 => Some("ARIS"),
487            105 => Some("SCPS"),
488            106 => Some("QNX"),
489            107 => Some("A/N"),
490            108 => Some("IPComp"),
491            109 => Some("SNP"),
492            110 => Some("Compaq-Peer"),
493            111 => Some("IPX-in-IP"),
494            112 => Some("VRRP"),
495            113 => Some("PGM"),
496            114 => None,
497            115 => Some("L2TP"),
498            116 => Some("DDX"),
499            117 => Some("IATP"),
500            118 => Some("STP"),
501            119 => Some("SRP"),
502            120 => Some("UTI"),
503            121 => Some("SMP"),
504            122 => Some("SM (deprecated)"),
505            123 => Some("PTP"),
506            124 => Some("ISIS over IPv4"),
507            125 => Some("FIRE"),
508            126 => Some("CRTP"),
509            127 => Some("CRUDP"),
510            128 => Some("SSCOPMCE"),
511            129 => Some("IPLT"),
512            130 => Some("SPS"),
513            131 => Some("PIPE"),
514            132 => Some("SCTP"),
515            133 => Some("FC"),
516            134 => Some("RSVP-E2E-IGNORE"),
517            135 => Some("Mobility Header"),
518            136 => Some("UDPLite"),
519            137 => Some("MPLS-in-IP"),
520            138 => Some("manet"),
521            139 => Some("HIP"),
522            140 => Some("Shim6"),
523            141 => Some("WESP"),
524            142 => Some("ROHC"),
525            143 => Some("Ethernet"),
526            144 => Some("AGGFRAG"),
527            145..=252 => None,
528            253 => None,
529            254 => None,
530            255 => Some("Reserved"),
531        }
532    }
533
534    /// Returns the "protocol" string if known. Usually this the non abbreviated name of the protocol.
535    ///
536    /// # Example
537    ///
538    /// ```
539    /// use etherparse::IpNumber;
540    ///
541    /// assert_eq!(IpNumber::UDP.protocol_str(), Some("User Datagram"));
542    ///
543    /// // Unassigned values return None
544    /// assert_eq!(IpNumber(145).protocol_str(), None);
545    /// ```
546    ///
547    /// # Data Source
548    ///
549    /// The string was copied from <https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml>
550    /// on 2023-04-11.
551    pub fn protocol_str(self) -> Option<&'static str> {
552        // auto generated from CSV
553        // https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
554        // on 2023-04-11.
555        match self.0 {
556            0 => Some("IPv6 Hop-by-Hop Option"),
557            1 => Some("Internet Control Message"),
558            2 => Some("Internet Group Management"),
559            3 => Some("Gateway-to-Gateway"),
560            4 => Some("IPv4 encapsulation"),
561            5 => Some("Stream"),
562            6 => Some("Transmission Control"),
563            7 => Some("CBT"),
564            8 => Some("Exterior Gateway Protocol"),
565            9 => Some("any private interior gateway (used by Cisco for their IGRP)"),
566            10 => Some("BBN RCC Monitoring"),
567            11 => Some("Network Voice Protocol"),
568            12 => Some("PUP"),
569            13 => Some("ARGUS"),
570            14 => Some("EMCON"),
571            15 => Some("Cross Net Debugger"),
572            16 => Some("Chaos"),
573            17 => Some("User Datagram"),
574            18 => Some("Multiplexing"),
575            19 => Some("DCN Measurement Subsystems"),
576            20 => Some("Host Monitoring"),
577            21 => Some("Packet Radio Measurement"),
578            22 => Some("XEROX NS IDP"),
579            23 => Some("Trunk-1"),
580            24 => Some("Trunk-2"),
581            25 => Some("Leaf-1"),
582            26 => Some("Leaf-2"),
583            27 => Some("Reliable Data Protocol"),
584            28 => Some("Internet Reliable Transaction"),
585            29 => Some("ISO Transport Protocol Class 4"),
586            30 => Some("Bulk Data Transfer Protocol"),
587            31 => Some("MFE Network Services Protocol"),
588            32 => Some("MERIT Internodal Protocol"),
589            33 => Some("Datagram Congestion Control Protocol"),
590            34 => Some("Third Party Connect Protocol"),
591            35 => Some("Inter-Domain Policy Routing Protocol"),
592            36 => Some("XTP"),
593            37 => Some("Datagram Delivery Protocol"),
594            38 => Some("IDPR Control Message Transport Proto"),
595            39 => Some("TP++ Transport Protocol"),
596            40 => Some("IL Transport Protocol"),
597            41 => Some("IPv6 encapsulation"),
598            42 => Some("Source Demand Routing Protocol"),
599            43 => Some("Routing Header for IPv6"),
600            44 => Some("Fragment Header for IPv6"),
601            45 => Some("Inter-Domain Routing Protocol"),
602            46 => Some("Reservation Protocol"),
603            47 => Some("Generic Routing Encapsulation"),
604            48 => Some("Dynamic Source Routing Protocol"),
605            49 => Some("BNA"),
606            50 => Some("Encap Security Payload"),
607            51 => Some("Authentication Header"),
608            52 => Some("Integrated Net Layer Security  TUBA"),
609            53 => Some("IP with Encryption"),
610            54 => Some("NBMA Address Resolution Protocol"),
611            55 => Some("IP Mobility"),
612            56 => Some("Transport Layer Security Protocol using Kryptonet key management"),
613            57 => Some("SKIP"),
614            58 => Some("ICMP for IPv6"),
615            59 => Some("No Next Header for IPv6"),
616            60 => Some("Destination Options for IPv6"),
617            61 => Some("any host internal protocol"),
618            62 => Some("CFTP"),
619            63 => Some("any local network"),
620            64 => Some("SATNET and Backroom EXPAK"),
621            65 => Some("Kryptolan"),
622            66 => Some("MIT Remote Virtual Disk Protocol"),
623            67 => Some("Internet Pluribus Packet Core"),
624            68 => Some("any distributed file system"),
625            69 => Some("SATNET Monitoring"),
626            70 => Some("VISA Protocol"),
627            71 => Some("Internet Packet Core Utility"),
628            72 => Some("Computer Protocol Network Executive"),
629            73 => Some("Computer Protocol Heart Beat"),
630            74 => Some("Wang Span Network"),
631            75 => Some("Packet Video Protocol"),
632            76 => Some("Backroom SATNET Monitoring"),
633            77 => Some("SUN ND PROTOCOL-Temporary"),
634            78 => Some("WIDEBAND Monitoring"),
635            79 => Some("WIDEBAND EXPAK"),
636            80 => Some("ISO Internet Protocol"),
637            81 => Some("VMTP"),
638            82 => Some("SECURE-VMTP"),
639            83 => Some("VINES"),
640            84 => Some("Internet Protocol Traffic Manager"),
641            85 => Some("NSFNET-IGP"),
642            86 => Some("Dissimilar Gateway Protocol"),
643            87 => Some("TCF"),
644            88 => Some("EIGRP"),
645            89 => Some("OSPFIGP"),
646            90 => Some("Sprite RPC Protocol"),
647            91 => Some("Locus Address Resolution Protocol"),
648            92 => Some("Multicast Transport Protocol"),
649            93 => Some("AX.25 Frames"),
650            94 => Some("IP-within-IP Encapsulation Protocol"),
651            95 => Some("Mobile Internetworking Control Pro."),
652            96 => Some("Semaphore Communications Sec. Pro."),
653            97 => Some("Ethernet-within-IP Encapsulation"),
654            98 => Some("Encapsulation Header"),
655            99 => Some("any private encryption scheme"),
656            100 => Some("GMTP"),
657            101 => Some("Ipsilon Flow Management Protocol"),
658            102 => Some("PNNI over IP"),
659            103 => Some("Protocol Independent Multicast"),
660            104 => Some("ARIS"),
661            105 => Some("SCPS"),
662            106 => Some("QNX"),
663            107 => Some("Active Networks"),
664            108 => Some("IP Payload Compression Protocol"),
665            109 => Some("Sitara Networks Protocol"),
666            110 => Some("Compaq Peer Protocol"),
667            111 => Some("IPX in IP"),
668            112 => Some("Virtual Router Redundancy Protocol"),
669            113 => Some("PGM Reliable Transport Protocol"),
670            114 => Some("any 0-hop protocol"),
671            115 => Some("Layer Two Tunneling Protocol"),
672            116 => Some("D-II Data Exchange (DDX)"),
673            117 => Some("Interactive Agent Transfer Protocol"),
674            118 => Some("Schedule Transfer Protocol"),
675            119 => Some("SpectraLink Radio Protocol"),
676            120 => Some("UTI"),
677            121 => Some("Simple Message Protocol"),
678            122 => Some("Simple Multicast Protocol"),
679            123 => Some("Performance Transparency Protocol"),
680            124 => None,
681            125 => None,
682            126 => Some("Combat Radio Transport Protocol"),
683            127 => Some("Combat Radio User Datagram"),
684            128 => None,
685            129 => None,
686            130 => Some("Secure Packet Shield"),
687            131 => Some("Private IP Encapsulation within IP"),
688            132 => Some("Stream Control Transmission Protocol"),
689            133 => Some("Fibre Channel"),
690            134 => None,
691            135 => None,
692            136 => None,
693            137 => None,
694            138 => Some("MANET Protocols"),
695            139 => Some("Host Identity Protocol"),
696            140 => Some("Shim6 Protocol"),
697            141 => Some("Wrapped Encapsulating Security Payload"),
698            142 => Some("Robust Header Compression"),
699            143 => Some("Ethernet"),
700            144 => Some("AGGFRAG encapsulation payload for ESP"),
701            145..=252 => None,
702            253 => Some("Use for experimentation and testing"),
703            254 => Some("Use for experimentation and testing"),
704            255 => None,
705        }
706    }
707}
708
709impl Default for IpNumber {
710    #[inline]
711    fn default() -> Self {
712        // 255 chosen as it is not used by any
713        // protocol and is reserved.
714        Self(255)
715    }
716}
717
718impl From<u8> for IpNumber {
719    #[inline]
720    fn from(val: u8) -> Self {
721        Self(val)
722    }
723}
724
725impl From<IpNumber> for u8 {
726    #[inline]
727    fn from(val: IpNumber) -> Self {
728        val.0
729    }
730}
731
732impl core::fmt::Debug for IpNumber {
733    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
734        if let Some(keyword) = self.keyword_str() {
735            if let Some(protocol) = self.protocol_str() {
736                write!(f, "{} ({} - {})", self.0, keyword, protocol)
737            } else {
738                write!(f, "{} ({})", self.0, keyword)
739            }
740        } else if let Some(protocol) = self.protocol_str() {
741            write!(f, "{} ({})", self.0, protocol)
742        } else {
743            write!(f, "{}", self.0)
744        }
745    }
746}
747
748/// Constants for the ip protocol numbers for easy importing (e.g. `use ip_number::*;`).
749///
750/// The constants only exist for convenience so you can import them
751/// (`use ip_number::*`) without a need to write `IpNumber::` in front
752/// of every constant.
753///
754/// You can access the underlying `u8` value by using `.0` and any `u8`
755/// can be converted to an `IpNumber`:
756///
757/// ```
758/// use etherparse::{ip_number::TCP, IpNumber};
759///
760/// assert_eq!(TCP.0, 6);
761/// assert_eq!(TCP, IpNumber(6));
762/// let num: IpNumber = 6.into();
763/// assert_eq!(TCP, num);
764/// ```
765///
766/// The list original values were copied from
767/// <https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml>
768pub mod ip_number {
769    use crate::IpNumber;
770
771    /// IPv6 Hop-by-Hop Option \[[RFC8200](https://datatracker.ietf.org/doc/html/rfc8200)\]
772    pub const IPV6_HOP_BY_HOP: IpNumber = IpNumber::IPV6_HEADER_HOP_BY_HOP; // 0
773    /// IPv6 Hop-by-Hop Option \[[RFC8200](https://datatracker.ietf.org/doc/html/rfc8200)\]
774    pub const IPV6_HEADER_HOP_BY_HOP: IpNumber = IpNumber::IPV6_HEADER_HOP_BY_HOP; // 0
775    /// Internet Control Message \[[RFC792](https://datatracker.ietf.org/doc/html/rfc792)\]
776    pub const ICMP: IpNumber = IpNumber::ICMP; // 1
777    /// Internet Group Management \[[RFC1112](https://datatracker.ietf.org/doc/html/rfc1112)\]
778    pub const IGMP: IpNumber = IpNumber::IGMP; // 2
779    /// Gateway-to-Gateway \[[RFC823](https://datatracker.ietf.org/doc/html/rfc823)\]
780    pub const GGP: IpNumber = IpNumber::GGP; // 3
781    /// IPv4 encapsulation \[[RFC2003](https://datatracker.ietf.org/doc/html/rfc2003)\]
782    pub const IPV4: IpNumber = IpNumber::IPV4; // 4
783    /// Stream \[[RFC1190](https://datatracker.ietf.org/doc/html/rfc1190)\] \[[RFC1819](https://datatracker.ietf.org/doc/html/rfc1819)\]
784    pub const STREAM: IpNumber = IpNumber::STREAM; // 5
785    /// Transmission Control \[[RFC793](https://datatracker.ietf.org/doc/html/rfc793)\]
786    pub const TCP: IpNumber = IpNumber::TCP; // 6
787    /// CBT \[Tony_Ballardie\]
788    pub const CBT: IpNumber = IpNumber::CBT; // 7
789    /// Exterior Gateway Protocol \[[RFC888](https://datatracker.ietf.org/doc/html/rfc888)\] \[David_Mills\]
790    pub const EGP: IpNumber = IpNumber::EGP; // 8
791    /// any private interior gateway (used by Cisco for their IGRP) \[Internet_Assigned_Numbers_Authority\]
792    pub const IGP: IpNumber = IpNumber::IGP; // 9
793    /// BBN RCC Monitoring \[Steve_Chipman\]
794    pub const BBN_RCC_MON: IpNumber = IpNumber::BBN_RCC_MON; // 10
795    /// Network Voice Protocol \[[RFC741](https://datatracker.ietf.org/doc/html/rfc741)\]\[Steve_Casner\]
796    pub const NVP_II: IpNumber = IpNumber::NVP_II; // 11
797    /// PUP
798    pub const PUP: IpNumber = IpNumber::PUP; // 12
799    /// ARGUS (deprecated) \[Robert_W_Scheifler\]
800    pub const ARGUS: IpNumber = IpNumber::ARGUS; // 13
801    /// EMCON \[mystery contact\]
802    pub const EMCON: IpNumber = IpNumber::EMCON; // 14
803    /// Cross Net Debugger \[Haverty, J., "XNET Formats for Internet Protocol Version 4", IEN 158, October 1980.\]\[Jack_Haverty\]
804    pub const XNET: IpNumber = IpNumber::XNET; // 15
805    /// Chaos \[J_Noel_Chiappa\]
806    pub const CHAOS: IpNumber = IpNumber::CHAOS; // 16
807    /// User Datagram \[[RFC768](https://datatracker.ietf.org/doc/html/rfc768)\] \[Jon_Postel\]
808    pub const UDP: IpNumber = IpNumber::UDP; // 17
809    /// Multiplexing \[Cohen, D. and J. Postel, "Multiplexing Protocol", IEN 90, USC/Information Sciences Institute, May 1979.\]\[Jon_Postel\]
810    pub const MUX: IpNumber = IpNumber::MUX; // 18
811    /// DCN Measurement Subsystems \[David_Mills\]
812    pub const DCN_MEAS: IpNumber = IpNumber::DCN_MEAS; // 19
813    /// Host Monitoring \[[RFC869](https://datatracker.ietf.org/doc/html/rfc869)\]\[Bob_Hinden\]
814    pub const HMP: IpNumber = IpNumber::HMP; // 20
815    /// Packet Radio Measurement \[Zaw_Sing_Su\]
816    pub const PRM: IpNumber = IpNumber::PRM; // 21
817    /// XEROX NS IDP
818    pub const XNS_IDP: IpNumber = IpNumber::XNS_IDP; // 22
819    /// Trunk-1 \[Barry_Boehm\]
820    pub const TRUNK1: IpNumber = IpNumber::TRUNK1; // 23
821    /// Trunk-2 \[Barry_Boehm\]
822    pub const TRUNK2: IpNumber = IpNumber::TRUNK2; // 24
823    /// Leaf-1 \[Barry_Boehm\]
824    pub const LEAF1: IpNumber = IpNumber::LEAF1; // 25
825    /// Leaf-2 \[Barry_Boehm\]
826    pub const LEAF2: IpNumber = IpNumber::LEAF2; // 26
827    /// Reliable Data Protocol \[[RFC908](https://datatracker.ietf.org/doc/html/rfc908)\] \[Bob_Hinden\]
828    pub const RDP: IpNumber = IpNumber::RDP; // 27
829    /// Internet Reliable Transaction \[[RFC938](https://datatracker.ietf.org/doc/html/rfc938)\] \[Trudy_Miller\]
830    pub const IRTP: IpNumber = IpNumber::IRTP; // 28
831    /// ISO Transport Protocol Class 4 \[[RFC905](https://datatracker.ietf.org/doc/html/rfc905)\] \[mystery contact\]
832    pub const ISO_TP4: IpNumber = IpNumber::ISO_TP4; // 29
833    /// Bulk Data Transfer Protocol \[[RFC969](https://datatracker.ietf.org/doc/html/rfc969)\] \[David_Clark\]
834    pub const NET_BLT: IpNumber = IpNumber::NET_BLT; // 30
835    /// MFE Network Services Protocol \[Shuttleworth, B., "A Documentary of MFENet, a National Computer Network", UCRL-52317, Lawrence Livermore Labs, Livermore, California, June 1977.\] \[Barry_Howard\]
836    pub const MFE_NSP: IpNumber = IpNumber::MFE_NSP; // 31
837    /// MERIT Internodal Protocol \[Hans_Werner_Braun\]
838    pub const MERIT_INP: IpNumber = IpNumber::MERIT_INP; // 32
839    /// Datagram Congestion Control Protocol \[[RFC4340](https://datatracker.ietf.org/doc/html/rfc4340)\]
840    pub const DCCP: IpNumber = IpNumber::DCCP; // 33
841    /// Third Party Connect Protocol \[Stuart_A_Friedberg\]
842    pub const THIRD_PARTY_CONNECT_PROTOCOL: IpNumber = IpNumber::THIRD_PARTY_CONNECT_PROTOCOL; // 34
843    /// Inter-Domain Policy Routing Protocol \[Martha_Steenstrup\]
844    pub const IDPR: IpNumber = IpNumber::IDPR; // 35
845    /// XTP \[Greg_Chesson\]
846    pub const XTP: IpNumber = IpNumber::XTP; // 36
847    /// Datagram Delivery Protocol \[Wesley_Craig\]
848    pub const DDP: IpNumber = IpNumber::DDP; // 37
849    /// IDPR Control Message Transport Proto \[Martha_Steenstrup\]
850    pub const IDPR_CMTP: IpNumber = IpNumber::IDPR_CMTP; // 38
851    /// TP++ Transport Protocol \[Dirk_Fromhein\]
852    pub const TP_PLUS_PLUS: IpNumber = IpNumber::TP_PLUS_PLUS; // 39
853    /// IL Transport Protocol \[Dave_Presotto\]
854    pub const IL: IpNumber = IpNumber::IL; // 40
855    /// IPv6 encapsulation \[[RFC2473](https://datatracker.ietf.org/doc/html/rfc2473)\]
856    pub const IPV6: IpNumber = IpNumber::IPV6; // 41
857    /// Source Demand Routing Protocol \[Deborah_Estrin\]
858    pub const SDRP: IpNumber = IpNumber::SDRP; // 42
859    /// Routing Header for IPv6 \[Steve_Deering\]
860    pub const IPV6_ROUTE_HEADER: IpNumber = IpNumber::IPV6_ROUTE_HEADER; // 43
861    /// Routing Header for IPv6 \[Steve_Deering\]
862    pub const IPV6_ROUTE: IpNumber = IpNumber::IPV6_ROUTE_HEADER; // 43
863    /// Fragment Header for IPv6 \[Steve_Deering\]
864    pub const IPV6_FRAGMENTATION_HEADER: IpNumber = IpNumber::IPV6_FRAGMENTATION_HEADER; // 44
865    /// Fragment Header for IPv6 \[Steve_Deering\]
866    pub const IPV6_FRAG: IpNumber = IpNumber::IPV6_FRAGMENTATION_HEADER; // 44
867    /// Inter-Domain Routing Protocol \[Sue_Hares\]
868    pub const IDRP: IpNumber = IpNumber::IDRP; // 45
869    /// Reservation Protocol \[[RFC2205](https://datatracker.ietf.org/doc/html/rfc2205)\]\[[RFC3209](https://datatracker.ietf.org/doc/html/rfc3209)\]\[Bob_Braden\]
870    pub const RSVP: IpNumber = IpNumber::RSVP; // 46
871    /// Generic Routing Encapsulation \[[RFC2784](https://datatracker.ietf.org/doc/html/rfc2784)\]\[Tony_Li\]
872    pub const GRE: IpNumber = IpNumber::GRE; // 47
873    /// Dynamic Source Routing Protocol \[[RFC4728](https://datatracker.ietf.org/doc/html/rfc4728)\]
874    pub const DSR: IpNumber = IpNumber::DSR; // 48
875    /// BNA \[Gary Salamon\]
876    pub const BNA: IpNumber = IpNumber::BNA; // 49
877    /// Encapsulating Security Payload \[[RFC4303](https://datatracker.ietf.org/doc/html/rfc4303)\]
878    pub const ENCAP_SEC: IpNumber = IpNumber::ENCAPSULATING_SECURITY_PAYLOAD; // 50
879    /// Encapsulating Security Payload \[[RFC4303](https://datatracker.ietf.org/doc/html/rfc4303)\]
880    pub const ENCAPSULATING_SECURITY_PAYLOAD: IpNumber = IpNumber::ENCAPSULATING_SECURITY_PAYLOAD; // 50
881    /// Authentication Header \[[RFC4302](https://datatracker.ietf.org/doc/html/rfc4302)\]
882    pub const AUTH: IpNumber = IpNumber::AUTHENTICATION_HEADER; // 51
883    /// Authentication Header \[[RFC4302](https://datatracker.ietf.org/doc/html/rfc4302)\]
884    pub const AUTHENTICATION_HEADER: IpNumber = IpNumber::AUTHENTICATION_HEADER; // 51
885    /// Integrated Net Layer Security  TUBA \[K_Robert_Glenn\]
886    pub const INLSP: IpNumber = IpNumber::INLSP; // 52
887    /// IP with Encryption (deprecated) \[John_Ioannidis\]
888    pub const SWIPE: IpNumber = IpNumber::SWIPE; // 53
889    /// NBMA Address Resolution Protocol \[[RFC1735](https://datatracker.ietf.org/doc/html/rfc1735)\]
890    pub const NARP: IpNumber = IpNumber::NARP; // 54
891    /// IP Mobility \[Charlie_Perkins\]
892    pub const MOBILE: IpNumber = IpNumber::MOBILE; // 55
893    /// Transport Layer Security Protocol using Kryptonet key management \[Christer_Oberg\]
894    pub const TLSP: IpNumber = IpNumber::TLSP; // 56
895    /// SKIP \[Tom_Markson\]
896    pub const SKIP: IpNumber = IpNumber::SKIP; // 57
897    /// IPv6 ICMP next-header type \[[RFC4443](https://datatracker.ietf.org/doc/html/rfc4443)\]
898    pub const IPV6_ICMP: IpNumber = IpNumber::IPV6_ICMP; // 58
899    /// No Next Header for IPv6 \[[RFC8200](https://datatracker.ietf.org/doc/html/rfc8200)\]
900    pub const IPV6_NO_NEXT_HEADER: IpNumber = IpNumber::IPV6_NO_NEXT_HEADER; // 59
901    /// Destination Options for IPv6 \[[RFC8200](https://datatracker.ietf.org/doc/html/rfc8200)\]
902    pub const IPV6_DEST_OPTIONS: IpNumber = IpNumber::IPV6_DESTINATION_OPTIONS; // 60
903    /// Destination Options for IPv6 \[[RFC8200](https://datatracker.ietf.org/doc/html/rfc8200)\]
904    pub const IPV6_DESTINATION_OPTIONS: IpNumber = IpNumber::IPV6_DESTINATION_OPTIONS; // 60
905    /// any host internal protocol \[Internet_Assigned_Numbers_Authority\]
906    pub const ANY_HOST_INTERNAL_PROTOCOL: IpNumber = IpNumber::ANY_HOST_INTERNAL_PROTOCOL; // 61
907    /// CFTP \[Forsdick, H., "CFTP", Network Message, Bolt Beranek and Newman, January 1982.\]\[Harry_Forsdick\]
908    pub const CFTP: IpNumber = IpNumber::CFTP; // 62
909    /// any local network \[Internet_Assigned_Numbers_Authority\]
910    pub const ANY_LOCAL_NETWORK: IpNumber = IpNumber::ANY_LOCAL_NETWORK; // 63
911    /// SATNET and Backroom EXPAK \[Steven_Blumenthal\]
912    pub const SAT_EXPAK: IpNumber = IpNumber::SAT_EXPAK; // 64
913    /// Kryptolan \[Paul Liu\]
914    pub const KRYTOLAN: IpNumber = IpNumber::KRYTOLAN; // 65
915    /// MIT Remote Virtual Disk Protocol \[Michael_Greenwald\]
916    pub const RVD: IpNumber = IpNumber::RVD; // 66
917    /// Internet Pluribus Packet Core \[Steven_Blumenthal\]
918    pub const IPPC: IpNumber = IpNumber::IPPC; // 67
919    /// any distributed file system \[Internet_Assigned_Numbers_Authority\]
920    pub const ANY_DISTRIBUTED_FILE_SYSTEM: IpNumber = IpNumber::ANY_DISTRIBUTED_FILE_SYSTEM; // 68
921    /// SATNET Monitoring \[Steven_Blumenthal\]
922    pub const SAT_MON: IpNumber = IpNumber::SAT_MON; // 69
923    /// VISA Protocol \[Gene_Tsudik\]
924    pub const VISA: IpNumber = IpNumber::VISA; // 70
925    /// Internet Packet Core Utility \[Steven_Blumenthal\]
926    pub const IPCV: IpNumber = IpNumber::IPCV; // 71
927    /// Computer Protocol Network Executive \[David Mittnacht\]
928    pub const CPNX: IpNumber = IpNumber::CPNX; // 72
929    /// Computer Protocol Heart Beat \[David Mittnacht\]
930    pub const CPHB: IpNumber = IpNumber::CPHB; // 73
931    /// Wang Span Network \[Victor Dafoulas\]
932    pub const WSN: IpNumber = IpNumber::WSN; // 74
933    /// Packet Video Protocol \[Steve_Casner\]
934    pub const PVP: IpNumber = IpNumber::PVP; // 75
935    /// Backroom SATNET Monitoring \[Steven_Blumenthal\]
936    pub const BR_SAT_MON: IpNumber = IpNumber::BR_SAT_MON; // 76
937    /// SUN ND PROTOCOL-Temporary \[William_Melohn\]
938    pub const SUN_ND: IpNumber = IpNumber::SUN_ND; // 77
939    /// WIDEBAND Monitoring \[Steven_Blumenthal\]
940    pub const WB_MON: IpNumber = IpNumber::WB_MON; // 78
941    /// WIDEBAND EXPAK \[Steven_Blumenthal\]
942    pub const WB_EXPAK: IpNumber = IpNumber::WB_EXPAK; // 79
943    /// ISO Internet Protocol \[Marshall_T_Rose\]
944    pub const ISO_IP: IpNumber = IpNumber::ISO_IP; // 80
945    /// VMTP \[Dave_Cheriton\]
946    pub const VMTP: IpNumber = IpNumber::VMTP; // 81
947    /// SECURE-VMTP \[Dave_Cheriton\]
948    pub const SECURE_VMTP: IpNumber = IpNumber::SECURE_VMTP; // 82
949    /// VINES \[Brian Horn\]
950    pub const VINES: IpNumber = IpNumber::VINES; // 83
951    /// Transaction Transport Protocol or Internet Protocol Traffic Manager \[Jim_Stevens\]
952    pub const TTP_OR_IPTM: IpNumber = IpNumber::TTP_OR_IPTM; // 84
953    /// NSFNET-IGP \[Hans_Werner_Braun\]
954    pub const NSFNET_IGP: IpNumber = IpNumber::NSFNET_IGP; // 85
955    /// Dissimilar Gateway Protocol \[M/A-COM Government Systems, "Dissimilar Gateway Protocol Specification, Draft Version", Contract no. CS901145, November 16, 1987.\]\[Mike_Little\]
956    pub const DGP: IpNumber = IpNumber::DGP; // 86
957    /// TCF \[Guillermo_A_Loyola\]
958    pub const TCF: IpNumber = IpNumber::TCF; // 87
959    /// EIGRP \[[RFC7868](https://datatracker.ietf.org/doc/html/rfc7868)\]
960    pub const EIGRP: IpNumber = IpNumber::EIGRP; // 88
961    /// OSPFIGP \[[RFC1583](https://datatracker.ietf.org/doc/html/rfc1583)\]\[[RFC2328](https://datatracker.ietf.org/doc/html/rfc2328)\]\[[RFC5340](https://datatracker.ietf.org/doc/html/rfc5340)\]\[John_Moy\]
962    pub const OSPFIGP: IpNumber = IpNumber::OSPFIGP; // 89
963    /// Sprite RPC Protocol \[Welch, B., "The Sprite Remote Procedure Call System", Technical Report, UCB/Computer Science Dept., 86/302, University of California at Berkeley, June 1986.\]\[Bruce Willins\]
964    pub const SPRITE_RPC: IpNumber = IpNumber::SPRITE_RPC; // 90
965    /// Locus Address Resolution Protocol \[Brian Horn\]
966    pub const LARP: IpNumber = IpNumber::LARP; // 91
967    /// Multicast Transport Protocol \[Susie_Armstrong\]
968    pub const MTP: IpNumber = IpNumber::MTP; // 92
969    /// AX.25 Frames \[Brian_Kantor\]
970    pub const AX25: IpNumber = IpNumber::AX25; // 93
971    /// IP-within-IP Encapsulation Protocol \[John_Ioannidis\]
972    pub const IPIP: IpNumber = IpNumber::IPIP; // 94
973    /// Mobile Internetworking Control Pro. (deprecated) \[John_Ioannidis\]
974    pub const MICP: IpNumber = IpNumber::MICP; // 95
975    /// Semaphore Communications Sec. Pro. \[Howard_Hart\]
976    pub const SCC_SP: IpNumber = IpNumber::SCC_SP; // 96
977    /// Ethernet-within-IP Encapsulation \[[RFC3378](https://datatracker.ietf.org/doc/html/rfc3378)\]
978    pub const ETHER_IP: IpNumber = IpNumber::ETHER_IP; // 97
979    /// Encapsulation Header \[[RFC1241](https://datatracker.ietf.org/doc/html/rfc1241)\]\[Robert_Woodburn\]
980    pub const ENCAP: IpNumber = IpNumber::ENCAP; // 98
981    /// GMTP \[\[RXB5\]\]
982    pub const GMTP: IpNumber = IpNumber::GMTP; // 100
983    /// Ipsilon Flow Management Protocol \[Bob_Hinden\]\[November 1995, 1997.\]
984    pub const IFMP: IpNumber = IpNumber::IFMP; // 101
985    /// PNNI over IP \[Ross_Callon\]
986    pub const PNNI: IpNumber = IpNumber::PNNI; // 102
987    /// Protocol Independent Multicast \[[RFC7761](https://datatracker.ietf.org/doc/html/rfc7761)\]\[Dino_Farinacci\]
988    pub const PIM: IpNumber = IpNumber::PIM; // 103
989    /// ARIS \[Nancy_Feldman\]
990    pub const ARIS: IpNumber = IpNumber::ARIS; // 104
991    /// SCPS \[Robert_Durst\]
992    pub const SCPS: IpNumber = IpNumber::SCPS; // 105
993    /// QNX \[Michael_Hunter\]
994    pub const QNX: IpNumber = IpNumber::QNX; // 106
995    /// Active Networks \[Bob_Braden\]
996    pub const ACTIVE_NETWORKS: IpNumber = IpNumber::ACTIVE_NETWORKS; // 107
997    /// IP Payload Compression Protocol \[[RFC2393](https://datatracker.ietf.org/doc/html/rfc2393)\]
998    pub const IP_COMP: IpNumber = IpNumber::IP_COMP; // 108
999    /// Sitara Networks Protocol \[Manickam_R_Sridhar\]
1000    pub const SITRA_NETWORKS_PROTOCOL: IpNumber = IpNumber::SITRA_NETWORKS_PROTOCOL; // 109
1001    /// Compaq Peer Protocol \[Victor_Volpe\]
1002    pub const COMPAQ_PEER: IpNumber = IpNumber::COMPAQ_PEER; // 110
1003    /// IPX in IP \[CJ_Lee\]
1004    pub const IPX_IN_IP: IpNumber = IpNumber::IPX_IN_IP; // 111
1005    /// Virtual Router Redundancy Protocol \[[RFC5798](https://datatracker.ietf.org/doc/html/rfc5798)\]
1006    pub const VRRP: IpNumber = IpNumber::VRRP; // 112
1007    /// PGM Reliable Transport Protocol \[Tony_Speakman\]
1008    pub const PGM: IpNumber = IpNumber::PGM; // 113
1009    /// any 0-hop protocol \[Internet_Assigned_Numbers_Authority\]
1010    pub const ANY_ZERO_HOP_PROTOCOL: IpNumber = IpNumber::ANY_ZERO_HOP_PROTOCOL; // 114
1011    /// Layer Two Tunneling Protocol \[[RFC3931](https://datatracker.ietf.org/doc/html/rfc3931)\]\[Bernard_Aboba\]
1012    pub const LAYER2_TUNNELING_PROTOCOL: IpNumber = IpNumber::LAYER2_TUNNELING_PROTOCOL; // 115
1013    /// D-II Data Exchange (DDX) \[John_Worley\]
1014    pub const DDX: IpNumber = IpNumber::DDX; // 116
1015    /// Interactive Agent Transfer Protocol \[John_Murphy\]
1016    pub const IATP: IpNumber = IpNumber::IATP; // 117
1017    /// Schedule Transfer Protocol \[Jean_Michel_Pittet\]
1018    pub const STP: IpNumber = IpNumber::STP; // 118
1019    /// SpectraLink Radio Protocol \[Mark_Hamilton\]
1020    pub const SRP: IpNumber = IpNumber::SRP; // 119
1021    /// UTI \[Peter_Lothberg\]
1022    pub const UTI: IpNumber = IpNumber::UTI; // 120
1023    /// Simple Message Protocol \[Leif_Ekblad\]
1024    pub const SIMPLE_MESSAGE_PROTOCOL: IpNumber = IpNumber::SIMPLE_MESSAGE_PROTOCOL; // 121
1025    /// Simple Multicast Protocol (deprecated) \[Jon_Crowcroft\]\[draft-perlman-simple-multicast\]
1026    pub const SM: IpNumber = IpNumber::SM; // 122
1027    /// Performance Transparency Protocol \[Michael_Welzl\]
1028    pub const PTP: IpNumber = IpNumber::PTP; // 123
1029    /// ISIS over IPv4 \[Tony_Przygienda\]
1030    pub const ISIS_OVER_IPV4: IpNumber = IpNumber::ISIS_OVER_IPV4; // 124
1031    /// FIRE \[Criag_Partridge\]
1032    pub const FIRE: IpNumber = IpNumber::FIRE; // 125
1033    /// Combat Radio Transport Protocol \[Robert_Sautter\]
1034    pub const CRTP: IpNumber = IpNumber::CRTP; // 126
1035    /// Combat Radio User Datagram \[Robert_Sautter\]
1036    pub const CRUDP: IpNumber = IpNumber::CRUDP; // 127
1037    /// SSCOPMCE \[Kurt_Waber\]
1038    pub const SSCOPMCE: IpNumber = IpNumber::SSCOPMCE; // 128
1039    /// IPLT \[\[Hollbach\]\]
1040    pub const IPLT: IpNumber = IpNumber::IPLT; // 129
1041    /// Secure Packet Shield \[Bill_McIntosh\]
1042    pub const SPS: IpNumber = IpNumber::SPS; // 130
1043    /// Private IP Encapsulation within IP \[Bernhard_Petri\]
1044    pub const PIPE: IpNumber = IpNumber::PIPE; // 131
1045    /// Stream Control Transmission Protocol \[Randall_R_Stewart\]
1046    pub const SCTP: IpNumber = IpNumber::SCTP; // 132
1047    /// Fibre Channel \[Murali_Rajagopal\]\[[RFC6172](https://datatracker.ietf.org/doc/html/rfc6172)\]
1048    pub const FC: IpNumber = IpNumber::FC; // 133
1049    /// RSVP-E2E-IGNORE \[[RFC3175](https://datatracker.ietf.org/doc/html/rfc3175)\]
1050    pub const RSVP_E2E_IGNORE: IpNumber = IpNumber::RSVP_E2E_IGNORE; // 134
1051    /// MobilityHeader \[[RFC6275](https://datatracker.ietf.org/doc/html/rfc6275)\]
1052    pub const MOBILITY: IpNumber = IpNumber::MOBILITY_HEADER; // 135
1053    /// MobilityHeader \[[RFC6275](https://datatracker.ietf.org/doc/html/rfc6275)\]
1054    pub const MOBILITY_HEADER: IpNumber = IpNumber::MOBILITY_HEADER; // 135
1055    /// UDPLite \[[RFC3828](https://datatracker.ietf.org/doc/html/rfc3828)\]
1056    pub const UDP_LITE: IpNumber = IpNumber::UDP_LITE; // 136
1057    /// \[[RFC4023](https://datatracker.ietf.org/doc/html/rfc4023)\]
1058    pub const MPLS_IN_IP: IpNumber = IpNumber::MPLS_IN_IP; // 137
1059    /// MANET Protocols \[[RFC5498](https://datatracker.ietf.org/doc/html/rfc5498)\]
1060    pub const MANET: IpNumber = IpNumber::MANET; // 138
1061    /// Host Identity Protocol \[[RFC7401](https://datatracker.ietf.org/doc/html/rfc7401)\]
1062    pub const HIP: IpNumber = IpNumber::HIP; // 139
1063    /// Shim6 Protocol \[[RFC5533](https://datatracker.ietf.org/doc/html/rfc5533)\]
1064    pub const SHIM6: IpNumber = IpNumber::SHIM6; // 140
1065    /// Wrapped Encapsulating Security Payload \[[RFC5840](https://datatracker.ietf.org/doc/html/rfc5840)\]
1066    pub const WESP: IpNumber = IpNumber::WESP; // 141
1067    /// Robust Header Compression \[[RFC5858](https://datatracker.ietf.org/doc/html/rfc5858)\]
1068    pub const ROHC: IpNumber = IpNumber::ROHC; // 142
1069    /// Use for experimentation and testing
1070    pub const EXP0: IpNumber = IpNumber::EXPERIMENTAL_AND_TESTING_0; // 253
1071    /// Use for experimentation and testing
1072    pub const EXPERIMENTAL_AND_TESTING_0: IpNumber = IpNumber::EXPERIMENTAL_AND_TESTING_0; // 253
1073    /// Use for experimentation and testing
1074    pub const EXP1: IpNumber = IpNumber::EXPERIMENTAL_AND_TESTING_1; // 254
1075    /// Use for experimentation and testing
1076    pub const EXPERIMENTAL_AND_TESTING_1: IpNumber = IpNumber::EXPERIMENTAL_AND_TESTING_1;
1077    // 254
1078}
1079
1080#[cfg(test)]
1081mod tests {
1082    use super::*;
1083    use core::{
1084        cmp::Ordering,
1085        hash::{Hash, Hasher},
1086    };
1087    use proptest::prelude::*;
1088    use std::{collections::hash_map::DefaultHasher, format};
1089
1090    #[test]
1091    fn is_ipv6_ext_header_value() {
1092        use crate::ip_number::*;
1093        use crate::IpNumber;
1094        let ext_ids = [
1095            IPV6_HOP_BY_HOP,
1096            IPV6_ROUTE,
1097            IPV6_FRAG,
1098            ENCAP_SEC,
1099            AUTH,
1100            IPV6_DEST_OPTIONS,
1101            MOBILITY,
1102            HIP,
1103            SHIM6,
1104            EXP0,
1105            EXP1,
1106        ];
1107
1108        for i in 0..std::u8::MAX {
1109            assert_eq!(
1110                ext_ids.contains(&IpNumber(i)),
1111                IpNumber(i).is_ipv6_ext_header_value()
1112            );
1113        }
1114    }
1115
1116    #[test]
1117    fn keyword_str() {
1118        // auto generated from CSV
1119        // https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
1120        // on 2023-04-11.
1121        assert_eq!(IpNumber(0).keyword_str(), Some("HOPOPT"));
1122        assert_eq!(IpNumber(1).keyword_str(), Some("ICMP"));
1123        assert_eq!(IpNumber(2).keyword_str(), Some("IGMP"));
1124        assert_eq!(IpNumber(3).keyword_str(), Some("GGP"));
1125        assert_eq!(IpNumber(4).keyword_str(), Some("IPv4"));
1126        assert_eq!(IpNumber(5).keyword_str(), Some("ST"));
1127        assert_eq!(IpNumber(6).keyword_str(), Some("TCP"));
1128        assert_eq!(IpNumber(7).keyword_str(), Some("CBT"));
1129        assert_eq!(IpNumber(8).keyword_str(), Some("EGP"));
1130        assert_eq!(IpNumber(9).keyword_str(), Some("IGP"));
1131        assert_eq!(IpNumber(10).keyword_str(), Some("BBN-RCC-MON"));
1132        assert_eq!(IpNumber(11).keyword_str(), Some("NVP-II"));
1133        assert_eq!(IpNumber(12).keyword_str(), Some("PUP"));
1134        assert_eq!(IpNumber(13).keyword_str(), Some("ARGUS (deprecated)"));
1135        assert_eq!(IpNumber(14).keyword_str(), Some("EMCON"));
1136        assert_eq!(IpNumber(15).keyword_str(), Some("XNET"));
1137        assert_eq!(IpNumber(16).keyword_str(), Some("CHAOS"));
1138        assert_eq!(IpNumber(17).keyword_str(), Some("UDP"));
1139        assert_eq!(IpNumber(18).keyword_str(), Some("MUX"));
1140        assert_eq!(IpNumber(19).keyword_str(), Some("DCN-MEAS"));
1141        assert_eq!(IpNumber(20).keyword_str(), Some("HMP"));
1142        assert_eq!(IpNumber(21).keyword_str(), Some("PRM"));
1143        assert_eq!(IpNumber(22).keyword_str(), Some("XNS-IDP"));
1144        assert_eq!(IpNumber(23).keyword_str(), Some("TRUNK-1"));
1145        assert_eq!(IpNumber(24).keyword_str(), Some("TRUNK-2"));
1146        assert_eq!(IpNumber(25).keyword_str(), Some("LEAF-1"));
1147        assert_eq!(IpNumber(26).keyword_str(), Some("LEAF-2"));
1148        assert_eq!(IpNumber(27).keyword_str(), Some("RDP"));
1149        assert_eq!(IpNumber(28).keyword_str(), Some("IRTP"));
1150        assert_eq!(IpNumber(29).keyword_str(), Some("ISO-TP4"));
1151        assert_eq!(IpNumber(30).keyword_str(), Some("NETBLT"));
1152        assert_eq!(IpNumber(31).keyword_str(), Some("MFE-NSP"));
1153        assert_eq!(IpNumber(32).keyword_str(), Some("MERIT-INP"));
1154        assert_eq!(IpNumber(33).keyword_str(), Some("DCCP"));
1155        assert_eq!(IpNumber(34).keyword_str(), Some("3PC"));
1156        assert_eq!(IpNumber(35).keyword_str(), Some("IDPR"));
1157        assert_eq!(IpNumber(36).keyword_str(), Some("XTP"));
1158        assert_eq!(IpNumber(37).keyword_str(), Some("DDP"));
1159        assert_eq!(IpNumber(38).keyword_str(), Some("IDPR-CMTP"));
1160        assert_eq!(IpNumber(39).keyword_str(), Some("TP++"));
1161        assert_eq!(IpNumber(40).keyword_str(), Some("IL"));
1162        assert_eq!(IpNumber(41).keyword_str(), Some("IPv6"));
1163        assert_eq!(IpNumber(42).keyword_str(), Some("SDRP"));
1164        assert_eq!(IpNumber(43).keyword_str(), Some("IPv6-Route"));
1165        assert_eq!(IpNumber(44).keyword_str(), Some("IPv6-Frag"));
1166        assert_eq!(IpNumber(45).keyword_str(), Some("IDRP"));
1167        assert_eq!(IpNumber(46).keyword_str(), Some("RSVP"));
1168        assert_eq!(IpNumber(47).keyword_str(), Some("GRE"));
1169        assert_eq!(IpNumber(48).keyword_str(), Some("DSR"));
1170        assert_eq!(IpNumber(49).keyword_str(), Some("BNA"));
1171        assert_eq!(IpNumber(50).keyword_str(), Some("ESP"));
1172        assert_eq!(IpNumber(51).keyword_str(), Some("AH"));
1173        assert_eq!(IpNumber(52).keyword_str(), Some("I-NLSP"));
1174        assert_eq!(IpNumber(53).keyword_str(), Some("SWIPE (deprecated)"));
1175        assert_eq!(IpNumber(54).keyword_str(), Some("NARP"));
1176        assert_eq!(IpNumber(55).keyword_str(), Some("MOBILE"));
1177        assert_eq!(IpNumber(56).keyword_str(), Some("TLSP"));
1178        assert_eq!(IpNumber(57).keyword_str(), Some("SKIP"));
1179        assert_eq!(IpNumber(58).keyword_str(), Some("IPv6-ICMP"));
1180        assert_eq!(IpNumber(59).keyword_str(), Some("IPv6-NoNxt"));
1181        assert_eq!(IpNumber(60).keyword_str(), Some("IPv6-Opts"));
1182        assert_eq!(IpNumber(61).keyword_str(), None);
1183        assert_eq!(IpNumber(62).keyword_str(), Some("CFTP"));
1184        assert_eq!(IpNumber(63).keyword_str(), None);
1185        assert_eq!(IpNumber(64).keyword_str(), Some("SAT-EXPAK"));
1186        assert_eq!(IpNumber(65).keyword_str(), Some("KRYPTOLAN"));
1187        assert_eq!(IpNumber(66).keyword_str(), Some("RVD"));
1188        assert_eq!(IpNumber(67).keyword_str(), Some("IPPC"));
1189        assert_eq!(IpNumber(68).keyword_str(), None);
1190        assert_eq!(IpNumber(69).keyword_str(), Some("SAT-MON"));
1191        assert_eq!(IpNumber(70).keyword_str(), Some("VISA"));
1192        assert_eq!(IpNumber(71).keyword_str(), Some("IPCV"));
1193        assert_eq!(IpNumber(72).keyword_str(), Some("CPNX"));
1194        assert_eq!(IpNumber(73).keyword_str(), Some("CPHB"));
1195        assert_eq!(IpNumber(74).keyword_str(), Some("WSN"));
1196        assert_eq!(IpNumber(75).keyword_str(), Some("PVP"));
1197        assert_eq!(IpNumber(76).keyword_str(), Some("BR-SAT-MON"));
1198        assert_eq!(IpNumber(77).keyword_str(), Some("SUN-ND"));
1199        assert_eq!(IpNumber(78).keyword_str(), Some("WB-MON"));
1200        assert_eq!(IpNumber(79).keyword_str(), Some("WB-EXPAK"));
1201        assert_eq!(IpNumber(80).keyword_str(), Some("ISO-IP"));
1202        assert_eq!(IpNumber(81).keyword_str(), Some("VMTP"));
1203        assert_eq!(IpNumber(82).keyword_str(), Some("SECURE-VMTP"));
1204        assert_eq!(IpNumber(83).keyword_str(), Some("VINES"));
1205        assert_eq!(IpNumber(84).keyword_str(), Some("IPTM"));
1206        assert_eq!(IpNumber(85).keyword_str(), Some("NSFNET-IGP"));
1207        assert_eq!(IpNumber(86).keyword_str(), Some("DGP"));
1208        assert_eq!(IpNumber(87).keyword_str(), Some("TCF"));
1209        assert_eq!(IpNumber(88).keyword_str(), Some("EIGRP"));
1210        assert_eq!(IpNumber(89).keyword_str(), Some("OSPFIGP"));
1211        assert_eq!(IpNumber(90).keyword_str(), Some("Sprite-RPC"));
1212        assert_eq!(IpNumber(91).keyword_str(), Some("LARP"));
1213        assert_eq!(IpNumber(92).keyword_str(), Some("MTP"));
1214        assert_eq!(IpNumber(93).keyword_str(), Some("AX.25"));
1215        assert_eq!(IpNumber(94).keyword_str(), Some("IPIP"));
1216        assert_eq!(IpNumber(95).keyword_str(), Some("MICP (deprecated)"));
1217        assert_eq!(IpNumber(96).keyword_str(), Some("SCC-SP"));
1218        assert_eq!(IpNumber(97).keyword_str(), Some("ETHERIP"));
1219        assert_eq!(IpNumber(98).keyword_str(), Some("ENCAP"));
1220        assert_eq!(IpNumber(99).keyword_str(), None);
1221        assert_eq!(IpNumber(100).keyword_str(), Some("GMTP"));
1222        assert_eq!(IpNumber(101).keyword_str(), Some("IFMP"));
1223        assert_eq!(IpNumber(102).keyword_str(), Some("PNNI"));
1224        assert_eq!(IpNumber(103).keyword_str(), Some("PIM"));
1225        assert_eq!(IpNumber(104).keyword_str(), Some("ARIS"));
1226        assert_eq!(IpNumber(105).keyword_str(), Some("SCPS"));
1227        assert_eq!(IpNumber(106).keyword_str(), Some("QNX"));
1228        assert_eq!(IpNumber(107).keyword_str(), Some("A/N"));
1229        assert_eq!(IpNumber(108).keyword_str(), Some("IPComp"));
1230        assert_eq!(IpNumber(109).keyword_str(), Some("SNP"));
1231        assert_eq!(IpNumber(110).keyword_str(), Some("Compaq-Peer"));
1232        assert_eq!(IpNumber(111).keyword_str(), Some("IPX-in-IP"));
1233        assert_eq!(IpNumber(112).keyword_str(), Some("VRRP"));
1234        assert_eq!(IpNumber(113).keyword_str(), Some("PGM"));
1235        assert_eq!(IpNumber(114).keyword_str(), None);
1236        assert_eq!(IpNumber(115).keyword_str(), Some("L2TP"));
1237        assert_eq!(IpNumber(116).keyword_str(), Some("DDX"));
1238        assert_eq!(IpNumber(117).keyword_str(), Some("IATP"));
1239        assert_eq!(IpNumber(118).keyword_str(), Some("STP"));
1240        assert_eq!(IpNumber(119).keyword_str(), Some("SRP"));
1241        assert_eq!(IpNumber(120).keyword_str(), Some("UTI"));
1242        assert_eq!(IpNumber(121).keyword_str(), Some("SMP"));
1243        assert_eq!(IpNumber(122).keyword_str(), Some("SM (deprecated)"));
1244        assert_eq!(IpNumber(123).keyword_str(), Some("PTP"));
1245        assert_eq!(IpNumber(124).keyword_str(), Some("ISIS over IPv4"));
1246        assert_eq!(IpNumber(125).keyword_str(), Some("FIRE"));
1247        assert_eq!(IpNumber(126).keyword_str(), Some("CRTP"));
1248        assert_eq!(IpNumber(127).keyword_str(), Some("CRUDP"));
1249        assert_eq!(IpNumber(128).keyword_str(), Some("SSCOPMCE"));
1250        assert_eq!(IpNumber(129).keyword_str(), Some("IPLT"));
1251        assert_eq!(IpNumber(130).keyword_str(), Some("SPS"));
1252        assert_eq!(IpNumber(131).keyword_str(), Some("PIPE"));
1253        assert_eq!(IpNumber(132).keyword_str(), Some("SCTP"));
1254        assert_eq!(IpNumber(133).keyword_str(), Some("FC"));
1255        assert_eq!(IpNumber(134).keyword_str(), Some("RSVP-E2E-IGNORE"));
1256        assert_eq!(IpNumber(135).keyword_str(), Some("Mobility Header"));
1257        assert_eq!(IpNumber(136).keyword_str(), Some("UDPLite"));
1258        assert_eq!(IpNumber(137).keyword_str(), Some("MPLS-in-IP"));
1259        assert_eq!(IpNumber(138).keyword_str(), Some("manet"));
1260        assert_eq!(IpNumber(139).keyword_str(), Some("HIP"));
1261        assert_eq!(IpNumber(140).keyword_str(), Some("Shim6"));
1262        assert_eq!(IpNumber(141).keyword_str(), Some("WESP"));
1263        assert_eq!(IpNumber(142).keyword_str(), Some("ROHC"));
1264        assert_eq!(IpNumber(143).keyword_str(), Some("Ethernet"));
1265        assert_eq!(IpNumber(144).keyword_str(), Some("AGGFRAG"));
1266        for i in 145u8..=252 {
1267            assert_eq!(IpNumber(i).keyword_str(), None);
1268        }
1269        assert_eq!(IpNumber(253).keyword_str(), None);
1270        assert_eq!(IpNumber(254).keyword_str(), None);
1271        assert_eq!(IpNumber(255).keyword_str(), Some("Reserved"));
1272    }
1273
1274    #[test]
1275    fn protocol_str() {
1276        // auto generated from CSV
1277        // https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
1278        // on 2023-04-11.
1279        assert_eq!(IpNumber(0).protocol_str(), Some("IPv6 Hop-by-Hop Option"));
1280        assert_eq!(IpNumber(1).protocol_str(), Some("Internet Control Message"));
1281        assert_eq!(
1282            IpNumber(2).protocol_str(),
1283            Some("Internet Group Management")
1284        );
1285        assert_eq!(IpNumber(3).protocol_str(), Some("Gateway-to-Gateway"));
1286        assert_eq!(IpNumber(4).protocol_str(), Some("IPv4 encapsulation"));
1287        assert_eq!(IpNumber(5).protocol_str(), Some("Stream"));
1288        assert_eq!(IpNumber(6).protocol_str(), Some("Transmission Control"));
1289        assert_eq!(IpNumber(7).protocol_str(), Some("CBT"));
1290        assert_eq!(
1291            IpNumber(8).protocol_str(),
1292            Some("Exterior Gateway Protocol")
1293        );
1294        assert_eq!(
1295            IpNumber(9).protocol_str(),
1296            Some("any private interior gateway (used by Cisco for their IGRP)")
1297        );
1298        assert_eq!(IpNumber(10).protocol_str(), Some("BBN RCC Monitoring"));
1299        assert_eq!(IpNumber(11).protocol_str(), Some("Network Voice Protocol"));
1300        assert_eq!(IpNumber(12).protocol_str(), Some("PUP"));
1301        assert_eq!(IpNumber(13).protocol_str(), Some("ARGUS"));
1302        assert_eq!(IpNumber(14).protocol_str(), Some("EMCON"));
1303        assert_eq!(IpNumber(15).protocol_str(), Some("Cross Net Debugger"));
1304        assert_eq!(IpNumber(16).protocol_str(), Some("Chaos"));
1305        assert_eq!(IpNumber(17).protocol_str(), Some("User Datagram"));
1306        assert_eq!(IpNumber(18).protocol_str(), Some("Multiplexing"));
1307        assert_eq!(
1308            IpNumber(19).protocol_str(),
1309            Some("DCN Measurement Subsystems")
1310        );
1311        assert_eq!(IpNumber(20).protocol_str(), Some("Host Monitoring"));
1312        assert_eq!(
1313            IpNumber(21).protocol_str(),
1314            Some("Packet Radio Measurement")
1315        );
1316        assert_eq!(IpNumber(22).protocol_str(), Some("XEROX NS IDP"));
1317        assert_eq!(IpNumber(23).protocol_str(), Some("Trunk-1"));
1318        assert_eq!(IpNumber(24).protocol_str(), Some("Trunk-2"));
1319        assert_eq!(IpNumber(25).protocol_str(), Some("Leaf-1"));
1320        assert_eq!(IpNumber(26).protocol_str(), Some("Leaf-2"));
1321        assert_eq!(IpNumber(27).protocol_str(), Some("Reliable Data Protocol"));
1322        assert_eq!(
1323            IpNumber(28).protocol_str(),
1324            Some("Internet Reliable Transaction")
1325        );
1326        assert_eq!(
1327            IpNumber(29).protocol_str(),
1328            Some("ISO Transport Protocol Class 4")
1329        );
1330        assert_eq!(
1331            IpNumber(30).protocol_str(),
1332            Some("Bulk Data Transfer Protocol")
1333        );
1334        assert_eq!(
1335            IpNumber(31).protocol_str(),
1336            Some("MFE Network Services Protocol")
1337        );
1338        assert_eq!(
1339            IpNumber(32).protocol_str(),
1340            Some("MERIT Internodal Protocol")
1341        );
1342        assert_eq!(
1343            IpNumber(33).protocol_str(),
1344            Some("Datagram Congestion Control Protocol")
1345        );
1346        assert_eq!(
1347            IpNumber(34).protocol_str(),
1348            Some("Third Party Connect Protocol")
1349        );
1350        assert_eq!(
1351            IpNumber(35).protocol_str(),
1352            Some("Inter-Domain Policy Routing Protocol")
1353        );
1354        assert_eq!(IpNumber(36).protocol_str(), Some("XTP"));
1355        assert_eq!(
1356            IpNumber(37).protocol_str(),
1357            Some("Datagram Delivery Protocol")
1358        );
1359        assert_eq!(
1360            IpNumber(38).protocol_str(),
1361            Some("IDPR Control Message Transport Proto")
1362        );
1363        assert_eq!(IpNumber(39).protocol_str(), Some("TP++ Transport Protocol"));
1364        assert_eq!(IpNumber(40).protocol_str(), Some("IL Transport Protocol"));
1365        assert_eq!(IpNumber(41).protocol_str(), Some("IPv6 encapsulation"));
1366        assert_eq!(
1367            IpNumber(42).protocol_str(),
1368            Some("Source Demand Routing Protocol")
1369        );
1370        assert_eq!(IpNumber(43).protocol_str(), Some("Routing Header for IPv6"));
1371        assert_eq!(
1372            IpNumber(44).protocol_str(),
1373            Some("Fragment Header for IPv6")
1374        );
1375        assert_eq!(
1376            IpNumber(45).protocol_str(),
1377            Some("Inter-Domain Routing Protocol")
1378        );
1379        assert_eq!(IpNumber(46).protocol_str(), Some("Reservation Protocol"));
1380        assert_eq!(
1381            IpNumber(47).protocol_str(),
1382            Some("Generic Routing Encapsulation")
1383        );
1384        assert_eq!(
1385            IpNumber(48).protocol_str(),
1386            Some("Dynamic Source Routing Protocol")
1387        );
1388        assert_eq!(IpNumber(49).protocol_str(), Some("BNA"));
1389        assert_eq!(IpNumber(50).protocol_str(), Some("Encap Security Payload"));
1390        assert_eq!(IpNumber(51).protocol_str(), Some("Authentication Header"));
1391        assert_eq!(
1392            IpNumber(52).protocol_str(),
1393            Some("Integrated Net Layer Security  TUBA")
1394        );
1395        assert_eq!(IpNumber(53).protocol_str(), Some("IP with Encryption"));
1396        assert_eq!(
1397            IpNumber(54).protocol_str(),
1398            Some("NBMA Address Resolution Protocol")
1399        );
1400        assert_eq!(IpNumber(55).protocol_str(), Some("IP Mobility"));
1401        assert_eq!(
1402            IpNumber(56).protocol_str(),
1403            Some("Transport Layer Security Protocol using Kryptonet key management")
1404        );
1405        assert_eq!(IpNumber(57).protocol_str(), Some("SKIP"));
1406        assert_eq!(IpNumber(58).protocol_str(), Some("ICMP for IPv6"));
1407        assert_eq!(IpNumber(59).protocol_str(), Some("No Next Header for IPv6"));
1408        assert_eq!(
1409            IpNumber(60).protocol_str(),
1410            Some("Destination Options for IPv6")
1411        );
1412        assert_eq!(
1413            IpNumber(61).protocol_str(),
1414            Some("any host internal protocol")
1415        );
1416        assert_eq!(IpNumber(62).protocol_str(), Some("CFTP"));
1417        assert_eq!(IpNumber(63).protocol_str(), Some("any local network"));
1418        assert_eq!(
1419            IpNumber(64).protocol_str(),
1420            Some("SATNET and Backroom EXPAK")
1421        );
1422        assert_eq!(IpNumber(65).protocol_str(), Some("Kryptolan"));
1423        assert_eq!(
1424            IpNumber(66).protocol_str(),
1425            Some("MIT Remote Virtual Disk Protocol")
1426        );
1427        assert_eq!(
1428            IpNumber(67).protocol_str(),
1429            Some("Internet Pluribus Packet Core")
1430        );
1431        assert_eq!(
1432            IpNumber(68).protocol_str(),
1433            Some("any distributed file system")
1434        );
1435        assert_eq!(IpNumber(69).protocol_str(), Some("SATNET Monitoring"));
1436        assert_eq!(IpNumber(70).protocol_str(), Some("VISA Protocol"));
1437        assert_eq!(
1438            IpNumber(71).protocol_str(),
1439            Some("Internet Packet Core Utility")
1440        );
1441        assert_eq!(
1442            IpNumber(72).protocol_str(),
1443            Some("Computer Protocol Network Executive")
1444        );
1445        assert_eq!(
1446            IpNumber(73).protocol_str(),
1447            Some("Computer Protocol Heart Beat")
1448        );
1449        assert_eq!(IpNumber(74).protocol_str(), Some("Wang Span Network"));
1450        assert_eq!(IpNumber(75).protocol_str(), Some("Packet Video Protocol"));
1451        assert_eq!(
1452            IpNumber(76).protocol_str(),
1453            Some("Backroom SATNET Monitoring")
1454        );
1455        assert_eq!(
1456            IpNumber(77).protocol_str(),
1457            Some("SUN ND PROTOCOL-Temporary")
1458        );
1459        assert_eq!(IpNumber(78).protocol_str(), Some("WIDEBAND Monitoring"));
1460        assert_eq!(IpNumber(79).protocol_str(), Some("WIDEBAND EXPAK"));
1461        assert_eq!(IpNumber(80).protocol_str(), Some("ISO Internet Protocol"));
1462        assert_eq!(IpNumber(81).protocol_str(), Some("VMTP"));
1463        assert_eq!(IpNumber(82).protocol_str(), Some("SECURE-VMTP"));
1464        assert_eq!(IpNumber(83).protocol_str(), Some("VINES"));
1465        assert_eq!(
1466            IpNumber(84).protocol_str(),
1467            Some("Internet Protocol Traffic Manager")
1468        );
1469        assert_eq!(IpNumber(85).protocol_str(), Some("NSFNET-IGP"));
1470        assert_eq!(
1471            IpNumber(86).protocol_str(),
1472            Some("Dissimilar Gateway Protocol")
1473        );
1474        assert_eq!(IpNumber(87).protocol_str(), Some("TCF"));
1475        assert_eq!(IpNumber(88).protocol_str(), Some("EIGRP"));
1476        assert_eq!(IpNumber(89).protocol_str(), Some("OSPFIGP"));
1477        assert_eq!(IpNumber(90).protocol_str(), Some("Sprite RPC Protocol"));
1478        assert_eq!(
1479            IpNumber(91).protocol_str(),
1480            Some("Locus Address Resolution Protocol")
1481        );
1482        assert_eq!(
1483            IpNumber(92).protocol_str(),
1484            Some("Multicast Transport Protocol")
1485        );
1486        assert_eq!(IpNumber(93).protocol_str(), Some("AX.25 Frames"));
1487        assert_eq!(
1488            IpNumber(94).protocol_str(),
1489            Some("IP-within-IP Encapsulation Protocol")
1490        );
1491        assert_eq!(
1492            IpNumber(95).protocol_str(),
1493            Some("Mobile Internetworking Control Pro.")
1494        );
1495        assert_eq!(
1496            IpNumber(96).protocol_str(),
1497            Some("Semaphore Communications Sec. Pro.")
1498        );
1499        assert_eq!(
1500            IpNumber(97).protocol_str(),
1501            Some("Ethernet-within-IP Encapsulation")
1502        );
1503        assert_eq!(IpNumber(98).protocol_str(), Some("Encapsulation Header"));
1504        assert_eq!(
1505            IpNumber(99).protocol_str(),
1506            Some("any private encryption scheme")
1507        );
1508        assert_eq!(IpNumber(100).protocol_str(), Some("GMTP"));
1509        assert_eq!(
1510            IpNumber(101).protocol_str(),
1511            Some("Ipsilon Flow Management Protocol")
1512        );
1513        assert_eq!(IpNumber(102).protocol_str(), Some("PNNI over IP"));
1514        assert_eq!(
1515            IpNumber(103).protocol_str(),
1516            Some("Protocol Independent Multicast")
1517        );
1518        assert_eq!(IpNumber(104).protocol_str(), Some("ARIS"));
1519        assert_eq!(IpNumber(105).protocol_str(), Some("SCPS"));
1520        assert_eq!(IpNumber(106).protocol_str(), Some("QNX"));
1521        assert_eq!(IpNumber(107).protocol_str(), Some("Active Networks"));
1522        assert_eq!(
1523            IpNumber(108).protocol_str(),
1524            Some("IP Payload Compression Protocol")
1525        );
1526        assert_eq!(
1527            IpNumber(109).protocol_str(),
1528            Some("Sitara Networks Protocol")
1529        );
1530        assert_eq!(IpNumber(110).protocol_str(), Some("Compaq Peer Protocol"));
1531        assert_eq!(IpNumber(111).protocol_str(), Some("IPX in IP"));
1532        assert_eq!(
1533            IpNumber(112).protocol_str(),
1534            Some("Virtual Router Redundancy Protocol")
1535        );
1536        assert_eq!(
1537            IpNumber(113).protocol_str(),
1538            Some("PGM Reliable Transport Protocol")
1539        );
1540        assert_eq!(IpNumber(114).protocol_str(), Some("any 0-hop protocol"));
1541        assert_eq!(
1542            IpNumber(115).protocol_str(),
1543            Some("Layer Two Tunneling Protocol")
1544        );
1545        assert_eq!(
1546            IpNumber(116).protocol_str(),
1547            Some("D-II Data Exchange (DDX)")
1548        );
1549        assert_eq!(
1550            IpNumber(117).protocol_str(),
1551            Some("Interactive Agent Transfer Protocol")
1552        );
1553        assert_eq!(
1554            IpNumber(118).protocol_str(),
1555            Some("Schedule Transfer Protocol")
1556        );
1557        assert_eq!(
1558            IpNumber(119).protocol_str(),
1559            Some("SpectraLink Radio Protocol")
1560        );
1561        assert_eq!(IpNumber(120).protocol_str(), Some("UTI"));
1562        assert_eq!(
1563            IpNumber(121).protocol_str(),
1564            Some("Simple Message Protocol")
1565        );
1566        assert_eq!(
1567            IpNumber(122).protocol_str(),
1568            Some("Simple Multicast Protocol")
1569        );
1570        assert_eq!(
1571            IpNumber(123).protocol_str(),
1572            Some("Performance Transparency Protocol")
1573        );
1574        assert_eq!(IpNumber(124).protocol_str(), None);
1575        assert_eq!(IpNumber(125).protocol_str(), None);
1576        assert_eq!(
1577            IpNumber(126).protocol_str(),
1578            Some("Combat Radio Transport Protocol")
1579        );
1580        assert_eq!(
1581            IpNumber(127).protocol_str(),
1582            Some("Combat Radio User Datagram")
1583        );
1584        assert_eq!(IpNumber(128).protocol_str(), None);
1585        assert_eq!(IpNumber(129).protocol_str(), None);
1586        assert_eq!(IpNumber(130).protocol_str(), Some("Secure Packet Shield"));
1587        assert_eq!(
1588            IpNumber(131).protocol_str(),
1589            Some("Private IP Encapsulation within IP")
1590        );
1591        assert_eq!(
1592            IpNumber(132).protocol_str(),
1593            Some("Stream Control Transmission Protocol")
1594        );
1595        assert_eq!(IpNumber(133).protocol_str(), Some("Fibre Channel"));
1596        assert_eq!(IpNumber(134).protocol_str(), None);
1597        assert_eq!(IpNumber(135).protocol_str(), None);
1598        assert_eq!(IpNumber(136).protocol_str(), None);
1599        assert_eq!(IpNumber(137).protocol_str(), None);
1600        assert_eq!(IpNumber(138).protocol_str(), Some("MANET Protocols"));
1601        assert_eq!(IpNumber(139).protocol_str(), Some("Host Identity Protocol"));
1602        assert_eq!(IpNumber(140).protocol_str(), Some("Shim6 Protocol"));
1603        assert_eq!(
1604            IpNumber(141).protocol_str(),
1605            Some("Wrapped Encapsulating Security Payload")
1606        );
1607        assert_eq!(
1608            IpNumber(142).protocol_str(),
1609            Some("Robust Header Compression")
1610        );
1611        assert_eq!(IpNumber(143).protocol_str(), Some("Ethernet"));
1612        assert_eq!(
1613            IpNumber(144).protocol_str(),
1614            Some("AGGFRAG encapsulation payload for ESP")
1615        );
1616        for i in 145u8..=252 {
1617            assert_eq!(IpNumber(i).protocol_str(), None);
1618        }
1619        assert_eq!(
1620            IpNumber(253).protocol_str(),
1621            Some("Use for experimentation and testing")
1622        );
1623        assert_eq!(
1624            IpNumber(254).protocol_str(),
1625            Some("Use for experimentation and testing")
1626        );
1627        assert_eq!(IpNumber(255).protocol_str(), None);
1628    }
1629
1630    #[test]
1631    fn ip_number_eq_check() {
1632        use crate::ip_number::*;
1633        use crate::IpNumber;
1634        let pairs = &[
1635            (IPV6_HOP_BY_HOP, IpNumber::IPV6_HEADER_HOP_BY_HOP),
1636            (IPV6_HEADER_HOP_BY_HOP, IpNumber::IPV6_HEADER_HOP_BY_HOP),
1637            (ICMP, IpNumber::ICMP),
1638            (IGMP, IpNumber::IGMP),
1639            (GGP, IpNumber::GGP),
1640            (IPV4, IpNumber::IPV4),
1641            (STREAM, IpNumber::STREAM),
1642            (TCP, IpNumber::TCP),
1643            (CBT, IpNumber::CBT),
1644            (EGP, IpNumber::EGP),
1645            (IGP, IpNumber::IGP),
1646            (BBN_RCC_MON, IpNumber::BBN_RCC_MON),
1647            (NVP_II, IpNumber::NVP_II),
1648            (PUP, IpNumber::PUP),
1649            (ARGUS, IpNumber::ARGUS),
1650            (EMCON, IpNumber::EMCON),
1651            (XNET, IpNumber::XNET),
1652            (CHAOS, IpNumber::CHAOS),
1653            (UDP, IpNumber::UDP),
1654            (MUX, IpNumber::MUX),
1655            (DCN_MEAS, IpNumber::DCN_MEAS),
1656            (HMP, IpNumber::HMP),
1657            (PRM, IpNumber::PRM),
1658            (XNS_IDP, IpNumber::XNS_IDP),
1659            (TRUNK1, IpNumber::TRUNK1),
1660            (TRUNK2, IpNumber::TRUNK2),
1661            (LEAF1, IpNumber::LEAF1),
1662            (LEAF2, IpNumber::LEAF2),
1663            (RDP, IpNumber::RDP),
1664            (IRTP, IpNumber::IRTP),
1665            (ISO_TP4, IpNumber::ISO_TP4),
1666            (NET_BLT, IpNumber::NET_BLT),
1667            (MFE_NSP, IpNumber::MFE_NSP),
1668            (MERIT_INP, IpNumber::MERIT_INP),
1669            (DCCP, IpNumber::DCCP),
1670            (
1671                THIRD_PARTY_CONNECT_PROTOCOL,
1672                IpNumber::THIRD_PARTY_CONNECT_PROTOCOL,
1673            ),
1674            (IDPR, IpNumber::IDPR),
1675            (XTP, IpNumber::XTP),
1676            (DDP, IpNumber::DDP),
1677            (IDPR_CMTP, IpNumber::IDPR_CMTP),
1678            (TP_PLUS_PLUS, IpNumber::TP_PLUS_PLUS),
1679            (IL, IpNumber::IL),
1680            (IPV6, IpNumber::IPV6),
1681            (SDRP, IpNumber::SDRP),
1682            (IPV6_ROUTE_HEADER, IpNumber::IPV6_ROUTE_HEADER),
1683            (IPV6_ROUTE, IpNumber::IPV6_ROUTE_HEADER),
1684            (
1685                IPV6_FRAGMENTATION_HEADER,
1686                IpNumber::IPV6_FRAGMENTATION_HEADER,
1687            ),
1688            (IPV6_FRAG, IpNumber::IPV6_FRAGMENTATION_HEADER),
1689            (IDRP, IpNumber::IDRP),
1690            (RSVP, IpNumber::RSVP),
1691            (GRE, IpNumber::GRE),
1692            (DSR, IpNumber::DSR),
1693            (BNA, IpNumber::BNA),
1694            (ENCAP_SEC, IpNumber::ENCAPSULATING_SECURITY_PAYLOAD),
1695            (
1696                ENCAPSULATING_SECURITY_PAYLOAD,
1697                IpNumber::ENCAPSULATING_SECURITY_PAYLOAD,
1698            ),
1699            (AUTH, IpNumber::AUTHENTICATION_HEADER),
1700            (AUTHENTICATION_HEADER, IpNumber::AUTHENTICATION_HEADER),
1701            (INLSP, IpNumber::INLSP),
1702            (SWIPE, IpNumber::SWIPE),
1703            (NARP, IpNumber::NARP),
1704            (MOBILE, IpNumber::MOBILE),
1705            (TLSP, IpNumber::TLSP),
1706            (SKIP, IpNumber::SKIP),
1707            (IPV6_ICMP, IpNumber::IPV6_ICMP),
1708            (IPV6_NO_NEXT_HEADER, IpNumber::IPV6_NO_NEXT_HEADER),
1709            (IPV6_DEST_OPTIONS, IpNumber::IPV6_DESTINATION_OPTIONS),
1710            (IPV6_DESTINATION_OPTIONS, IpNumber::IPV6_DESTINATION_OPTIONS),
1711            (
1712                ANY_HOST_INTERNAL_PROTOCOL,
1713                IpNumber::ANY_HOST_INTERNAL_PROTOCOL,
1714            ),
1715            (CFTP, IpNumber::CFTP),
1716            (ANY_LOCAL_NETWORK, IpNumber::ANY_LOCAL_NETWORK),
1717            (SAT_EXPAK, IpNumber::SAT_EXPAK),
1718            (KRYTOLAN, IpNumber::KRYTOLAN),
1719            (RVD, IpNumber::RVD),
1720            (IPPC, IpNumber::IPPC),
1721            (
1722                ANY_DISTRIBUTED_FILE_SYSTEM,
1723                IpNumber::ANY_DISTRIBUTED_FILE_SYSTEM,
1724            ),
1725            (SAT_MON, IpNumber::SAT_MON),
1726            (VISA, IpNumber::VISA),
1727            (IPCV, IpNumber::IPCV),
1728            (CPNX, IpNumber::CPNX),
1729            (CPHB, IpNumber::CPHB),
1730            (WSN, IpNumber::WSN),
1731            (PVP, IpNumber::PVP),
1732            (BR_SAT_MON, IpNumber::BR_SAT_MON),
1733            (SUN_ND, IpNumber::SUN_ND),
1734            (WB_MON, IpNumber::WB_MON),
1735            (WB_EXPAK, IpNumber::WB_EXPAK),
1736            (ISO_IP, IpNumber::ISO_IP),
1737            (VMTP, IpNumber::VMTP),
1738            (SECURE_VMTP, IpNumber::SECURE_VMTP),
1739            (VINES, IpNumber::VINES),
1740            (TTP_OR_IPTM, IpNumber::TTP_OR_IPTM),
1741            (NSFNET_IGP, IpNumber::NSFNET_IGP),
1742            (DGP, IpNumber::DGP),
1743            (TCF, IpNumber::TCF),
1744            (EIGRP, IpNumber::EIGRP),
1745            (OSPFIGP, IpNumber::OSPFIGP),
1746            (SPRITE_RPC, IpNumber::SPRITE_RPC),
1747            (LARP, IpNumber::LARP),
1748            (MTP, IpNumber::MTP),
1749            (AX25, IpNumber::AX25),
1750            (IPIP, IpNumber::IPIP),
1751            (MICP, IpNumber::MICP),
1752            (SCC_SP, IpNumber::SCC_SP),
1753            (ETHER_IP, IpNumber::ETHER_IP),
1754            (ENCAP, IpNumber::ENCAP),
1755            (GMTP, IpNumber::GMTP),
1756            (IFMP, IpNumber::IFMP),
1757            (PNNI, IpNumber::PNNI),
1758            (PIM, IpNumber::PIM),
1759            (ARIS, IpNumber::ARIS),
1760            (SCPS, IpNumber::SCPS),
1761            (QNX, IpNumber::QNX),
1762            (ACTIVE_NETWORKS, IpNumber::ACTIVE_NETWORKS),
1763            (IP_COMP, IpNumber::IP_COMP),
1764            (SITRA_NETWORKS_PROTOCOL, IpNumber::SITRA_NETWORKS_PROTOCOL),
1765            (COMPAQ_PEER, IpNumber::COMPAQ_PEER),
1766            (IPX_IN_IP, IpNumber::IPX_IN_IP),
1767            (VRRP, IpNumber::VRRP),
1768            (PGM, IpNumber::PGM),
1769            (ANY_ZERO_HOP_PROTOCOL, IpNumber::ANY_ZERO_HOP_PROTOCOL),
1770            (
1771                LAYER2_TUNNELING_PROTOCOL,
1772                IpNumber::LAYER2_TUNNELING_PROTOCOL,
1773            ),
1774            (DDX, IpNumber::DDX),
1775            (IATP, IpNumber::IATP),
1776            (STP, IpNumber::STP),
1777            (SRP, IpNumber::SRP),
1778            (UTI, IpNumber::UTI),
1779            (SIMPLE_MESSAGE_PROTOCOL, IpNumber::SIMPLE_MESSAGE_PROTOCOL),
1780            (SM, IpNumber::SM),
1781            (PTP, IpNumber::PTP),
1782            (ISIS_OVER_IPV4, IpNumber::ISIS_OVER_IPV4),
1783            (FIRE, IpNumber::FIRE),
1784            (CRTP, IpNumber::CRTP),
1785            (CRUDP, IpNumber::CRUDP),
1786            (SSCOPMCE, IpNumber::SSCOPMCE),
1787            (IPLT, IpNumber::IPLT),
1788            (SPS, IpNumber::SPS),
1789            (PIPE, IpNumber::PIPE),
1790            (SCTP, IpNumber::SCTP),
1791            (FC, IpNumber::FC),
1792            (RSVP_E2E_IGNORE, IpNumber::RSVP_E2E_IGNORE),
1793            (MOBILITY, IpNumber::MOBILITY_HEADER),
1794            (MOBILITY_HEADER, IpNumber::MOBILITY_HEADER),
1795            (UDP_LITE, IpNumber::UDP_LITE),
1796            (MPLS_IN_IP, IpNumber::MPLS_IN_IP),
1797            (MANET, IpNumber::MANET),
1798            (HIP, IpNumber::HIP),
1799            (SHIM6, IpNumber::SHIM6),
1800            (WESP, IpNumber::WESP),
1801            (ROHC, IpNumber::ROHC),
1802            (EXP0, IpNumber::EXPERIMENTAL_AND_TESTING_0),
1803            (
1804                EXPERIMENTAL_AND_TESTING_0,
1805                IpNumber::EXPERIMENTAL_AND_TESTING_0,
1806            ),
1807            (EXP1, IpNumber::EXPERIMENTAL_AND_TESTING_1),
1808            (
1809                EXPERIMENTAL_AND_TESTING_1,
1810                IpNumber::EXPERIMENTAL_AND_TESTING_1,
1811            ),
1812        ];
1813        for (raw, enum_value) in pairs {
1814            assert_eq!(*raw, *enum_value);
1815        }
1816    }
1817
1818    #[test]
1819    fn default() {
1820        let actual: IpNumber = Default::default();
1821        assert_eq!(actual, IpNumber(255));
1822    }
1823
1824    proptest! {
1825        #[test]
1826        fn into(num in any::<u8>()) {
1827            {
1828                let converted: u8 = IpNumber(num).into();
1829                assert_eq!(converted, num);
1830            }
1831            {
1832                let converted: IpNumber = num.into();
1833                assert_eq!(converted, IpNumber(num));
1834            }
1835        }
1836    }
1837
1838    proptest! {
1839        #[test]
1840        fn from(num in any::<u8>()) {
1841            {
1842                let converted: u8 = u8::from(IpNumber(num));
1843                assert_eq!(converted, num);
1844            }
1845            {
1846                let converted: IpNumber = IpNumber::from(num);
1847                assert_eq!(converted, IpNumber(num));
1848            }
1849        }
1850    }
1851
1852    #[test]
1853    fn debug() {
1854        // keyword & protocol string exist
1855        assert_eq!(
1856            format!("{:?}", IpNumber::UDP),
1857            format!("17 (UDP - User Datagram)")
1858        );
1859        // only keyword string exist
1860        assert_eq!(
1861            format!("{:?}", IpNumber::MOBILITY_HEADER),
1862            format!("135 (Mobility Header)")
1863        );
1864        // only protocol string exist
1865        assert_eq!(
1866            format!("{:?}", IpNumber(253)),
1867            format!("253 (Use for experimentation and testing)")
1868        );
1869        // no keyword & no protocol string
1870        assert_eq!(format!("{:?}", IpNumber(145)), format!("145"));
1871    }
1872
1873    #[test]
1874    fn clone_eq_hash_ord() {
1875        // clone eq
1876        let value = IpNumber::IPV6_HEADER_HOP_BY_HOP;
1877        assert_eq!(value, value.clone());
1878        // hash
1879        let a_hash = {
1880            let mut s = DefaultHasher::new();
1881            value.hash(&mut s);
1882            s.finish()
1883        };
1884        let b_hash = {
1885            let mut s = DefaultHasher::new();
1886            value.hash(&mut s);
1887            s.finish()
1888        };
1889        assert_eq!(a_hash, b_hash);
1890        // order
1891        assert_eq!(value.cmp(&value.clone()), Ordering::Equal);
1892        assert!(value.ge(&value.clone()));
1893    }
1894}