Skip to main content

packet_strata/packet/
protocol.rs

1//! IP Protocol Numbers
2//!
3//! This module defines IP protocol numbers as specified in RFC 1700 and maintained
4//! by IANA. These protocol numbers are used in IPv4 headers (Protocol field) and
5//! IPv6 headers (Next Header field).
6//!
7//! # Examples
8//!
9//! ```
10//! use packet_strata::packet::protocol::IpProto;
11//!
12//! // Common protocols
13//! let tcp = IpProto::TCP;
14//! let udp = IpProto::UDP;
15//! let icmp = IpProto::ICMP;
16//!
17//! // IPv6 extension headers
18//! let hop_by_hop = IpProto::IPV6_HOPOPT;
19//! let routing = IpProto::IPV6_ROUTE;
20//! let fragment = IpProto::IPV6_FRAG;
21//!
22//! // Display protocol names
23//! assert_eq!(format!("{}", tcp), "tcp");
24//! assert_eq!(format!("{}", udp), "udp");
25//! assert_eq!(format!("{}", IpProto::IPV6_ICMP), "ipv6-icmp");
26//!
27//! // Convert from/to u8
28//! let proto = IpProto::from(6);
29//! assert_eq!(proto, IpProto::TCP);
30//! let value: u8 = IpProto::UDP.into();
31//! assert_eq!(value, 17);
32//!
33//! // Check if protocol is valid/known
34//! assert!(IpProto::TCP.is_valid());
35//! assert!(IpProto::UDP.is_valid());
36//! assert!(!IpProto::from(200).is_valid());
37//! ```
38
39use zerocopy::{BigEndian, FromBytes, Immutable, IntoBytes, KnownLayout, U16};
40
41crate::protocol_constants! {
42    EtherProto, U16<BigEndian>, u16:
43        LOOP = 0x0060;
44        PUP = 0x0200;
45        PUPAT = 0x0201;
46        #[default] IPV4 = 0x0800;
47        X25 = 0x0805;
48        ARP = 0x0806;
49        BPQ = 0x08FF;
50        IEEEPUP = 0x0a00;
51        IEEEPUPAT = 0x0a01;
52        BATMAN = 0x4305;
53        DEC = 0x6000;
54        DNA_DL = 0x6001;
55        DNA_RC = 0x6002;
56        DNA_RT = 0x6003;
57        LAT = 0x6004;
58        DIAG = 0x6005;
59        CUST = 0x6006;
60        SCA = 0x6007;
61        TEB = 0x6558;
62        RARP = 0x8035;
63        ATALK = 0x809B;
64        AARP = 0x80F3;
65        VLAN_8021Q = 0x8100;
66        IPX = 0x8137;
67        IPV6 = 0x86DD;
68        PAUSE = 0x8808;
69        SLOW = 0x8809;
70        WCCP = 0x883E;
71        MPLS_UC = 0x8847;
72        MPLS_MC = 0x8848;
73        ATMMPOA = 0x884c;
74        PPP_DISC = 0x8863;
75        PPP_SES = 0x8864;
76        LINK_CTL = 0x886c;
77        ATMFATE = 0x8884;
78        PAE = 0x888E;
79        AOE = 0x88A2;
80        VLAN_8021AD = 0x88A8;
81        IEEE_802_EX1 = 0x88B5;
82        TIPC = 0x88CA;
83        VLAN_8021AH = 0x88E7;
84        MVRP = 0x88F5;
85        IEEE_1588 = 0x88F7;
86        PRP = 0x88FB;
87        FCOE = 0x8906;
88        TDLS = 0x890D;
89        FIP = 0x8914;
90        IEEE_80221 = 0x8917;
91        LOOPBACK = 0x9000;
92        QINQ1 = 0x9100;
93        QINQ2 = 0x9200;
94        QINQ3 = 0x9300;
95        EDSA = 0xDADA;
96        AF_IUCV = 0xFBFB;
97        IEEE_802_3_MIN = 0x0600;
98        IEEE_802_3 = 0x0001;
99        AX25 = 0x0002;
100        ALL = 0x0003;
101        IEEE_802_2 = 0x0004;
102        SNAP = 0x0005;
103        DDCMP = 0x0006;
104        WAN_PPP = 0x0007;
105        PPP_MP = 0x0008;
106        LOCALTALK = 0x0009;
107        CAN = 0x000C;
108        CANFD = 0x000D;
109        PPPTALK = 0x0010;
110        TR_802_2 = 0x0011;
111        MOBITEX = 0x0015;
112        CONTROL = 0x0016;
113        IRDA = 0x0017;
114        ECONET = 0x0018;
115        HDLC = 0x0019;
116        ARCNET = 0x001A;
117        DSA = 0x001B;
118        TRAILER = 0x001C;
119        PHONET = 0x00F5;
120        IEEE802154 = 0x00F6;
121        CAIF = 0x00F7;
122}
123
124crate::protocol_constants! {
125    IpProto, u8, u8:
126        IPV6_HOPOPT = 0;
127        ICMP = 1;
128        IGMP = 2;
129        GGP = 3;
130        IP_ENCAP = 4;
131        ST = 5;
132        TCP = 6;
133        CBT = 7;
134        EGP = 8;
135        IGP = 9;
136        BBN_RCC = 10;
137        NVP = 11;
138        PUP = 12;
139        ARGUS = 13;
140        EMCON = 14;
141        XNET = 15;
142        CHAOS = 16;
143        UDP = 17;
144        MUX = 18;
145        DCN_MEAS = 19;
146        HMP = 20;
147        PRM = 21;
148        XNS_IDP = 22;
149        TRUNK1 = 23;
150        TRUNK2 = 24;
151        LEAF1 = 25;
152        LEAF2 = 26;
153        RDP = 27;
154        IRTP = 28;
155        ISO_TP4 = 29;
156        NETBLT = 30;
157        MFE_NSP = 31;
158        MERIT_INP = 32;
159        DCCP = 33;
160        _3PC = 34;
161        IDPR = 35;
162        XTP = 36;
163        DDP = 37;
164        IDPR_CMTP = 38;
165        TP_PP = 39;
166        IL = 40;
167        IPV6 = 41;
168        SDRP = 42;
169        IPV6_ROUTE = 43;
170        IPV6_FRAG = 44;
171        IDRP = 45;
172        RSVP = 46;
173        GRE = 47;
174        BNA = 49;
175        ESP = 50;
176        AH = 51;
177        I_NLSP = 52;
178        SWIPE = 53;
179        NARP = 54;
180        MOBILE = 55;
181        TLSP = 56;
182        SKIP = 57;
183        IPV6_ICMP = 58;
184        IPV6_NONXT = 59;
185        IPV6_OPTS = 60;
186        CFTP = 62;
187        SAT_EXPAK = 64;
188        KRYPTOLAN = 65;
189        RVD = 66;
190        IPPC = 67;
191        SAT_MON = 69;
192        VISA = 70;
193        IPCU = 71;
194        CPNX = 72;
195        CPHB = 73;
196        WSN = 74;
197        PVP = 75;
198        BR_SAT_MON = 76;
199        SUN_ND = 77;
200        WB_MON = 78;
201        WB_EXPAK = 79;
202        ISO_IP = 80;
203        VMTP = 81;
204        SECURE_VMTP = 82;
205        VINES = 83;
206        IPTM = 84;
207        NSFNET_IGP = 85;
208        DGP = 86;
209        TCF = 87;
210        EIGRP = 88;
211        OSPF = 89;
212        SPRITE_RPC = 90;
213        LARP = 91;
214        MTP = 92;
215        AX_25 = 93;
216        OS = 94;
217        MICP = 95;
218        SCC_SP = 96;
219        ETHERIP = 97;
220        ENCAP = 98;
221        GMTP = 100;
222        IFMP = 101;
223        PNNI = 102;
224        PIM = 103;
225        ARIS = 104;
226        SCPS = 105;
227        QNX = 106;
228        AN = 107;
229        IPCOMP = 108;
230        SNP = 109;
231        COMPAQ_PEER = 110;
232        IPX_IN_IP = 111;
233        VRRP = 112;
234        PGM = 113;
235        L2TP = 115;
236        DDX = 116;
237        IATP = 117;
238        STP = 118;
239        SRP = 119;
240        UTI = 120;
241        SMP = 121;
242        SM = 122;
243        PTP = 123;
244        IS_IS = 124;
245        FIRE = 125;
246        CRTP = 126;
247        CRUDP = 127;
248        SSCOPMCE = 128;
249        IPLT = 129;
250        SPS = 130;
251        PIPE = 131;
252        SCTP = 132;
253        FC = 133;
254        RSVP_E2E = 134;
255        IPV6_MOBILITY = 135;
256        UDPLITE = 136;
257        MPLS_IN_IP = 137;
258        MANET = 138;
259        HIP = 139;
260        SHIM6 = 140;
261        WESP = 141;
262        ROHC = 142;
263        #[default] ANY = 255;
264}
265
266#[cfg(test)]
267mod tests {
268    use super::*;
269
270    #[test]
271    fn test_protocol_constants() {
272        assert_eq!(IpProto::TCP.0, 6);
273        assert_eq!(IpProto::UDP.0, 17);
274        assert_eq!(IpProto::ICMP.0, 1);
275        assert_eq!(IpProto::IPV6.0, 41);
276        assert_eq!(IpProto::IPV6_HOPOPT.0, 0);
277        assert_eq!(IpProto::IPV6_ROUTE.0, 43);
278        assert_eq!(IpProto::IPV6_FRAG.0, 44);
279        assert_eq!(IpProto::IPV6_ICMP.0, 58);
280        assert_eq!(IpProto::IPV6_NONXT.0, 59);
281        assert_eq!(IpProto::IPV6_OPTS.0, 60);
282        assert_eq!(IpProto::ANY.0, 255);
283    }
284
285    #[test]
286    fn test_protocol_display() {
287        assert_eq!(format!("{}", IpProto::TCP), "tcp");
288        assert_eq!(format!("{}", IpProto::UDP), "udp");
289        assert_eq!(format!("{}", IpProto::ICMP), "icmp");
290        assert_eq!(format!("{}", IpProto::IPV6_ICMP), "ipv6-icmp");
291        assert_eq!(format!("{}", IpProto::IPV6_ROUTE), "ipv6-route");
292        assert_eq!(format!("{}", IpProto::IPV6_FRAG), "ipv6-frag");
293        assert_eq!(format!("{}", IpProto::IPV6_OPTS), "ipv6-opts");
294        assert_eq!(format!("{}", IpProto::IPV6_NONXT), "ipv6-nonxt");
295        assert_eq!(format!("{}", IpProto::_3PC), "3pc");
296        assert_eq!(format!("{}", IpProto::ANY), "any");
297    }
298
299    #[test]
300    fn test_protocol_display_unknown() {
301        let unknown = IpProto(200);
302        assert_eq!(format!("{}", unknown), "0xc8");
303    }
304
305    #[test]
306    fn test_protocol_from_u8() {
307        let proto = IpProto::from(6);
308        assert_eq!(proto, IpProto::TCP);
309
310        let proto = IpProto::from(17);
311        assert_eq!(proto, IpProto::UDP);
312    }
313
314    #[test]
315    fn test_protocol_into_u8() {
316        let value: u8 = IpProto::TCP.into();
317        assert_eq!(value, 6);
318
319        let value: u8 = IpProto::UDP.into();
320        assert_eq!(value, 17);
321    }
322
323    #[test]
324    fn test_protocol_equality() {
325        assert_eq!(IpProto::TCP, IpProto::TCP);
326        assert_ne!(IpProto::TCP, IpProto::UDP);
327        assert_eq!(IpProto::from(6), IpProto::TCP);
328    }
329
330    #[test]
331    fn test_protocol_is_valid() {
332        // Known protocols should be valid
333        assert!(IpProto::TCP.is_valid());
334        assert!(IpProto::UDP.is_valid());
335        assert!(IpProto::ICMP.is_valid());
336        assert!(IpProto::IPV6.is_valid());
337        assert!(IpProto::IPV6_HOPOPT.is_valid());
338        assert!(IpProto::IPV6_ROUTE.is_valid());
339        assert!(IpProto::IPV6_FRAG.is_valid());
340        assert!(IpProto::ANY.is_valid());
341
342        // Unknown protocols should be invalid
343        assert!(!IpProto::from(200).is_valid());
344        assert!(!IpProto::from(150).is_valid());
345        assert!(!IpProto::from(48).is_valid()); // Gap in protocol numbers
346        assert!(!IpProto::from(61).is_valid()); // Gap in protocol numbers
347        assert!(!IpProto::from(254).is_valid());
348    }
349}