packet_strata/packet/
iter.rs

1//! Packet header iterator for traversing protocol stack layers
2//!
3//!
4//! This module provides an iterator that traverses the headers of a network packet,
5//! parsing each layer from link layer through transport layer, including tunnel protocols.
6//!
7//! # Overview
8//!
9//! The [`PacketIter`] struct implements [`Iterator`] and yields [`Header`] enum variants
10//! for each successfully parsed protocol header. The iterator automatically determines
11//! the next protocol to parse based on the `inner_type()` of the current header.
12//!
13//! # Supported Protocols
14//!
15//! ## Link Layer
16//! - Ethernet II (with VLAN 802.1Q support)
17//! - Linux cooked capture (SLL, SLLv2)
18//! - BSD Null/Loopback (LINKTYPE_NULL)
19//! - Raw IPv4 (LINKTYPE_RAW with IPv4)
20//! - Raw IPv6 (LINKTYPE_RAW with IPv6)
21//!
22//! ## Network Layer
23//! - IPv4 (with options parsing)
24//! - IPv6 (with extension headers: Hop-by-Hop, Routing, Fragment, Destination, AH, ESP)
25//! - ARP (Address Resolution Protocol)
26//!
27//! ## Transport Layer
28//! - TCP (with options parsing: MSS, Window Scale, SACK, Timestamps, etc.)
29//! - UDP
30//! - SCTP (Stream Control Transmission Protocol)
31//! - ICMPv4
32//! - ICMPv6
33//!
34//! ## Tunnel Protocols
35//! - VXLAN (Virtual Extensible LAN, UDP port 4789)
36//! - Geneve (Generic Network Virtualization Encapsulation, UDP port 6081)
37//! - GRE (Generic Routing Encapsulation, IP protocol 47)
38//! - NVGRE (Network Virtualization using GRE, GRE with Key and TEB protocol)
39//! - MPLS (Multi-Protocol Label Switching, EtherType 0x8847/0x8848)
40//! - Teredo (IPv6 over UDP, UDP port 3544)
41//! - GTPv1-U (GPRS Tunneling Protocol User Plane, UDP port 2152)
42//! - GTPv1-C (GPRS Tunneling Protocol Control Plane, UDP port 2123)
43//! - GTPv2-C (GTPv2 Control Plane, UDP port 2123)
44//! - L2TPv2 (Layer 2 Tunneling Protocol v2, UDP port 1701)
45//! - L2TPv3 (Layer 2 Tunneling Protocol v3, IP protocol 115)
46//! - PBB (Provider Backbone Bridge, EtherType 0x88E7/0x88A8)
47//! - STT (Stateless Transport Tunneling, TCP port 7471)
48//! - PPTP (Point-to-Point Tunneling Protocol, Enhanced GRE version 1)
49//!
50//! ## IP-in-IP Tunnels
51//! - IPIP (IPv4-in-IPv4, IP protocol 4)
52//! - SIT/6in4 (IPv6-in-IPv4, IP protocol 41)
53//! - IP4in6 (IPv4-in-IPv6, IPv6 next header 4)
54//! - IP6Tnl (IPv6-in-IPv6, IPv6 next header 41)
55//!
56//! # Example
57//!
58//! ```
59//! use packet_strata::packet::iter::{PacketIter, Header, LinkType};
60//!
61//! // Example Ethernet + IPv4 + TCP packet
62//! let packet = vec![
63//!     // Ethernet header (14 bytes)
64//!     0x00, 0x11, 0x22, 0x33, 0x44, 0x55,  // Destination MAC
65//!     0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb,  // Source MAC
66//!     0x08, 0x00,                          // EtherType: IPv4
67//!     // IPv4 header (20 bytes, no options)
68//!     0x45, 0x00, 0x00, 0x28,              // Version, IHL, DSCP, Total Length
69//!     0x00, 0x00, 0x00, 0x00,              // ID, Flags, Fragment Offset
70//!     0x40, 0x06, 0x00, 0x00,              // TTL, Protocol (TCP), Checksum
71//!     0xc0, 0xa8, 0x01, 0x01,              // Source IP
72//!     0xc0, 0xa8, 0x01, 0x02,              // Destination IP
73//!     // TCP header (20 bytes, no options)
74//!     0x00, 0x50, 0x01, 0xbb,              // Src Port, Dst Port
75//!     0x00, 0x00, 0x00, 0x00,              // Sequence Number
76//!     0x00, 0x00, 0x00, 0x00,              // Acknowledgment Number
77//!     0x50, 0x02, 0x00, 0x00,              // Data Offset, Flags, Window
78//!     0x00, 0x00, 0x00, 0x00,              // Checksum, Urgent Pointer
79//! ];
80//!
81//! let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
82//!
83//! // First header should be Ethernet
84//! let first = iter.next().unwrap().unwrap();
85//! assert!(matches!(first, Header::Ethernet(_)));
86//!
87//! // Second header should be IPv4
88//! let second = iter.next().unwrap().unwrap();
89//! assert!(matches!(second, Header::Ipv4(_)));
90//!
91//! // Third header should be TCP
92//! let third = iter.next().unwrap().unwrap();
93//! assert!(matches!(third, Header::Tcp(_)));
94//!
95//! // No more headers
96//! assert!(iter.next().is_none());
97//! ```
98//!
99//! # Error Handling
100//!
101//! The iterator yields `Result<Header<'a>, PacketHeaderError>`. When parsing fails:
102//! - `Some(Err(e))` is returned with the error
103//! - The iterator becomes "fused" and subsequent calls return `None`
104//!
105//! # Unsupported Protocols
106//!
107//! When an unsupported protocol is encountered, the iterator returns `Header::Unknown`
108//! with the protocol identifier and remaining buffer, then terminates.
109
110use super::arp::ArpHeader;
111use super::detect::{
112    detect_gre_variant, detect_mpls_inner_protocol, detect_udp_tunnel, find_ipv6_upper_protocol,
113    is_stt_port, NextLayer, TunnelType,
114};
115use super::ether::EtherHeader;
116// Re-export Header and UnknownProto for API compatibility
117pub use super::header::{Header, UnknownProto};
118use super::icmp::IcmpHeader;
119use super::icmp6::Icmp6Header;
120use super::ipv4::Ipv4Header;
121use super::ipv6::Ipv6Header;
122use super::null::NullHeader;
123use super::protocol::{EtherProto, IpProto};
124use super::sctp::SctpHeader;
125use super::sll::{SllHeader, Sllv2Header};
126use super::tcp::TcpHeader;
127use super::tunnel::geneve::GeneveHeader;
128use super::tunnel::gre::GreHeader;
129use super::tunnel::gtpv1::Gtpv1Header;
130use super::tunnel::gtpv2::Gtpv2Header;
131use super::tunnel::ipip::IpipTunnel;
132use super::tunnel::l2tp::{L2tpv2Header, L2tpv3SessionHeader};
133use super::tunnel::mpls::MplsLabelStack;
134use super::tunnel::nvgre::NvgreHeader;
135use super::tunnel::pbb::PbbHeader;
136use super::tunnel::pptp::PptpGreHeader;
137use super::tunnel::stt::SttPacket;
138use super::tunnel::teredo::TeredoPacket;
139use super::tunnel::vxlan::VxlanHeader;
140use super::udp::UdpHeader;
141use super::{HeaderParser, PacketHeaderError};
142
143/// Link layer type for the packet capture
144///
145/// This determines what protocol to expect at the beginning of the packet.
146#[derive(Debug, Clone, Copy, PartialEq, Eq)]
147pub enum LinkType {
148    /// Standard Ethernet II frame
149    Ethernet,
150    /// Linux cooked capture v1 (SLL)
151    Sll,
152    /// Linux cooked capture v2 (SLLv2)
153    Sllv2,
154    /// BSD Null/Loopback encapsulation
155    Null,
156    /// Raw IPv4 (no link layer header)
157    RawIpv4,
158    /// Raw IPv6 (no link layer header)
159    RawIpv6,
160}
161
162/// Iterator over packet headers
163///
164/// Parses each protocol layer and yields [`Header`] variants.
165/// The iterator is fused after an error or when parsing is complete.
166pub struct PacketIter<'a> {
167    /// Remaining unparsed buffer
168    remaining: &'a [u8],
169    /// Next layer to parse
170    next_layer: NextLayer,
171    /// Whether the iterator is done (fused)
172    done: bool,
173    /// Track the last UDP header for tunnel detection
174    last_udp_ports: Option<(u16, u16)>,
175}
176
177impl<'a> PacketIter<'a> {
178    /// Create a new packet iterator
179    ///
180    /// # Arguments
181    ///
182    /// * `buf` - The packet buffer to parse
183    /// * `link_type` - The link layer type of the packet
184    ///
185    /// # Example
186    ///
187    /// ```
188    /// use packet_strata::packet::iter::{PacketIter, LinkType};
189    ///
190    /// let packet = vec![/* ... */];
191    /// let iter = PacketIter::new(&packet, LinkType::Ethernet);
192    /// ```
193    pub fn new(buf: &'a [u8], link_type: LinkType) -> Self {
194        Self {
195            remaining: buf,
196            next_layer: NextLayer::Link(link_type),
197            done: false,
198            last_udp_ports: None,
199        }
200    }
201
202    /// Guess the link type from raw packet bytes
203    ///
204    /// This is a super fast heuristic that examines a few bytes to determine
205    /// the most likely link layer type. It's designed for speed over accuracy.
206    ///
207    /// # Returns
208    ///
209    /// The guessed `LinkType`, defaulting to `Ethernet` if undetermined.
210    #[inline]
211    pub fn guess_link_type(buf: &[u8]) -> LinkType {
212        // Need at least 1 byte to check anything
213        if buf.is_empty() {
214            return LinkType::Ethernet;
215        }
216
217        // Fast path: Check for raw IP (most common in tunnels/VPNs)
218        // IPv4: version = 4 in high nibble (0x4X), IHL >= 5 in low nibble
219        // IPv6: version = 6 in high nibble (0x6X)
220        let first_byte = buf[0];
221        let version = first_byte >> 4;
222
223        if version == 4 {
224            // Likely IPv4: check IHL is valid (5-15)
225            let ihl = first_byte & 0x0F;
226            if (5..=15).contains(&ihl) {
227                return LinkType::RawIpv4;
228            }
229        } else if version == 6 {
230            // Likely IPv6
231            return LinkType::RawIpv6;
232        }
233
234        // Check for Null/Loopback (4 bytes AF_* in host byte order)
235        if buf.len() >= 4 {
236            let le_val = u32::from_le_bytes([buf[0], buf[1], buf[2], buf[3]]);
237            let be_val = u32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]);
238
239            // Valid AF_* values: 2 (INET), 10 (INET6 Linux), 24 (OpenBSD), 28 (FreeBSD), 30 (Darwin)
240            let is_valid_af = |v: u32| matches!(v, 2 | 10 | 24 | 28 | 30);
241
242            if is_valid_af(le_val) || is_valid_af(be_val) {
243                // Additional check: after the 4-byte header, should be IP
244                if buf.len() >= 5 {
245                    let next_version = buf[4] >> 4;
246                    if next_version == 4 || next_version == 6 {
247                        return LinkType::Null;
248                    }
249                }
250            }
251        }
252
253        // Check for Ethernet (14 byte header, EtherType at 12-13)
254        if buf.len() >= 14 {
255            let ether_type = u16::from_be_bytes([buf[12], buf[13]]);
256
257            // Common EtherTypes: IPv4 (0x0800), IPv6 (0x86DD), ARP (0x0806), VLAN (0x8100, 0x88A8)
258            // MPLS (0x8847, 0x8848), PPPoE (0x8863, 0x8864)
259            match ether_type {
260                0x0800 | 0x86DD | 0x0806 | 0x8100 | 0x88A8 | 0x8847 | 0x8848 | 0x8863 | 0x8864 => {
261                    return LinkType::Ethernet;
262                }
263                _ => {}
264            }
265        }
266
267        // Check for SLL (16 bytes) - packet type at 0-1 should be 0-4
268        if buf.len() >= 16 {
269            let packet_type = u16::from_be_bytes([buf[0], buf[1]]);
270            let protocol = u16::from_be_bytes([buf[14], buf[15]]);
271
272            // Packet type: 0=host, 1=broadcast, 2=multicast, 3=otherhost, 4=outgoing
273            // Protocol should be a valid EtherType
274            if packet_type <= 4 {
275                match protocol {
276                    0x0800 | 0x86DD | 0x0806 | 0x8100 => {
277                        return LinkType::Sll;
278                    }
279                    _ => {}
280                }
281            }
282        }
283
284        // Check for SLLv2 (20 bytes) - protocol at 0-1
285        if buf.len() >= 20 {
286            let protocol = u16::from_be_bytes([buf[0], buf[1]]);
287            let packet_type = buf[10]; // Packet type at byte 10
288
289            if packet_type <= 4 {
290                match protocol {
291                    0x0800 | 0x86DD | 0x0806 | 0x8100 => {
292                        return LinkType::Sllv2;
293                    }
294                    _ => {}
295                }
296            }
297        }
298
299        // Default to Ethernet (most common)
300        LinkType::Ethernet
301    }
302
303    /// Create a new packet iterator starting at the network layer
304    ///
305    /// Use this when you already know the EtherType/protocol and want
306    /// to skip link layer parsing.
307    ///
308    /// # Arguments
309    ///
310    /// * `buf` - The packet buffer to parse (starting at network layer)
311    /// * `ether_proto` - The EtherType indicating the network protocol
312    pub fn from_network_layer(buf: &'a [u8], ether_proto: EtherProto) -> Self {
313        Self {
314            remaining: buf,
315            next_layer: NextLayer::Network(ether_proto),
316            done: false,
317            last_udp_ports: None,
318        }
319    }
320
321    /// Create a new packet iterator starting at the transport layer
322    ///
323    /// Use this when you already know the IP protocol and want
324    /// to skip network layer parsing.
325    ///
326    /// # Arguments
327    ///
328    /// * `buf` - The packet buffer to parse (starting at transport layer)
329    /// * `ip_proto` - The IP protocol number
330    pub fn from_transport_layer(buf: &'a [u8], ip_proto: IpProto) -> Self {
331        Self {
332            remaining: buf,
333            next_layer: NextLayer::Transport(ip_proto),
334            done: false,
335            last_udp_ports: None,
336        }
337    }
338
339    /// Returns the remaining unparsed bytes
340    ///
341    /// This is the payload after all parsed headers.
342    pub fn remaining(&self) -> &'a [u8] {
343        self.remaining
344    }
345
346    /// Returns true if the iterator is done
347    pub fn is_done(&self) -> bool {
348        self.done
349    }
350
351    /// Parse link layer header
352    fn parse_link(&mut self, link_type: LinkType) -> Option<Result<Header<'a>, PacketHeaderError>> {
353        match link_type {
354            LinkType::Ethernet => match EtherHeader::from_bytes(self.remaining) {
355                Ok((eth, rest)) => {
356                    let next_proto = eth.inner_type();
357                    self.remaining = rest;
358                    self.next_layer = NextLayer::Network(next_proto);
359                    Some(Ok(Header::Ethernet(eth)))
360                }
361                Err(e) => {
362                    self.done = true;
363                    Some(Err(e))
364                }
365            },
366            LinkType::Sll => match SllHeader::from_bytes(self.remaining) {
367                Ok((sll, rest)) => {
368                    let next_proto = sll.protocol();
369                    self.remaining = rest;
370                    self.next_layer = NextLayer::Network(next_proto);
371                    Some(Ok(Header::Sll(sll)))
372                }
373                Err(e) => {
374                    self.done = true;
375                    Some(Err(e))
376                }
377            },
378            LinkType::Sllv2 => match Sllv2Header::from_bytes(self.remaining) {
379                Ok((sll, rest)) => {
380                    let next_proto = sll.protocol();
381                    self.remaining = rest;
382                    self.next_layer = NextLayer::Network(next_proto);
383                    Some(Ok(Header::Sllv2(sll)))
384                }
385                Err(e) => {
386                    self.done = true;
387                    Some(Err(e))
388                }
389            },
390            LinkType::Null => match NullHeader::from_bytes(self.remaining) {
391                Ok((null, rest)) => {
392                    let next_proto = null.protocol();
393                    self.remaining = rest;
394                    self.next_layer = NextLayer::Network(next_proto);
395                    Some(Ok(Header::Null(null)))
396                }
397                Err(e) => {
398                    self.done = true;
399                    Some(Err(e))
400                }
401            },
402            LinkType::RawIpv4 => {
403                self.next_layer = NextLayer::Network(EtherProto::IPV4);
404                self.next()
405            }
406            LinkType::RawIpv6 => {
407                self.next_layer = NextLayer::Network(EtherProto::IPV6);
408                self.next()
409            }
410        }
411    }
412
413    /// Parse network layer header
414    fn parse_network(
415        &mut self,
416        ether_proto: EtherProto,
417    ) -> Option<Result<Header<'a>, PacketHeaderError>> {
418        match ether_proto {
419            EtherProto::IPV4 => match Ipv4Header::from_bytes(self.remaining) {
420                Ok((ipv4, rest)) => {
421                    let proto = ipv4.protocol();
422                    self.remaining = rest;
423                    // Common case first: transport protocol (TCP, UDP, etc.)
424                    if proto != IpProto::IP_ENCAP && proto != IpProto::IPV6 {
425                        self.next_layer = NextLayer::Transport(proto);
426                        Some(Ok(Header::Ipv4(ipv4)))
427                    } else if proto == IpProto::IP_ENCAP {
428                        // Rare: IPv4-in-IPv4 tunnel
429                        self.next_layer = NextLayer::Network(EtherProto::IPV4);
430                        Some(Ok(Header::Ipip(IpipTunnel::ipip(ipv4))))
431                    } else {
432                        // Rare: IPv6-in-IPv4 (SIT) tunnel
433                        self.next_layer = NextLayer::Network(EtherProto::IPV6);
434                        Some(Ok(Header::Ipip(IpipTunnel::sit(ipv4))))
435                    }
436                }
437                Err(e) => {
438                    self.done = true;
439                    Some(Err(e))
440                }
441            },
442            EtherProto::IPV6 => match Ipv6Header::from_bytes(self.remaining) {
443                Ok((ipv6, rest)) => {
444                    // For IPv6, find the upper layer protocol
445                    // Fast path: no extension headers
446                    let next_proto = if ipv6.raw_extensions.is_empty() {
447                        ipv6.next_header()
448                    } else {
449                        find_ipv6_upper_protocol(&ipv6)
450                    };
451                    self.remaining = rest;
452                    // Common case first: transport protocol
453                    if next_proto != IpProto::IP_ENCAP && next_proto != IpProto::IPV6 {
454                        self.next_layer = NextLayer::Transport(next_proto);
455                        Some(Ok(Header::Ipv6(ipv6)))
456                    } else if next_proto == IpProto::IP_ENCAP {
457                        // Rare: IPv4-in-IPv6 (IP4in6) tunnel
458                        self.next_layer = NextLayer::Network(EtherProto::IPV4);
459                        Some(Ok(Header::Ipip(IpipTunnel::ip4in6(ipv6))))
460                    } else {
461                        // Rare: IPv6-in-IPv6 (IP6Tnl) tunnel
462                        self.next_layer = NextLayer::Network(EtherProto::IPV6);
463                        Some(Ok(Header::Ipip(IpipTunnel::ip6tnl(ipv6))))
464                    }
465                }
466                Err(e) => {
467                    self.done = true;
468                    Some(Err(e))
469                }
470            },
471            EtherProto::ARP => match ArpHeader::from_bytes(self.remaining) {
472                Ok((arp, rest)) => {
473                    self.remaining = rest;
474                    self.next_layer = NextLayer::Done;
475                    Some(Ok(Header::Arp(arp)))
476                }
477                Err(e) => {
478                    self.done = true;
479                    Some(Err(e))
480                }
481            },
482            EtherProto::MPLS_UC | EtherProto::MPLS_MC => {
483                // MPLS encapsulation
484                self.next_layer = NextLayer::Tunnel(TunnelType::Mpls);
485                self.next()
486            }
487            EtherProto::TEB => {
488                // Transparent Ethernet Bridging - inner Ethernet frame
489                self.next_layer = NextLayer::Link(LinkType::Ethernet);
490                self.next()
491            }
492            EtherProto::VLAN_8021AH | EtherProto::VLAN_8021AD => {
493                // PBB (Provider Backbone Bridge / MAC-in-MAC)
494                // 0x88E7 = I-Tag (802.1ah), 0x88A8 = B-Tag (802.1ad)
495                self.next_layer = NextLayer::Tunnel(TunnelType::Pbb);
496                self.next()
497            }
498            _ => {
499                // Unknown network protocol
500                let header = Header::Unknown {
501                    proto: UnknownProto::Ether(ether_proto),
502                    data: self.remaining,
503                };
504                self.remaining = &[];
505                self.done = true;
506                Some(Ok(header))
507            }
508        }
509    }
510
511    /// Parse transport layer header
512    fn parse_transport(
513        &mut self,
514        ip_proto: IpProto,
515    ) -> Option<Result<Header<'a>, PacketHeaderError>> {
516        match ip_proto {
517            IpProto::TCP => match TcpHeader::from_bytes(self.remaining) {
518                Ok((tcp, rest)) => {
519                    let src_port = tcp.src_port();
520                    let dst_port = tcp.dst_port();
521
522                    // Check for STT tunnel (TCP port 7471)
523                    if is_stt_port(dst_port) || is_stt_port(src_port) {
524                        self.next_layer = NextLayer::Tunnel(TunnelType::Stt);
525                    } else {
526                        self.next_layer = NextLayer::Done;
527                    }
528
529                    self.remaining = rest;
530                    Some(Ok(Header::Tcp(tcp)))
531                }
532                Err(e) => {
533                    self.done = true;
534                    Some(Err(e))
535                }
536            },
537            IpProto::UDP => match UdpHeader::from_bytes(self.remaining) {
538                Ok((udp, rest)) => {
539                    let src_port = udp.src_port();
540                    let dst_port = udp.dst_port();
541                    self.last_udp_ports = Some((src_port, dst_port));
542
543                    // Check for tunnel protocols based on UDP ports
544                    if let Some(tunnel_type) = detect_udp_tunnel(src_port, dst_port, rest) {
545                        self.remaining = rest;
546                        self.next_layer = NextLayer::Tunnel(tunnel_type);
547                    } else {
548                        self.remaining = rest;
549                        self.next_layer = NextLayer::Done;
550                    }
551                    Some(Ok(Header::Udp(udp)))
552                }
553                Err(e) => {
554                    self.done = true;
555                    Some(Err(e))
556                }
557            },
558            IpProto::SCTP => match SctpHeader::from_bytes(self.remaining) {
559                Ok((sctp, rest)) => {
560                    self.remaining = rest;
561                    self.next_layer = NextLayer::Done;
562                    Some(Ok(Header::Sctp(sctp)))
563                }
564                Err(e) => {
565                    self.done = true;
566                    Some(Err(e))
567                }
568            },
569            IpProto::ICMP => match IcmpHeader::from_bytes(self.remaining) {
570                Ok((icmp, rest)) => {
571                    self.remaining = rest;
572                    self.next_layer = NextLayer::Done;
573                    Some(Ok(Header::Icmp(icmp)))
574                }
575                Err(e) => {
576                    self.done = true;
577                    Some(Err(e))
578                }
579            },
580            IpProto::ICMP6 => match Icmp6Header::from_bytes(self.remaining) {
581                Ok((icmp6, rest)) => {
582                    self.remaining = rest;
583                    self.next_layer = NextLayer::Done;
584                    Some(Ok(Header::Icmp6(icmp6)))
585                }
586                Err(e) => {
587                    self.done = true;
588                    Some(Err(e))
589                }
590            },
591            IpProto::GRE => {
592                // GRE tunnel - detect specific variant (PPTP, NVGRE, or standard GRE)
593                let tunnel_type = detect_gre_variant(self.remaining);
594                self.next_layer = NextLayer::Tunnel(tunnel_type);
595                self.next()
596            }
597            IpProto::L2TP => {
598                // L2TPv3 over IP (protocol 115)
599                self.next_layer = NextLayer::Tunnel(TunnelType::L2tpv3);
600                self.next()
601            }
602
603            IpProto::IPV6_NONXT => {
604                // No next header - we're done
605                self.next_layer = NextLayer::Done;
606                self.done = true;
607                None
608            }
609            _ => {
610                // Unknown transport protocol
611                let header = Header::Unknown {
612                    proto: UnknownProto::Ip(ip_proto),
613                    data: self.remaining,
614                };
615                self.remaining = &[];
616                self.done = true;
617                Some(Ok(header))
618            }
619        }
620    }
621
622    /// Parse tunnel header
623    fn parse_tunnel(
624        &mut self,
625        tunnel_type: TunnelType,
626    ) -> Option<Result<Header<'a>, PacketHeaderError>> {
627        match tunnel_type {
628            TunnelType::Vxlan => match VxlanHeader::from_bytes(self.remaining) {
629                Ok((vxlan, rest)) => {
630                    self.remaining = rest;
631                    // VXLAN always encapsulates Ethernet
632                    self.next_layer = NextLayer::Link(LinkType::Ethernet);
633                    Some(Ok(Header::Vxlan(vxlan)))
634                }
635                Err(e) => {
636                    self.done = true;
637                    Some(Err(e))
638                }
639            },
640            TunnelType::Geneve => match GeneveHeader::from_bytes(self.remaining) {
641                Ok((geneve, rest)) => {
642                    // Determine next protocol based on Geneve protocol type
643                    let inner_proto = geneve.protocol_type();
644                    self.remaining = rest;
645                    self.next_layer = NextLayer::Network(inner_proto);
646                    Some(Ok(Header::Geneve(geneve)))
647                }
648                Err(e) => {
649                    self.done = true;
650                    Some(Err(e))
651                }
652            },
653            TunnelType::Gre => match GreHeader::from_bytes(self.remaining) {
654                Ok((gre, rest)) => {
655                    let inner_proto = gre.protocol_type();
656                    self.remaining = rest;
657
658                    // Check if this is NVGRE (Ethernet over GRE) or standard GRE
659                    if inner_proto == EtherProto::TEB {
660                        self.next_layer = NextLayer::Link(LinkType::Ethernet);
661                    } else {
662                        self.next_layer = NextLayer::Network(inner_proto);
663                    }
664                    Some(Ok(Header::Gre(gre)))
665                }
666                Err(e) => {
667                    self.done = true;
668                    Some(Err(e))
669                }
670            },
671            TunnelType::Mpls => {
672                // Parse MPLS label stack
673                match MplsLabelStack::parse(self.remaining) {
674                    Some((mpls_stack, payload)) => {
675                        self.remaining = payload;
676
677                        // Determine inner protocol based on first nibble after MPLS
678                        if let Some(next) = detect_mpls_inner_protocol(payload) {
679                            self.next_layer = next;
680                        } else {
681                            self.next_layer = NextLayer::Done;
682                        }
683                        Some(Ok(Header::Mpls(mpls_stack)))
684                    }
685                    None => {
686                        self.done = true;
687                        Some(Err(PacketHeaderError::TooShort("MPLS")))
688                    }
689                }
690            }
691            TunnelType::Teredo => {
692                // Parse Teredo packet (may include auth/origin indicators + IPv6)
693                match TeredoPacket::parse(self.remaining) {
694                    Ok(teredo) => {
695                        // The payload is IPv6
696                        self.remaining = teredo.ipv6_payload();
697                        self.next_layer = NextLayer::Network(EtherProto::IPV6);
698                        Some(Ok(Header::Teredo(Box::new(teredo))))
699                    }
700                    Err(e) => {
701                        self.done = true;
702                        Some(Err(e))
703                    }
704                }
705            }
706            TunnelType::Gtpv1 => match Gtpv1Header::from_bytes(self.remaining) {
707                Ok((gtpv1, rest)) => {
708                    self.remaining = rest;
709
710                    // Check if this is a G-PDU (user data) with encapsulated IP
711                    if gtpv1.is_gpdu() && !rest.is_empty() {
712                        // Detect inner IP version from first nibble
713                        let version = (rest[0] & 0xF0) >> 4;
714                        match version {
715                            4 => self.next_layer = NextLayer::Network(EtherProto::IPV4),
716                            6 => self.next_layer = NextLayer::Network(EtherProto::IPV6),
717                            _ => self.next_layer = NextLayer::Done,
718                        }
719                    } else {
720                        // Control plane message - no further parsing
721                        self.next_layer = NextLayer::Done;
722                    }
723                    Some(Ok(Header::Gtpv1(gtpv1)))
724                }
725                Err(e) => {
726                    self.done = true;
727                    Some(Err(e))
728                }
729            },
730            TunnelType::Gtpv2 => match Gtpv2Header::from_bytes(self.remaining) {
731                Ok((gtpv2, rest)) => {
732                    self.remaining = rest;
733                    // GTPv2 is control plane only - no encapsulated user data
734                    self.next_layer = NextLayer::Done;
735                    Some(Ok(Header::Gtpv2(gtpv2)))
736                }
737                Err(e) => {
738                    self.done = true;
739                    Some(Err(e))
740                }
741            },
742            TunnelType::L2tpv2 => match L2tpv2Header::from_bytes(self.remaining) {
743                Ok((l2tpv2, rest)) => {
744                    self.remaining = rest;
745                    // L2TPv2 data messages encapsulate PPP frames
746                    // Control messages don't have inner payload to parse
747                    // For now, we stop parsing as PPP parsing is not implemented
748                    self.next_layer = NextLayer::Done;
749                    Some(Ok(Header::L2tpv2(l2tpv2)))
750                }
751                Err(e) => {
752                    self.done = true;
753                    Some(Err(e))
754                }
755            },
756            TunnelType::L2tpv3 => {
757                // L2TPv3 over IP - parse session header with no cookie (default)
758                // Cookie length is negotiated out-of-band, so we use 0 as default
759                match L2tpv3SessionHeader::parse_with_cookie_len(self.remaining, 0) {
760                    Ok((l2tpv3, rest)) => {
761                        self.remaining = rest;
762                        // L2TPv3 can encapsulate various L2 protocols
763                        // Most commonly Ethernet
764                        if !rest.is_empty() {
765                            // Try to detect inner protocol from first nibble
766                            let first_byte = rest[0];
767                            if first_byte == 0x00 || (first_byte & 0xF0) == 0x00 {
768                                // Likely Ethernet (starts with destination MAC)
769                                self.next_layer = NextLayer::Link(LinkType::Ethernet);
770                            } else {
771                                self.next_layer = NextLayer::Done;
772                            }
773                        } else {
774                            self.next_layer = NextLayer::Done;
775                        }
776                        Some(Ok(Header::L2tpv3(l2tpv3)))
777                    }
778                    Err(e) => {
779                        self.done = true;
780                        Some(Err(e))
781                    }
782                }
783            }
784            TunnelType::Nvgre => match NvgreHeader::from_bytes(self.remaining) {
785                Ok((nvgre, rest)) => {
786                    self.remaining = rest;
787                    // NVGRE always encapsulates Ethernet (TEB)
788                    self.next_layer = NextLayer::Link(LinkType::Ethernet);
789                    Some(Ok(Header::Nvgre(nvgre)))
790                }
791                Err(e) => {
792                    self.done = true;
793                    Some(Err(e))
794                }
795            },
796            TunnelType::Pbb => {
797                // Parse PBB (Provider Backbone Bridge) header
798                match PbbHeader::parse(self.remaining) {
799                    Ok((pbb, rest)) => {
800                        self.remaining = rest;
801                        // PBB encapsulates customer Ethernet frames
802                        self.next_layer = NextLayer::Link(LinkType::Ethernet);
803                        Some(Ok(Header::Pbb(pbb)))
804                    }
805                    Err(e) => {
806                        self.done = true;
807                        Some(Err(e))
808                    }
809                }
810            }
811            TunnelType::Stt => {
812                // Parse STT packet (includes TCP-like header + STT frame header)
813                match SttPacket::parse(self.remaining) {
814                    Some(stt) => {
815                        self.remaining = stt.payload;
816                        // STT encapsulates Ethernet frames
817                        self.next_layer = NextLayer::Link(LinkType::Ethernet);
818                        Some(Ok(Header::Stt(stt)))
819                    }
820                    None => {
821                        self.done = true;
822                        Some(Err(PacketHeaderError::TooShort("STT")))
823                    }
824                }
825            }
826            TunnelType::Pptp => match PptpGreHeader::from_bytes(self.remaining) {
827                Ok((pptp, rest)) => {
828                    self.remaining = rest;
829                    // PPTP encapsulates PPP frames
830                    // PPP parsing is not implemented, so we stop here
831                    self.next_layer = NextLayer::Done;
832                    Some(Ok(Header::Pptp(pptp)))
833                }
834                Err(e) => {
835                    self.done = true;
836                    Some(Err(e))
837                }
838            },
839        }
840    }
841}
842
843impl<'a> Iterator for PacketIter<'a> {
844    type Item = Result<Header<'a>, PacketHeaderError>;
845
846    #[inline(always)]
847    fn next(&mut self) -> Option<Self::Item> {
848        if self.done {
849            return None;
850        }
851
852        if self.remaining.is_empty() {
853            self.done = true;
854            return None;
855        }
856
857        match self.next_layer {
858            NextLayer::Link(link_type) => self.parse_link(link_type),
859            NextLayer::Network(ether_proto) => self.parse_network(ether_proto),
860            NextLayer::Transport(ip_proto) => self.parse_transport(ip_proto),
861            NextLayer::Tunnel(tunnel_type) => self.parse_tunnel(tunnel_type),
862            NextLayer::Done => {
863                self.done = true;
864                None
865            }
866        }
867    }
868}
869
870/// Extension trait to create a packet iterator from a buffer
871pub trait PacketIterExt {
872    /// Create an iterator over packet headers
873    fn headers(&self, link_type: LinkType) -> PacketIter<'_>;
874}
875
876impl PacketIterExt for [u8] {
877    fn headers(&self, link_type: LinkType) -> PacketIter<'_> {
878        PacketIter::new(self, link_type)
879    }
880}
881
882/// Collect all headers from a packet into a Vec
883///
884/// This is a convenience function that collects all headers, stopping at the first error.
885///
886/// # Returns
887///
888/// - `Ok(headers)` - All headers were parsed successfully
889/// - `Err(e)` - An error occurred during parsing
890///
891/// # Example
892///
893/// ```
894/// use packet_strata::packet::iter::{collect_headers, LinkType};
895///
896/// let packet = vec![/* ... */];
897/// match collect_headers(&packet, LinkType::Ethernet) {
898///     Ok(headers) => {
899///         for header in headers {
900///             println!("{}", header);
901///         }
902///     }
903///     Err(e) => eprintln!("Parse error: {}", e),
904/// }
905/// ```
906pub fn collect_headers(
907    buf: &[u8],
908    link_type: LinkType,
909) -> Result<Vec<Header<'_>>, PacketHeaderError> {
910    let mut headers = Vec::new();
911    for result in PacketIter::new(buf, link_type) {
912        headers.push(result?);
913    }
914    Ok(headers)
915}
916
917#[cfg(test)]
918mod tests {
919    use super::*;
920    use std::mem::size_of;
921
922    #[test]
923    fn test_structure_sizes() {
924        use crate::packet::arp::ArpHeaderFull;
925        use crate::packet::ether::EtherHeaderVlan;
926        use crate::packet::ipv4::Ipv4HeaderOpt;
927        use crate::packet::ipv6::Ipv6HeaderExt;
928        use crate::packet::tcp::TcpHeaderOpt;
929        use crate::packet::tunnel::geneve::GeneveHeaderOpt;
930        use crate::packet::tunnel::gre::GreHeaderOpt;
931        use crate::packet::tunnel::gtpv1::Gtpv1HeaderOpt;
932        use crate::packet::tunnel::gtpv2::Gtpv2HeaderOpt;
933        use crate::packet::tunnel::ipip::IpipTunnel;
934        use crate::packet::tunnel::l2tp::{L2tpv2HeaderOpt, L2tpv3SessionHeaderCookie};
935        use crate::packet::tunnel::mpls::MplsLabelStack;
936        use crate::packet::tunnel::pbb::PbbHeader;
937        use crate::packet::tunnel::pptp::PptpGreHeaderOpt;
938        use crate::packet::tunnel::stt::SttPacket;
939        use crate::packet::tunnel::teredo::TeredoPacket;
940
941        println!("\n=== Structure Sizes ===");
942        println!("PacketIter: {} bytes", size_of::<PacketIter>());
943        println!("NextLayer: {} bytes", size_of::<NextLayer>());
944        println!("TunnelType: {} bytes", size_of::<TunnelType>());
945        println!("Header: {} bytes", size_of::<Header>());
946        println!(
947            "Option<Result<Header, PacketHeaderError>>: {} bytes",
948            size_of::<Option<Result<Header, crate::packet::PacketHeaderError>>>()
949        );
950        println!("&[u8]: {} bytes", size_of::<&[u8]>());
951        println!("EtherProto: {} bytes", size_of::<EtherProto>());
952        println!("IpProto: {} bytes", size_of::<IpProto>());
953
954        println!("\n=== Potential Optimization ===");
955        println!(
956            "Box<TeredoPacket>: {} bytes",
957            size_of::<Box<TeredoPacket>>()
958        );
959        println!("Box<IpipTunnel>: {} bytes", size_of::<Box<IpipTunnel>>());
960        println!("If we Box Teredo, Header would be ~40 bytes (IpipTunnel is largest)");
961        println!("If we Box both Teredo and IpipTunnel, Header would be ~32 bytes (MplsLabelStack/EtherHeaderVlan)");
962
963        println!("\n=== Header Variant Inner Types (sorted by size) ===");
964        println!("\n=== Header Variant Inner Types (sorted by size) ===");
965        println!(
966            "TeredoPacket: {} bytes  <-- LARGEST, causes Header to be 104 bytes!",
967            size_of::<TeredoPacket>()
968        );
969        println!(
970            "IpipTunnel: {} bytes  <-- second largest",
971            size_of::<IpipTunnel>()
972        );
973        println!("SttPacket: {} bytes", size_of::<SttPacket>());
974        println!("MplsLabelStack: {} bytes", size_of::<MplsLabelStack>());
975        println!("EtherHeaderVlan: {} bytes", size_of::<EtherHeaderVlan>());
976        println!("Ipv4HeaderOpt: {} bytes", size_of::<Ipv4HeaderOpt>());
977        println!("Ipv6HeaderExt: {} bytes", size_of::<Ipv6HeaderExt>());
978        println!("ArpHeaderFull: {} bytes", size_of::<ArpHeaderFull>());
979        println!("TcpHeaderOpt: {} bytes", size_of::<TcpHeaderOpt>());
980        println!("GeneveHeaderOpt: {} bytes", size_of::<GeneveHeaderOpt>());
981        println!("GreHeaderOpt: {} bytes", size_of::<GreHeaderOpt>());
982        println!("Gtpv1HeaderOpt: {} bytes", size_of::<Gtpv1HeaderOpt>());
983        println!("Gtpv2HeaderOpt: {} bytes", size_of::<Gtpv2HeaderOpt>());
984        println!("L2tpv2HeaderOpt: {} bytes", size_of::<L2tpv2HeaderOpt>());
985        println!(
986            "L2tpv3SessionHeaderCookie: {} bytes",
987            size_of::<L2tpv3SessionHeaderCookie>()
988        );
989        println!("PptpGreHeaderOpt: {} bytes", size_of::<PptpGreHeaderOpt>());
990        println!("PbbHeader: {} bytes", size_of::<PbbHeader>());
991
992        println!("\n=== Summary ===");
993        println!(
994            "Current Header size: {} bytes (dominated by TeredoPacket)",
995            size_of::<Header>()
996        );
997        println!("Most common headers (Ethernet+IPv4+TCP) are only 24-32 bytes each");
998        println!(
999            "Every iteration copies {} bytes even for simple TCP packets!",
1000            size_of::<Header>()
1001        );
1002        println!("========================\n");
1003    }
1004
1005    /// Create a minimal Ethernet + IPv4 + TCP packet for testing
1006    fn create_eth_ipv4_tcp_packet() -> Vec<u8> {
1007        let mut packet = Vec::new();
1008
1009        // Ethernet header (14 bytes)
1010        packet.extend_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]); // Dest MAC
1011        packet.extend_from_slice(&[0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb]); // Src MAC
1012        packet.extend_from_slice(&[0x08, 0x00]); // EtherType: IPv4
1013
1014        // IPv4 header (20 bytes, no options)
1015        packet.push(0x45); // Version 4, IHL 5
1016        packet.push(0x00); // DSCP, ECN
1017        packet.extend_from_slice(&40u16.to_be_bytes()); // Total length (20 + 20)
1018        packet.extend_from_slice(&[0x00, 0x00]); // ID
1019        packet.extend_from_slice(&[0x00, 0x00]); // Flags, Fragment offset
1020        packet.push(64); // TTL
1021        packet.push(6); // Protocol: TCP
1022        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1023        packet.extend_from_slice(&[192, 168, 1, 1]); // Src IP
1024        packet.extend_from_slice(&[192, 168, 1, 2]); // Dst IP
1025
1026        // TCP header (20 bytes, no options)
1027        packet.extend_from_slice(&80u16.to_be_bytes()); // Src port
1028        packet.extend_from_slice(&443u16.to_be_bytes()); // Dst port
1029        packet.extend_from_slice(&[0x00, 0x00, 0x00, 0x01]); // Seq num
1030        packet.extend_from_slice(&[0x00, 0x00, 0x00, 0x00]); // Ack num
1031        packet.push(0x50); // Data offset (5 << 4)
1032        packet.push(0x02); // Flags (SYN)
1033        packet.extend_from_slice(&[0x00, 0x00]); // Window
1034        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1035        packet.extend_from_slice(&[0x00, 0x00]); // Urgent pointer
1036
1037        packet
1038    }
1039
1040    /// Create a minimal Ethernet + IPv4 + UDP packet for testing
1041    fn create_eth_ipv4_udp_packet() -> Vec<u8> {
1042        let mut packet = Vec::new();
1043
1044        // Ethernet header (14 bytes)
1045        packet.extend_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]); // Dest MAC
1046        packet.extend_from_slice(&[0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb]); // Src MAC
1047        packet.extend_from_slice(&[0x08, 0x00]); // EtherType: IPv4
1048
1049        // IPv4 header (20 bytes)
1050        packet.push(0x45); // Version 4, IHL 5
1051        packet.push(0x00); // DSCP, ECN
1052        packet.extend_from_slice(&28u16.to_be_bytes()); // Total length (20 + 8)
1053        packet.extend_from_slice(&[0x00, 0x00]); // ID
1054        packet.extend_from_slice(&[0x00, 0x00]); // Flags, Fragment offset
1055        packet.push(64); // TTL
1056        packet.push(17); // Protocol: UDP
1057        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1058        packet.extend_from_slice(&[10, 0, 0, 1]); // Src IP
1059        packet.extend_from_slice(&[10, 0, 0, 2]); // Dst IP
1060
1061        // UDP header (8 bytes)
1062        packet.extend_from_slice(&53u16.to_be_bytes()); // Src port
1063        packet.extend_from_slice(&53u16.to_be_bytes()); // Dst port
1064        packet.extend_from_slice(&8u16.to_be_bytes()); // Length
1065        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1066
1067        packet
1068    }
1069
1070    /// Create a minimal Ethernet + ARP packet for testing
1071    fn create_eth_arp_packet() -> Vec<u8> {
1072        let mut packet = Vec::new();
1073
1074        // Ethernet header (14 bytes)
1075        packet.extend_from_slice(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); // Dest MAC (broadcast)
1076        packet.extend_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]); // Src MAC
1077        packet.extend_from_slice(&[0x08, 0x06]); // EtherType: ARP
1078
1079        // ARP header (28 bytes for Ethernet/IPv4)
1080        packet.extend_from_slice(&1u16.to_be_bytes()); // Hardware type: Ethernet
1081        packet.extend_from_slice(&0x0800u16.to_be_bytes()); // Protocol type: IPv4
1082        packet.push(6); // Hardware addr len
1083        packet.push(4); // Protocol addr len
1084        packet.extend_from_slice(&1u16.to_be_bytes()); // Operation: Request
1085
1086        // Sender hardware address
1087        packet.extend_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]);
1088        // Sender protocol address
1089        packet.extend_from_slice(&[192, 168, 1, 1]);
1090        // Target hardware address
1091        packet.extend_from_slice(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
1092        // Target protocol address
1093        packet.extend_from_slice(&[192, 168, 1, 2]);
1094
1095        packet
1096    }
1097
1098    #[test]
1099    fn test_eth_ipv4_tcp_iteration() {
1100        let packet = create_eth_ipv4_tcp_packet();
1101        let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
1102
1103        // First: Ethernet
1104        let header = iter.next().unwrap().unwrap();
1105        assert!(matches!(header, Header::Ethernet(_)));
1106        assert_eq!(header.name(), "Ethernet");
1107        assert!(header.is_link_layer());
1108
1109        // Second: IPv4
1110        let header = iter.next().unwrap().unwrap();
1111        assert!(matches!(header, Header::Ipv4(_)));
1112        assert_eq!(header.name(), "IPv4");
1113        assert!(header.is_network_layer());
1114
1115        // Third: TCP
1116        let header = iter.next().unwrap().unwrap();
1117        assert!(matches!(header, Header::Tcp(_)));
1118        assert_eq!(header.name(), "TCP");
1119        assert!(header.is_transport_layer());
1120
1121        // Done
1122        assert!(iter.next().is_none());
1123        assert!(iter.is_done());
1124    }
1125
1126    #[test]
1127    fn test_eth_ipv4_udp_iteration() {
1128        let packet = create_eth_ipv4_udp_packet();
1129        let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
1130
1131        // Ethernet
1132        let header = iter.next().unwrap().unwrap();
1133        assert!(matches!(header, Header::Ethernet(_)));
1134
1135        // IPv4
1136        let header = iter.next().unwrap().unwrap();
1137        assert!(matches!(header, Header::Ipv4(_)));
1138
1139        // UDP
1140        let header = iter.next().unwrap().unwrap();
1141        assert!(matches!(header, Header::Udp(_)));
1142
1143        // Done
1144        assert!(iter.next().is_none());
1145    }
1146
1147    #[test]
1148    fn test_eth_arp_iteration() {
1149        let packet = create_eth_arp_packet();
1150        let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
1151
1152        // Ethernet
1153        let header = iter.next().unwrap().unwrap();
1154        assert!(matches!(header, Header::Ethernet(_)));
1155
1156        // ARP
1157        let header = iter.next().unwrap().unwrap();
1158        assert!(matches!(header, Header::Arp(_)));
1159
1160        // Done (ARP is terminal)
1161        assert!(iter.next().is_none());
1162    }
1163
1164    #[test]
1165    fn test_raw_ipv4_iteration() {
1166        let packet = create_eth_ipv4_tcp_packet();
1167        // Skip Ethernet header (14 bytes) to get raw IPv4
1168        let ipv4_packet = &packet[14..];
1169
1170        let mut iter = PacketIter::new(ipv4_packet, LinkType::RawIpv4);
1171
1172        // IPv4
1173        let header = iter.next().unwrap().unwrap();
1174        assert!(matches!(header, Header::Ipv4(_)));
1175
1176        // TCP
1177        let header = iter.next().unwrap().unwrap();
1178        assert!(matches!(header, Header::Tcp(_)));
1179
1180        // Done
1181        assert!(iter.next().is_none());
1182    }
1183
1184    #[test]
1185    fn test_null_loopback_ipv4_iteration() {
1186        // Null/Loopback header (4 bytes) + IPv4 + TCP
1187        let mut packet = Vec::new();
1188
1189        // Null header: AF_INET = 2 (little-endian)
1190        packet.extend_from_slice(&[0x02, 0x00, 0x00, 0x00]);
1191
1192        // IPv4 header (20 bytes)
1193        packet.push(0x45); // Version 4, IHL 5
1194        packet.push(0x00); // DSCP, ECN
1195        packet.extend_from_slice(&40u16.to_be_bytes()); // Total length
1196        packet.extend_from_slice(&[0x00, 0x00]); // ID
1197        packet.extend_from_slice(&[0x00, 0x00]); // Flags, Fragment offset
1198        packet.push(64); // TTL
1199        packet.push(6); // Protocol: TCP
1200        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1201        packet.extend_from_slice(&[127, 0, 0, 1]); // Src IP (localhost)
1202        packet.extend_from_slice(&[127, 0, 0, 1]); // Dst IP (localhost)
1203
1204        // TCP header (20 bytes)
1205        packet.extend_from_slice(&8080u16.to_be_bytes()); // Src port
1206        packet.extend_from_slice(&80u16.to_be_bytes()); // Dst port
1207        packet.extend_from_slice(&[0x00, 0x00, 0x00, 0x01]); // Seq num
1208        packet.extend_from_slice(&[0x00, 0x00, 0x00, 0x00]); // Ack num
1209        packet.push(0x50); // Data offset (5 words)
1210        packet.push(0x02); // Flags: SYN
1211        packet.extend_from_slice(&[0x00, 0x00]); // Window
1212        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1213        packet.extend_from_slice(&[0x00, 0x00]); // Urgent pointer
1214
1215        let mut iter = PacketIter::new(&packet, LinkType::Null);
1216
1217        // Null header
1218        let header = iter.next().unwrap().unwrap();
1219        assert!(matches!(header, Header::Null(_)));
1220        assert_eq!(header.name(), "Null/Loopback");
1221
1222        // IPv4
1223        let header = iter.next().unwrap().unwrap();
1224        assert!(matches!(header, Header::Ipv4(_)));
1225
1226        // TCP
1227        let header = iter.next().unwrap().unwrap();
1228        assert!(matches!(header, Header::Tcp(_)));
1229
1230        // Done
1231        assert!(iter.next().is_none());
1232    }
1233
1234    #[test]
1235    fn test_null_loopback_ipv6_iteration() {
1236        // Null/Loopback header (4 bytes) + IPv6 + UDP
1237        let mut packet = Vec::new();
1238
1239        // Null header: AF_INET6 = 30 on macOS (little-endian)
1240        packet.extend_from_slice(&[0x1e, 0x00, 0x00, 0x00]);
1241
1242        // IPv6 header (40 bytes)
1243        packet.push(0x60); // Version 6
1244        packet.extend_from_slice(&[0x00, 0x00, 0x00]); // Traffic class, Flow label
1245        packet.extend_from_slice(&8u16.to_be_bytes()); // Payload length
1246        packet.push(17); // Next header: UDP
1247        packet.push(64); // Hop limit
1248                         // Source address (::1)
1249        packet.extend_from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
1250        // Destination address (::1)
1251        packet.extend_from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
1252
1253        // UDP header (8 bytes)
1254        packet.extend_from_slice(&53u16.to_be_bytes()); // Src port
1255        packet.extend_from_slice(&53u16.to_be_bytes()); // Dst port
1256        packet.extend_from_slice(&8u16.to_be_bytes()); // Length
1257        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1258
1259        let mut iter = PacketIter::new(&packet, LinkType::Null);
1260
1261        // Null header
1262        let header = iter.next().unwrap().unwrap();
1263        assert!(matches!(header, Header::Null(_)));
1264
1265        // IPv6
1266        let header = iter.next().unwrap().unwrap();
1267        assert!(matches!(header, Header::Ipv6(_)));
1268
1269        // UDP
1270        let header = iter.next().unwrap().unwrap();
1271        assert!(matches!(header, Header::Udp(_)));
1272
1273        // Done
1274        assert!(iter.next().is_none());
1275    }
1276
1277    #[test]
1278    fn test_from_network_layer() {
1279        let packet = create_eth_ipv4_tcp_packet();
1280        // Skip Ethernet header (14 bytes)
1281        let ipv4_packet = &packet[14..];
1282
1283        let mut iter = PacketIter::from_network_layer(ipv4_packet, EtherProto::IPV4);
1284
1285        // IPv4
1286        let header = iter.next().unwrap().unwrap();
1287        assert!(matches!(header, Header::Ipv4(_)));
1288
1289        // TCP
1290        let header = iter.next().unwrap().unwrap();
1291        assert!(matches!(header, Header::Tcp(_)));
1292
1293        // Done
1294        assert!(iter.next().is_none());
1295    }
1296
1297    #[test]
1298    fn test_from_transport_layer() {
1299        let packet = create_eth_ipv4_tcp_packet();
1300        // Skip Ethernet (14) + IPv4 (20) headers
1301        let tcp_packet = &packet[34..];
1302
1303        let mut iter = PacketIter::from_transport_layer(tcp_packet, IpProto::TCP);
1304
1305        // TCP
1306        let header = iter.next().unwrap().unwrap();
1307        assert!(matches!(header, Header::Tcp(_)));
1308
1309        // Done
1310        assert!(iter.next().is_none());
1311    }
1312
1313    #[test]
1314    fn test_remaining_payload() {
1315        let mut packet = create_eth_ipv4_tcp_packet();
1316        // Add some payload
1317        packet.extend_from_slice(b"Hello, World!");
1318
1319        let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
1320
1321        // Consume all headers
1322        while iter.next().is_some() {}
1323
1324        // Check remaining payload
1325        assert_eq!(iter.remaining(), b"Hello, World!");
1326    }
1327
1328    #[test]
1329    fn test_error_on_short_buffer() {
1330        let packet = vec![0u8; 5]; // Too short for any header
1331
1332        let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
1333
1334        let result = iter.next().unwrap();
1335        assert!(result.is_err());
1336
1337        // Iterator should be fused
1338        assert!(iter.is_done());
1339        assert!(iter.next().is_none());
1340    }
1341
1342    #[test]
1343    fn test_unknown_ether_proto() {
1344        let mut packet = Vec::new();
1345
1346        // Ethernet header with unknown EtherType
1347        packet.extend_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]); // Dest MAC
1348        packet.extend_from_slice(&[0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb]); // Src MAC
1349        packet.extend_from_slice(&[0x99, 0x99]); // Unknown EtherType
1350
1351        // Some payload
1352        packet.extend_from_slice(b"unknown protocol data");
1353
1354        let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
1355
1356        // Ethernet
1357        let header = iter.next().unwrap().unwrap();
1358        assert!(matches!(header, Header::Ethernet(_)));
1359
1360        // Unknown
1361        let header = iter.next().unwrap().unwrap();
1362        assert!(header.is_unknown());
1363        if let Header::Unknown { proto, data } = header {
1364            assert!(matches!(proto, UnknownProto::Ether(_)));
1365            assert_eq!(data, b"unknown protocol data");
1366        }
1367
1368        // Done
1369        assert!(iter.next().is_none());
1370    }
1371
1372    #[test]
1373    fn test_unknown_ip_proto() {
1374        let mut packet = Vec::new();
1375
1376        // Ethernet header
1377        packet.extend_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]); // Dest MAC
1378        packet.extend_from_slice(&[0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb]); // Src MAC
1379        packet.extend_from_slice(&[0x08, 0x00]); // EtherType: IPv4
1380
1381        // IPv4 header with unknown protocol
1382        packet.push(0x45); // Version 4, IHL 5
1383        packet.push(0x00); // DSCP, ECN
1384        packet.extend_from_slice(&30u16.to_be_bytes()); // Total length
1385        packet.extend_from_slice(&[0x00, 0x00]); // ID
1386        packet.extend_from_slice(&[0x00, 0x00]); // Flags, Fragment offset
1387        packet.push(64); // TTL
1388        packet.push(200); // Protocol: Unknown (200)
1389        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1390        packet.extend_from_slice(&[192, 168, 1, 1]); // Src IP
1391        packet.extend_from_slice(&[192, 168, 1, 2]); // Dst IP
1392
1393        // Some payload
1394        packet.extend_from_slice(b"unknown");
1395
1396        let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
1397
1398        // Ethernet
1399        iter.next().unwrap().unwrap();
1400
1401        // IPv4
1402        iter.next().unwrap().unwrap();
1403
1404        // Unknown
1405        let header = iter.next().unwrap().unwrap();
1406        assert!(header.is_unknown());
1407        if let Header::Unknown { proto, .. } = header {
1408            assert!(matches!(proto, UnknownProto::Ip(_)));
1409        }
1410
1411        // Done
1412        assert!(iter.next().is_none());
1413    }
1414
1415    #[test]
1416    fn test_collect_headers() {
1417        let packet = create_eth_ipv4_tcp_packet();
1418
1419        let headers = collect_headers(&packet, LinkType::Ethernet).unwrap();
1420
1421        assert_eq!(headers.len(), 3);
1422        assert!(matches!(headers[0], Header::Ethernet(_)));
1423        assert!(matches!(headers[1], Header::Ipv4(_)));
1424        assert!(matches!(headers[2], Header::Tcp(_)));
1425    }
1426
1427    #[test]
1428    fn test_collect_headers_error() {
1429        let packet = vec![0u8; 5]; // Too short
1430
1431        let result = collect_headers(&packet, LinkType::Ethernet);
1432        assert!(result.is_err());
1433    }
1434
1435    #[test]
1436    fn test_empty_buffer() {
1437        let packet: Vec<u8> = vec![];
1438        let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
1439
1440        assert!(iter.next().is_none());
1441        assert!(iter.is_done());
1442    }
1443
1444    #[test]
1445    fn test_packet_iter_ext_trait() {
1446        let packet = create_eth_ipv4_tcp_packet();
1447
1448        let headers: Vec<_> = packet
1449            .headers(LinkType::Ethernet)
1450            .filter_map(Result::ok)
1451            .collect();
1452
1453        assert_eq!(headers.len(), 3);
1454    }
1455
1456    #[test]
1457    fn test_header_display() {
1458        let packet = create_eth_ipv4_tcp_packet();
1459        let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
1460
1461        while let Some(Ok(header)) = iter.next() {
1462            // Just make sure Display doesn't panic
1463            let _ = format!("{}", header);
1464        }
1465    }
1466
1467    /// Create a minimal Ethernet + IPv6 + ICMPv6 packet for testing
1468    fn create_eth_ipv6_icmp6_packet() -> Vec<u8> {
1469        let mut packet = Vec::new();
1470
1471        // Ethernet header (14 bytes)
1472        packet.extend_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]); // Dest MAC
1473        packet.extend_from_slice(&[0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb]); // Src MAC
1474        packet.extend_from_slice(&[0x86, 0xdd]); // EtherType: IPv6
1475
1476        // IPv6 header (40 bytes)
1477        packet.extend_from_slice(&[0x60, 0x00, 0x00, 0x00]); // Version, TC, Flow Label
1478        packet.extend_from_slice(&8u16.to_be_bytes()); // Payload length (ICMPv6 header)
1479        packet.push(58); // Next Header: ICMPv6
1480        packet.push(64); // Hop Limit
1481                         // Source IPv6 (16 bytes) - ::1
1482        packet.extend_from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
1483        // Dest IPv6 (16 bytes) - ::2
1484        packet.extend_from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]);
1485
1486        // ICMPv6 Echo Request (8 bytes)
1487        packet.push(128); // Type: Echo Request
1488        packet.push(0); // Code
1489        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1490        packet.extend_from_slice(&[0x00, 0x01]); // Identifier
1491        packet.extend_from_slice(&[0x00, 0x01]); // Sequence
1492
1493        packet
1494    }
1495
1496    /// Create an Ethernet + IPv6 + UDP packet for testing
1497    fn create_eth_ipv6_udp_packet() -> Vec<u8> {
1498        let mut packet = Vec::new();
1499
1500        // Ethernet header (14 bytes)
1501        packet.extend_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]); // Dest MAC
1502        packet.extend_from_slice(&[0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb]); // Src MAC
1503        packet.extend_from_slice(&[0x86, 0xdd]); // EtherType: IPv6
1504
1505        // IPv6 header (40 bytes)
1506        packet.extend_from_slice(&[0x60, 0x00, 0x00, 0x00]); // Version, TC, Flow Label
1507        packet.extend_from_slice(&8u16.to_be_bytes()); // Payload length (UDP header)
1508        packet.push(17); // Next Header: UDP
1509        packet.push(64); // Hop Limit
1510                         // Source IPv6 (16 bytes)
1511        packet.extend_from_slice(&[0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
1512        // Dest IPv6 (16 bytes)
1513        packet.extend_from_slice(&[0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]);
1514
1515        // UDP header (8 bytes)
1516        packet.extend_from_slice(&53u16.to_be_bytes()); // Src port
1517        packet.extend_from_slice(&53u16.to_be_bytes()); // Dst port
1518        packet.extend_from_slice(&8u16.to_be_bytes()); // Length
1519        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1520
1521        packet
1522    }
1523
1524    #[test]
1525    fn test_eth_ipv6_icmp6_iteration() {
1526        let packet = create_eth_ipv6_icmp6_packet();
1527        let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
1528
1529        // Ethernet
1530        let header = iter.next().unwrap().unwrap();
1531        assert!(matches!(header, Header::Ethernet(_)));
1532
1533        // IPv6
1534        let header = iter.next().unwrap().unwrap();
1535        assert!(matches!(header, Header::Ipv6(_)));
1536        assert_eq!(header.name(), "IPv6");
1537
1538        // ICMPv6
1539        let header = iter.next().unwrap().unwrap();
1540        assert!(matches!(header, Header::Icmp6(_)));
1541        assert_eq!(header.name(), "ICMPv6");
1542
1543        // Done
1544        assert!(iter.next().is_none());
1545    }
1546
1547    #[test]
1548    fn test_eth_ipv6_udp_iteration() {
1549        let packet = create_eth_ipv6_udp_packet();
1550        let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
1551
1552        // Ethernet
1553        let header = iter.next().unwrap().unwrap();
1554        assert!(matches!(header, Header::Ethernet(_)));
1555
1556        // IPv6
1557        let header = iter.next().unwrap().unwrap();
1558        assert!(matches!(header, Header::Ipv6(_)));
1559
1560        // UDP
1561        let header = iter.next().unwrap().unwrap();
1562        assert!(matches!(header, Header::Udp(_)));
1563
1564        // Done
1565        assert!(iter.next().is_none());
1566    }
1567
1568    #[test]
1569    fn test_raw_ipv6_iteration() {
1570        let packet = create_eth_ipv6_udp_packet();
1571        // Skip Ethernet header (14 bytes) to get raw IPv6
1572        let ipv6_packet = &packet[14..];
1573
1574        let mut iter = PacketIter::new(ipv6_packet, LinkType::RawIpv6);
1575
1576        // IPv6
1577        let header = iter.next().unwrap().unwrap();
1578        assert!(matches!(header, Header::Ipv6(_)));
1579
1580        // UDP
1581        let header = iter.next().unwrap().unwrap();
1582        assert!(matches!(header, Header::Udp(_)));
1583
1584        // Done
1585        assert!(iter.next().is_none());
1586    }
1587
1588    // ==================== TUNNEL TESTS ====================
1589
1590    /// Create Ethernet + IPv4 + UDP + VXLAN + inner Ethernet + inner IPv4 packet
1591    fn create_vxlan_packet() -> Vec<u8> {
1592        let mut packet = Vec::new();
1593
1594        // Outer Ethernet header (14 bytes)
1595        packet.extend_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]); // Dest MAC
1596        packet.extend_from_slice(&[0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb]); // Src MAC
1597        packet.extend_from_slice(&[0x08, 0x00]); // EtherType: IPv4
1598
1599        // Outer IPv4 header (20 bytes)
1600        packet.push(0x45); // Version 4, IHL 5
1601        packet.push(0x00); // DSCP, ECN
1602        packet.extend_from_slice(&72u16.to_be_bytes()); // Total length
1603        packet.extend_from_slice(&[0x00, 0x00]); // ID
1604        packet.extend_from_slice(&[0x00, 0x00]); // Flags, Fragment offset
1605        packet.push(64); // TTL
1606        packet.push(17); // Protocol: UDP
1607        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1608        packet.extend_from_slice(&[10, 0, 0, 1]); // Src IP
1609        packet.extend_from_slice(&[10, 0, 0, 2]); // Dst IP
1610
1611        // Outer UDP header (8 bytes)
1612        packet.extend_from_slice(&12345u16.to_be_bytes()); // Src port
1613        packet.extend_from_slice(&4789u16.to_be_bytes()); // Dst port (VXLAN)
1614        packet.extend_from_slice(&52u16.to_be_bytes()); // Length
1615        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1616
1617        // VXLAN header (8 bytes)
1618        packet.extend_from_slice(&[0x08, 0x00, 0x00, 0x00]); // Flags (I=1)
1619        packet.extend_from_slice(&[0x00, 0x00, 0x64, 0x00]); // VNI = 100
1620
1621        // Inner Ethernet header (14 bytes)
1622        packet.extend_from_slice(&[0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]); // Dest MAC
1623        packet.extend_from_slice(&[0x11, 0x22, 0x33, 0x44, 0x55, 0x66]); // Src MAC
1624        packet.extend_from_slice(&[0x08, 0x00]); // EtherType: IPv4
1625
1626        // Inner IPv4 header (20 bytes)
1627        packet.push(0x45); // Version 4, IHL 5
1628        packet.push(0x00); // DSCP, ECN
1629        packet.extend_from_slice(&20u16.to_be_bytes()); // Total length
1630        packet.extend_from_slice(&[0x00, 0x00]); // ID
1631        packet.extend_from_slice(&[0x00, 0x00]); // Flags, Fragment offset
1632        packet.push(64); // TTL
1633        packet.push(6); // Protocol: TCP
1634        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1635        packet.extend_from_slice(&[192, 168, 1, 1]); // Src IP
1636        packet.extend_from_slice(&[192, 168, 1, 2]); // Dst IP
1637
1638        packet
1639    }
1640
1641    #[test]
1642    fn test_vxlan_tunnel_iteration() {
1643        let packet = create_vxlan_packet();
1644        let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
1645
1646        // Outer Ethernet
1647        let header = iter.next().unwrap().unwrap();
1648        assert!(matches!(header, Header::Ethernet(_)));
1649        assert!(header.is_link_layer());
1650
1651        // Outer IPv4
1652        let header = iter.next().unwrap().unwrap();
1653        assert!(matches!(header, Header::Ipv4(_)));
1654        assert!(header.is_network_layer());
1655
1656        // Outer UDP
1657        let header = iter.next().unwrap().unwrap();
1658        assert!(matches!(header, Header::Udp(_)));
1659        assert!(header.is_transport_layer());
1660
1661        // VXLAN
1662        let header = iter.next().unwrap().unwrap();
1663        assert!(matches!(header, Header::Vxlan(_)));
1664        assert!(header.is_tunnel());
1665        assert_eq!(header.name(), "VXLAN");
1666
1667        // Inner Ethernet
1668        let header = iter.next().unwrap().unwrap();
1669        assert!(matches!(header, Header::Ethernet(_)));
1670
1671        // Inner IPv4
1672        let header = iter.next().unwrap().unwrap();
1673        assert!(matches!(header, Header::Ipv4(_)));
1674
1675        // No TCP header in our test packet (just IPv4 with protocol=TCP)
1676        // The iterator would try to parse TCP but we don't have the bytes
1677    }
1678
1679    /// Create Ethernet + IPv4 + GRE + inner IPv4 packet
1680    fn create_gre_packet() -> Vec<u8> {
1681        let mut packet = Vec::new();
1682
1683        // Outer Ethernet header (14 bytes)
1684        packet.extend_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]); // Dest MAC
1685        packet.extend_from_slice(&[0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb]); // Src MAC
1686        packet.extend_from_slice(&[0x08, 0x00]); // EtherType: IPv4
1687
1688        // Outer IPv4 header (20 bytes)
1689        packet.push(0x45); // Version 4, IHL 5
1690        packet.push(0x00); // DSCP, ECN
1691        packet.extend_from_slice(&44u16.to_be_bytes()); // Total length
1692        packet.extend_from_slice(&[0x00, 0x00]); // ID
1693        packet.extend_from_slice(&[0x00, 0x00]); // Flags, Fragment offset
1694        packet.push(64); // TTL
1695        packet.push(47); // Protocol: GRE
1696        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1697        packet.extend_from_slice(&[10, 0, 0, 1]); // Src IP
1698        packet.extend_from_slice(&[10, 0, 0, 2]); // Dst IP
1699
1700        // GRE header (4 bytes, no options)
1701        packet.extend_from_slice(&[0x00, 0x00]); // Flags, Version
1702        packet.extend_from_slice(&[0x08, 0x00]); // Protocol: IPv4
1703
1704        // Inner IPv4 header (20 bytes)
1705        packet.push(0x45); // Version 4, IHL 5
1706        packet.push(0x00); // DSCP, ECN
1707        packet.extend_from_slice(&28u16.to_be_bytes()); // Total length (20 + 8 ICMP)
1708        packet.extend_from_slice(&[0x00, 0x00]); // ID
1709        packet.extend_from_slice(&[0x00, 0x00]); // Flags, Fragment offset
1710        packet.push(64); // TTL
1711        packet.push(1); // Protocol: ICMP
1712        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1713        packet.extend_from_slice(&[192, 168, 1, 1]); // Src IP
1714        packet.extend_from_slice(&[192, 168, 1, 2]); // Dst IP
1715
1716        // ICMP Echo Request (8 bytes)
1717        packet.push(8); // Type: Echo Request
1718        packet.push(0); // Code
1719        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1720        packet.extend_from_slice(&[0x00, 0x01]); // Identifier
1721        packet.extend_from_slice(&[0x00, 0x01]); // Sequence
1722
1723        packet
1724    }
1725
1726    #[test]
1727    fn test_gre_tunnel_iteration() {
1728        let packet = create_gre_packet();
1729        let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
1730
1731        // Outer Ethernet
1732        let header = iter.next().unwrap().unwrap();
1733        assert!(matches!(header, Header::Ethernet(_)));
1734
1735        // Outer IPv4
1736        let header = iter.next().unwrap().unwrap();
1737        assert!(matches!(header, Header::Ipv4(_)));
1738
1739        // GRE
1740        let header = iter.next().unwrap().unwrap();
1741        assert!(matches!(header, Header::Gre(_)));
1742        assert!(header.is_tunnel());
1743        assert_eq!(header.name(), "GRE");
1744
1745        // Inner IPv4
1746        let header = iter.next().unwrap().unwrap();
1747        assert!(matches!(header, Header::Ipv4(_)));
1748
1749        // ICMP
1750        let header = iter.next().unwrap().unwrap();
1751        assert!(matches!(header, Header::Icmp(_)));
1752
1753        // Done
1754        assert!(iter.next().is_none());
1755    }
1756
1757    /// Create Ethernet + MPLS + IPv4 packet
1758    fn create_mpls_packet() -> Vec<u8> {
1759        let mut packet = Vec::new();
1760
1761        // Ethernet header (14 bytes)
1762        packet.extend_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]); // Dest MAC
1763        packet.extend_from_slice(&[0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb]); // Src MAC
1764        packet.extend_from_slice(&[0x88, 0x47]); // EtherType: MPLS Unicast
1765
1766        // MPLS label (4 bytes) - Label=1000, TC=0, S=1 (bottom), TTL=64
1767        // Label (20 bits) = 1000 = 0x3E8
1768        // TC (3 bits) = 0
1769        // S (1 bit) = 1 (bottom of stack)
1770        // TTL (8 bits) = 64 = 0x40
1771        // Combined: 0x003E8140
1772        packet.extend_from_slice(&[0x00, 0x3E, 0x81, 0x40]);
1773
1774        // Inner IPv4 header (20 bytes)
1775        packet.push(0x45); // Version 4, IHL 5
1776        packet.push(0x00); // DSCP, ECN
1777        packet.extend_from_slice(&28u16.to_be_bytes()); // Total length (20 + 8 UDP)
1778        packet.extend_from_slice(&[0x00, 0x00]); // ID
1779        packet.extend_from_slice(&[0x00, 0x00]); // Flags, Fragment offset
1780        packet.push(64); // TTL
1781        packet.push(17); // Protocol: UDP
1782        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1783        packet.extend_from_slice(&[10, 0, 0, 1]); // Src IP
1784        packet.extend_from_slice(&[10, 0, 0, 2]); // Dst IP
1785
1786        // UDP header (8 bytes)
1787        packet.extend_from_slice(&53u16.to_be_bytes()); // Src port
1788        packet.extend_from_slice(&53u16.to_be_bytes()); // Dst port
1789        packet.extend_from_slice(&8u16.to_be_bytes()); // Length
1790        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1791
1792        packet
1793    }
1794
1795    #[test]
1796    fn test_mpls_tunnel_iteration() {
1797        let packet = create_mpls_packet();
1798        let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
1799
1800        // Ethernet
1801        let header = iter.next().unwrap().unwrap();
1802        assert!(matches!(header, Header::Ethernet(_)));
1803
1804        // MPLS
1805        let header = iter.next().unwrap().unwrap();
1806        assert!(matches!(header, Header::Mpls(_)));
1807        assert!(header.is_tunnel());
1808        assert_eq!(header.name(), "MPLS");
1809
1810        // Inner IPv4
1811        let header = iter.next().unwrap().unwrap();
1812        assert!(matches!(header, Header::Ipv4(_)));
1813
1814        // UDP
1815        let header = iter.next().unwrap().unwrap();
1816        assert!(matches!(header, Header::Udp(_)));
1817
1818        // Done
1819        assert!(iter.next().is_none());
1820    }
1821
1822    #[test]
1823    fn test_ip_in_ip_encapsulation() {
1824        let mut packet = Vec::new();
1825
1826        // Ethernet header (14 bytes)
1827        packet.extend_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]); // Dest MAC
1828        packet.extend_from_slice(&[0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb]); // Src MAC
1829        packet.extend_from_slice(&[0x08, 0x00]); // EtherType: IPv4
1830
1831        // Outer IPv4 header (20 bytes)
1832        packet.push(0x45); // Version 4, IHL 5
1833        packet.push(0x00); // DSCP, ECN
1834        packet.extend_from_slice(&40u16.to_be_bytes()); // Total length
1835        packet.extend_from_slice(&[0x00, 0x00]); // ID
1836        packet.extend_from_slice(&[0x00, 0x00]); // Flags, Fragment offset
1837        packet.push(64); // TTL
1838        packet.push(4); // Protocol: IP-in-IP (IPIP)
1839        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1840        packet.extend_from_slice(&[10, 0, 0, 1]); // Src IP
1841        packet.extend_from_slice(&[10, 0, 0, 2]); // Dst IP
1842
1843        // Inner IPv4 header (20 bytes)
1844        packet.push(0x45); // Version 4, IHL 5
1845        packet.push(0x00); // DSCP, ECN
1846        packet.extend_from_slice(&28u16.to_be_bytes()); // Total length (20 + 8 ICMP)
1847        packet.extend_from_slice(&[0x00, 0x00]); // ID
1848        packet.extend_from_slice(&[0x00, 0x00]); // Flags, Fragment offset
1849        packet.push(64); // TTL
1850        packet.push(1); // Protocol: ICMP
1851        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1852        packet.extend_from_slice(&[192, 168, 1, 1]); // Src IP
1853        packet.extend_from_slice(&[192, 168, 1, 2]); // Dst IP
1854
1855        // ICMP Echo Request (8 bytes)
1856        packet.push(8); // Type: Echo Request
1857        packet.push(0); // Code
1858        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1859        packet.extend_from_slice(&[0x00, 0x01]); // Identifier
1860        packet.extend_from_slice(&[0x00, 0x01]); // Sequence
1861
1862        let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
1863
1864        // Ethernet
1865        let header = iter.next().unwrap().unwrap();
1866        assert!(matches!(header, Header::Ethernet(_)));
1867
1868        // IPIP tunnel (wraps outer IPv4)
1869        let header = iter.next().unwrap().unwrap();
1870        assert!(
1871            matches!(header, Header::Ipip(_)),
1872            "Expected Ipip, got {:?}",
1873            header
1874        );
1875        if let Header::Ipip(tunnel) = &header {
1876            assert_eq!(
1877                tunnel.tunnel_type(),
1878                super::super::tunnel::ipip::IpipType::Ipip
1879            );
1880            assert!(tunnel.outer_ipv4().is_some());
1881        }
1882
1883        // Inner IPv4 (after decapsulation)
1884        let header = iter.next().unwrap().unwrap();
1885        assert!(matches!(header, Header::Ipv4(_)));
1886
1887        // ICMP
1888        let header = iter.next().unwrap().unwrap();
1889        assert!(matches!(header, Header::Icmp(_)));
1890
1891        // Done
1892        assert!(iter.next().is_none());
1893    }
1894
1895    #[test]
1896    fn test_header_is_tunnel() {
1897        let packet = create_vxlan_packet();
1898        let headers: Vec<_> = PacketIter::new(&packet, LinkType::Ethernet)
1899            .filter_map(Result::ok)
1900            .collect();
1901
1902        // Count tunnel headers
1903        let tunnel_count = headers.iter().filter(|h| h.is_tunnel()).count();
1904        assert_eq!(tunnel_count, 1); // Only VXLAN is a tunnel
1905    }
1906
1907    #[test]
1908    fn test_collect_headers_with_tunnel() {
1909        let packet = create_gre_packet();
1910
1911        let headers = collect_headers(&packet, LinkType::Ethernet).unwrap();
1912
1913        // Should have: Ethernet, IPv4, GRE, IPv4, ICMP
1914        assert_eq!(headers.len(), 5);
1915        assert!(matches!(headers[0], Header::Ethernet(_)));
1916        assert!(matches!(headers[1], Header::Ipv4(_)));
1917        assert!(matches!(headers[2], Header::Gre(_)));
1918        assert!(matches!(headers[3], Header::Ipv4(_)));
1919        assert!(matches!(headers[4], Header::Icmp(_)));
1920    }
1921
1922    #[test]
1923    fn test_l2tpv2_tunnel_detection() {
1924        let mut packet = Vec::new();
1925
1926        // Ethernet header (14 bytes)
1927        packet.extend_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]); // Dest MAC
1928        packet.extend_from_slice(&[0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb]); // Src MAC
1929        packet.extend_from_slice(&[0x08, 0x00]); // EtherType: IPv4
1930
1931        // IPv4 header (20 bytes)
1932        packet.push(0x45); // Version 4, IHL 5
1933        packet.push(0x00); // DSCP, ECN
1934        packet.extend_from_slice(&38u16.to_be_bytes()); // Total length
1935        packet.extend_from_slice(&[0x00, 0x00]); // ID
1936        packet.extend_from_slice(&[0x00, 0x00]); // Flags, Fragment offset
1937        packet.push(64); // TTL
1938        packet.push(17); // Protocol: UDP
1939        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1940        packet.extend_from_slice(&[10, 0, 0, 1]); // Src IP
1941        packet.extend_from_slice(&[10, 0, 0, 2]); // Dst IP
1942
1943        // UDP header (8 bytes)
1944        packet.extend_from_slice(&1701u16.to_be_bytes()); // Src port: L2TP
1945        packet.extend_from_slice(&1701u16.to_be_bytes()); // Dst port: L2TP
1946        packet.extend_from_slice(&18u16.to_be_bytes()); // Length
1947        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1948
1949        // L2TPv2 header (minimal data message - 6 bytes)
1950        // Flags: 0x0002 (version 2, data message)
1951        packet.extend_from_slice(&0x0002u16.to_be_bytes()); // Flags/version
1952        packet.extend_from_slice(&0x0001u16.to_be_bytes()); // Tunnel ID
1953        packet.extend_from_slice(&0x0001u16.to_be_bytes()); // Session ID
1954
1955        let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
1956
1957        // Ethernet
1958        let header = iter.next().unwrap().unwrap();
1959        assert!(matches!(header, Header::Ethernet(_)));
1960
1961        // IPv4
1962        let header = iter.next().unwrap().unwrap();
1963        assert!(matches!(header, Header::Ipv4(_)));
1964
1965        // UDP
1966        let header = iter.next().unwrap().unwrap();
1967        assert!(matches!(header, Header::Udp(_)));
1968
1969        // L2TPv2
1970        let header = iter.next().unwrap().unwrap();
1971        assert!(matches!(header, Header::L2tpv2(_)));
1972        assert!(header.is_tunnel());
1973        assert_eq!(header.name(), "L2TPv2");
1974    }
1975
1976    #[test]
1977    fn test_nvgre_tunnel_detection() {
1978        let mut packet = Vec::new();
1979
1980        // Ethernet header (14 bytes)
1981        packet.extend_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]); // Dest MAC
1982        packet.extend_from_slice(&[0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb]); // Src MAC
1983        packet.extend_from_slice(&[0x08, 0x00]); // EtherType: IPv4
1984
1985        // IPv4 header (20 bytes)
1986        packet.push(0x45); // Version 4, IHL 5
1987        packet.push(0x00); // DSCP, ECN
1988        packet.extend_from_slice(&44u16.to_be_bytes()); // Total length
1989        packet.extend_from_slice(&[0x00, 0x00]); // ID
1990        packet.extend_from_slice(&[0x00, 0x00]); // Flags, Fragment offset
1991        packet.push(64); // TTL
1992        packet.push(47); // Protocol: GRE
1993        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
1994        packet.extend_from_slice(&[10, 0, 0, 1]); // Src IP
1995        packet.extend_from_slice(&[10, 0, 0, 2]); // Dst IP
1996
1997        // NVGRE header (8 bytes): Key flag set, version 0, TEB protocol
1998        packet.extend_from_slice(&0x2000u16.to_be_bytes()); // Flags: Key present
1999        packet.extend_from_slice(&0x6558u16.to_be_bytes()); // Protocol: TEB
2000        packet.extend_from_slice(&0x00010001u32.to_be_bytes()); // VSID + FlowID
2001
2002        // Inner Ethernet (14 bytes minimum)
2003        packet.extend_from_slice(&[0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]); // Dest MAC
2004        packet.extend_from_slice(&[0x11, 0x22, 0x33, 0x44, 0x55, 0x66]); // Src MAC
2005        packet.extend_from_slice(&[0x08, 0x00]); // EtherType: IPv4
2006
2007        let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
2008
2009        // Ethernet
2010        let header = iter.next().unwrap().unwrap();
2011        assert!(matches!(header, Header::Ethernet(_)));
2012
2013        // IPv4
2014        let header = iter.next().unwrap().unwrap();
2015        assert!(matches!(header, Header::Ipv4(_)));
2016
2017        // NVGRE
2018        let header = iter.next().unwrap().unwrap();
2019        assert!(matches!(header, Header::Nvgre(_)));
2020        assert!(header.is_tunnel());
2021        assert_eq!(header.name(), "NVGRE");
2022
2023        // Inner Ethernet
2024        let header = iter.next().unwrap().unwrap();
2025        assert!(matches!(header, Header::Ethernet(_)));
2026    }
2027
2028    #[test]
2029    fn test_pptp_tunnel_detection() {
2030        let mut packet = Vec::new();
2031
2032        // Ethernet header (14 bytes)
2033        packet.extend_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]); // Dest MAC
2034        packet.extend_from_slice(&[0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb]); // Src MAC
2035        packet.extend_from_slice(&[0x08, 0x00]); // EtherType: IPv4
2036
2037        // IPv4 header (20 bytes)
2038        packet.push(0x45); // Version 4, IHL 5
2039        packet.push(0x00); // DSCP, ECN
2040        packet.extend_from_slice(&32u16.to_be_bytes()); // Total length
2041        packet.extend_from_slice(&[0x00, 0x00]); // ID
2042        packet.extend_from_slice(&[0x00, 0x00]); // Flags, Fragment offset
2043        packet.push(64); // TTL
2044        packet.push(47); // Protocol: GRE
2045        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
2046        packet.extend_from_slice(&[10, 0, 0, 1]); // Src IP
2047        packet.extend_from_slice(&[10, 0, 0, 2]); // Dst IP
2048
2049        // PPTP GRE header (Enhanced GRE version 1)
2050        // Flags: Key + Sequence, Version 1
2051        packet.extend_from_slice(&0x3001u16.to_be_bytes()); // K + S flags, version 1
2052        packet.extend_from_slice(&0x880Bu16.to_be_bytes()); // Protocol: PPP
2053        packet.extend_from_slice(&0x0004u16.to_be_bytes()); // Payload length
2054        packet.extend_from_slice(&0x0001u16.to_be_bytes()); // Call ID
2055        packet.extend_from_slice(&0x00000001u32.to_be_bytes()); // Sequence number
2056
2057        let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
2058
2059        // Ethernet
2060        let header = iter.next().unwrap().unwrap();
2061        assert!(matches!(header, Header::Ethernet(_)));
2062
2063        // IPv4
2064        let header = iter.next().unwrap().unwrap();
2065        assert!(matches!(header, Header::Ipv4(_)));
2066
2067        // PPTP
2068        let header = iter.next().unwrap().unwrap();
2069        assert!(matches!(header, Header::Pptp(_)));
2070        assert!(header.is_tunnel());
2071        assert_eq!(header.name(), "PPTP");
2072    }
2073
2074    #[test]
2075    fn test_pbb_tunnel_detection() {
2076        let mut packet = Vec::new();
2077
2078        // Ethernet header (14 bytes) - Backbone addresses
2079        packet.extend_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]); // B-DA
2080        packet.extend_from_slice(&[0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb]); // B-SA
2081        packet.extend_from_slice(&[0x88, 0xE7]); // EtherType: PBB I-Tag (802.1ah)
2082
2083        // I-Tag (6 bytes)
2084        packet.extend_from_slice(&[0x88, 0xE7]); // EtherType in I-Tag
2085        packet.extend_from_slice(&[0x00, 0x00, 0x01, 0x00]); // TCI + I-SID
2086
2087        // Inner Ethernet (customer frame - 14 bytes)
2088        packet.extend_from_slice(&[0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]); // C-DA
2089        packet.extend_from_slice(&[0x11, 0x22, 0x33, 0x44, 0x55, 0x66]); // C-SA
2090        packet.extend_from_slice(&[0x08, 0x00]); // EtherType: IPv4
2091
2092        let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
2093
2094        // Backbone Ethernet
2095        let header = iter.next().unwrap().unwrap();
2096        assert!(matches!(header, Header::Ethernet(_)));
2097
2098        // PBB
2099        let header = iter.next().unwrap().unwrap();
2100        assert!(matches!(header, Header::Pbb(_)));
2101        assert!(header.is_tunnel());
2102        assert_eq!(header.name(), "PBB");
2103
2104        // Customer Ethernet
2105        let header = iter.next().unwrap().unwrap();
2106        assert!(matches!(header, Header::Ethernet(_)));
2107    }
2108
2109    #[test]
2110    fn test_stt_tunnel_detection() {
2111        let mut packet = Vec::new();
2112
2113        // Ethernet header (14 bytes)
2114        packet.extend_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]); // Dest MAC
2115        packet.extend_from_slice(&[0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb]); // Src MAC
2116        packet.extend_from_slice(&[0x08, 0x00]); // EtherType: IPv4
2117
2118        // IPv4 header (20 bytes)
2119        packet.push(0x45); // Version 4, IHL 5
2120        packet.push(0x00); // DSCP, ECN
2121        packet.extend_from_slice(&100u16.to_be_bytes()); // Total length
2122        packet.extend_from_slice(&[0x00, 0x00]); // ID
2123        packet.extend_from_slice(&[0x00, 0x00]); // Flags, Fragment offset
2124        packet.push(64); // TTL
2125        packet.push(6); // Protocol: TCP
2126        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
2127        packet.extend_from_slice(&[10, 0, 0, 1]); // Src IP
2128        packet.extend_from_slice(&[10, 0, 0, 2]); // Dst IP
2129
2130        // TCP header (20 bytes) - pointing to STT port 7471
2131        packet.extend_from_slice(&12345u16.to_be_bytes()); // Src port
2132        packet.extend_from_slice(&7471u16.to_be_bytes()); // Dst port: STT
2133        packet.extend_from_slice(&[0x00, 0x00, 0x00, 0x01]); // Seq num
2134        packet.extend_from_slice(&[0x00, 0x00, 0x00, 0x00]); // Ack num
2135        packet.push(0x50); // Data offset (5 << 4)
2136        packet.push(0x02); // Flags (SYN)
2137        packet.extend_from_slice(&[0x00, 0x00]); // Window
2138        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
2139        packet.extend_from_slice(&[0x00, 0x00]); // Urgent pointer
2140
2141        // STT TCP-like header (20 bytes)
2142        packet.extend_from_slice(&0u16.to_be_bytes()); // Src port (unused)
2143        packet.extend_from_slice(&0u16.to_be_bytes()); // Dst port (unused)
2144        packet.extend_from_slice(&[0x00, 0x00, 0x00, 0x00]); // Seq (total len + frag offset)
2145        packet.extend_from_slice(&[0x00, 0x00, 0x00, 0x00]); // Ack (fragment ID)
2146        packet.push(0x50); // Data offset
2147        packet.push(0x00); // Flags
2148        packet.extend_from_slice(&[0x00, 0x00]); // Window
2149        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
2150        packet.extend_from_slice(&[0x00, 0x00]); // Urgent
2151
2152        // STT Frame Header (18 bytes)
2153        packet.push(0x00); // Version
2154        packet.push(0x00); // Flags
2155        packet.push(0x00); // L4 offset
2156        packet.push(0x00); // Reserved
2157        packet.extend_from_slice(&[0x00, 0x00]); // MSS
2158        packet.extend_from_slice(&[0x00, 0x00]); // VLAN TCI
2159        packet.extend_from_slice(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]); // Context ID
2160        packet.extend_from_slice(&[0x00, 0x00]); // Padding
2161
2162        // Inner Ethernet frame (minimum 14 bytes header + 2 bytes for EtherType parsing)
2163        packet.extend_from_slice(&[0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]); // Dest MAC
2164        packet.extend_from_slice(&[0x11, 0x22, 0x33, 0x44, 0x55, 0x66]); // Src MAC
2165        packet.extend_from_slice(&[0x08, 0x00]); // EtherType: IPv4
2166                                                 // Add minimal inner IPv4 header so Ethernet parsing succeeds
2167        packet.push(0x45); // Version 4, IHL 5
2168        packet.push(0x00); // DSCP, ECN
2169        packet.extend_from_slice(&20u16.to_be_bytes()); // Total length
2170        packet.extend_from_slice(&[0x00, 0x00]); // ID
2171        packet.extend_from_slice(&[0x00, 0x00]); // Flags, Fragment offset
2172        packet.push(64); // TTL
2173        packet.push(1); // Protocol: ICMP
2174        packet.extend_from_slice(&[0x00, 0x00]); // Checksum
2175        packet.extend_from_slice(&[192, 168, 1, 1]); // Src IP
2176        packet.extend_from_slice(&[192, 168, 1, 2]); // Dst IP
2177
2178        let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
2179
2180        // Ethernet
2181        let header = iter.next().unwrap().unwrap();
2182        assert!(matches!(header, Header::Ethernet(_)));
2183
2184        // IPv4
2185        let header = iter.next().unwrap().unwrap();
2186        assert!(matches!(header, Header::Ipv4(_)));
2187
2188        // TCP
2189        let header = iter.next().unwrap().unwrap();
2190        assert!(matches!(header, Header::Tcp(_)));
2191
2192        // STT
2193        let header = iter.next().unwrap().unwrap();
2194        assert!(matches!(header, Header::Stt(_)));
2195        assert!(header.is_tunnel());
2196        assert_eq!(header.name(), "STT");
2197
2198        // Inner Ethernet
2199        let header = iter.next().unwrap().unwrap();
2200        assert!(matches!(header, Header::Ethernet(_)));
2201
2202        // Inner IPv4
2203        let header = iter.next().unwrap().unwrap();
2204        assert!(matches!(header, Header::Ipv4(_)));
2205    }
2206
2207    #[test]
2208    fn test_gre_variant_detection() {
2209        // Test that standard GRE (version 0, no TEB) is detected correctly
2210        let mut packet = Vec::new();
2211
2212        // Ethernet header
2213        packet.extend_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]);
2214        packet.extend_from_slice(&[0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb]);
2215        packet.extend_from_slice(&[0x08, 0x00]);
2216
2217        // IPv4 header
2218        packet.push(0x45);
2219        packet.push(0x00);
2220        packet.extend_from_slice(&32u16.to_be_bytes());
2221        packet.extend_from_slice(&[0x00, 0x00]);
2222        packet.extend_from_slice(&[0x00, 0x00]);
2223        packet.push(64);
2224        packet.push(47); // GRE
2225        packet.extend_from_slice(&[0x00, 0x00]);
2226        packet.extend_from_slice(&[10, 0, 0, 1]);
2227        packet.extend_from_slice(&[10, 0, 0, 2]);
2228
2229        // Standard GRE header (version 0, IPv4 protocol)
2230        packet.extend_from_slice(&0x0000u16.to_be_bytes()); // No flags, version 0
2231        packet.extend_from_slice(&0x0800u16.to_be_bytes()); // Protocol: IPv4
2232
2233        // Inner IPv4
2234        packet.push(0x45);
2235        packet.push(0x00);
2236        packet.extend_from_slice(&20u16.to_be_bytes());
2237        packet.extend_from_slice(&[0x00, 0x00]);
2238        packet.extend_from_slice(&[0x00, 0x00]);
2239        packet.push(64);
2240        packet.push(1); // ICMP
2241        packet.extend_from_slice(&[0x00, 0x00]);
2242        packet.extend_from_slice(&[192, 168, 1, 1]);
2243        packet.extend_from_slice(&[192, 168, 1, 2]);
2244
2245        let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
2246
2247        iter.next(); // Ethernet
2248        iter.next(); // IPv4
2249
2250        // Should be standard GRE, not NVGRE or PPTP
2251        let header = iter.next().unwrap().unwrap();
2252        assert!(matches!(header, Header::Gre(_)));
2253        assert_eq!(header.name(), "GRE");
2254    }
2255
2256    #[test]
2257    fn test_guess_link_type_raw_ipv4() {
2258        // Raw IPv4 packet (version 4, IHL 5)
2259        let packet = vec![
2260            0x45, 0x00, 0x00, 0x28, // IPv4 header start
2261            0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x00, // TTL, TCP, checksum
2262            0xc0, 0xa8, 0x01, 0x01, // Src IP
2263            0xc0, 0xa8, 0x01, 0x02, // Dst IP
2264        ];
2265        assert_eq!(PacketIter::guess_link_type(&packet), LinkType::RawIpv4);
2266    }
2267
2268    #[test]
2269    fn test_guess_link_type_raw_ipv6() {
2270        // Raw IPv6 packet (version 6)
2271        let packet = vec![
2272            0x60, 0x00, 0x00, 0x00, // IPv6 header start
2273            0x00, 0x14, 0x06, 0x40, // Payload len, next header (TCP), hop limit
2274        ];
2275        assert_eq!(PacketIter::guess_link_type(&packet), LinkType::RawIpv6);
2276    }
2277
2278    #[test]
2279    fn test_guess_link_type_null_ipv4() {
2280        // Null/Loopback with AF_INET (2) little-endian, followed by IPv4
2281        let packet = vec![
2282            0x02, 0x00, 0x00, 0x00, // AF_INET
2283            0x45, 0x00, 0x00, 0x28, // IPv4 follows
2284        ];
2285        assert_eq!(PacketIter::guess_link_type(&packet), LinkType::Null);
2286    }
2287
2288    #[test]
2289    fn test_guess_link_type_null_ipv6_darwin() {
2290        // Null/Loopback with AF_INET6 (30) little-endian on macOS, followed by IPv6
2291        let packet = vec![
2292            0x1e, 0x00, 0x00, 0x00, // AF_INET6 (Darwin)
2293            0x60, 0x00, 0x00, 0x00, // IPv6 follows
2294        ];
2295        assert_eq!(PacketIter::guess_link_type(&packet), LinkType::Null);
2296    }
2297
2298    #[test]
2299    fn test_guess_link_type_ethernet_ipv4() {
2300        // Ethernet frame with IPv4
2301        let packet = vec![
2302            0x00, 0x11, 0x22, 0x33, 0x44, 0x55, // Dest MAC
2303            0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, // Src MAC
2304            0x08, 0x00, // EtherType: IPv4
2305            0x45, 0x00, // IPv4 header
2306        ];
2307        assert_eq!(PacketIter::guess_link_type(&packet), LinkType::Ethernet);
2308    }
2309
2310    #[test]
2311    fn test_guess_link_type_ethernet_ipv6() {
2312        // Ethernet frame with IPv6
2313        let packet = vec![
2314            0x00, 0x11, 0x22, 0x33, 0x44, 0x55, // Dest MAC
2315            0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, // Src MAC
2316            0x86, 0xdd, // EtherType: IPv6
2317            0x60, 0x00, // IPv6 header
2318        ];
2319        assert_eq!(PacketIter::guess_link_type(&packet), LinkType::Ethernet);
2320    }
2321
2322    #[test]
2323    fn test_guess_link_type_ethernet_arp() {
2324        // Ethernet frame with ARP
2325        let packet = vec![
2326            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Dest MAC (broadcast)
2327            0x00, 0x11, 0x22, 0x33, 0x44, 0x55, // Src MAC
2328            0x08, 0x06, // EtherType: ARP
2329        ];
2330        assert_eq!(PacketIter::guess_link_type(&packet), LinkType::Ethernet);
2331    }
2332
2333    #[test]
2334    fn test_guess_link_type_sll() {
2335        // SLL header (16 bytes)
2336        let packet = vec![
2337            0x00, 0x00, // Packet type: Host
2338            0x00, 0x01, // ARPHRD: Ethernet
2339            0x00, 0x06, // Address length
2340            0x00, 0x11, 0x22, 0x33, 0x44, 0x55, // Link-layer addr
2341            0x00, 0x00, // Padding
2342            0x08, 0x00, // Protocol: IPv4
2343            0x45, 0x00, // IPv4 data
2344        ];
2345        assert_eq!(PacketIter::guess_link_type(&packet), LinkType::Sll);
2346    }
2347
2348    #[test]
2349    fn test_guess_link_type_sllv2() {
2350        // SLLv2 header (20 bytes)
2351        let packet = vec![
2352            0x08, 0x00, // Protocol: IPv4
2353            0x00, 0x00, // Reserved
2354            0x00, 0x00, 0x00, 0x02, // Interface index
2355            0x00, 0x01, // ARPHRD: Ethernet
2356            0x00, // Packet type: Host
2357            0x06, // Address length
2358            0x00, 0x11, 0x22, 0x33, 0x44, 0x55, // Link-layer addr
2359            0x00, 0x00, // Padding
2360        ];
2361        assert_eq!(PacketIter::guess_link_type(&packet), LinkType::Sllv2);
2362    }
2363
2364    #[test]
2365    fn test_guess_link_type_empty() {
2366        let packet: Vec<u8> = vec![];
2367        // Default to Ethernet for empty buffer
2368        assert_eq!(PacketIter::guess_link_type(&packet), LinkType::Ethernet);
2369    }
2370
2371    #[test]
2372    fn test_guess_constructor_ipv4() {
2373        // Raw IPv4 packet
2374        let packet = vec![
2375            0x45, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x00, 0xc0, 0xa8,
2376            0x01, 0x01, 0xc0, 0xa8, 0x01, 0x02,
2377        ];
2378
2379        let link_type = PacketIter::guess_link_type(&packet);
2380        let mut iter = PacketIter::new(&packet, link_type);
2381        let first = iter.next().unwrap().unwrap();
2382        assert!(matches!(first, Header::Ipv4(_)));
2383    }
2384
2385    #[test]
2386    fn test_guess_constructor_ethernet() {
2387        let packet = create_eth_ipv4_tcp_packet();
2388        let link_type = PacketIter::guess_link_type(&packet);
2389        let mut iter = PacketIter::new(&packet, link_type);
2390
2391        let first = iter.next().unwrap().unwrap();
2392        assert!(matches!(first, Header::Ethernet(_)));
2393
2394        let second = iter.next().unwrap().unwrap();
2395        assert!(matches!(second, Header::Ipv4(_)));
2396    }
2397
2398    #[test]
2399    fn test_gre_over_raw_ip() {
2400        // Same packet but with explicit LinkType::RawIpv4
2401        let mut packet = Vec::new();
2402
2403        // Outer IPv4 header (20 bytes)
2404        packet.push(0x45);
2405        packet.push(0x00);
2406        packet.extend_from_slice(&52u16.to_be_bytes());
2407        packet.extend_from_slice(&[0x00, 0x00]);
2408        packet.extend_from_slice(&[0x00, 0x00]);
2409        packet.push(64);
2410        packet.push(47); // GRE
2411        packet.extend_from_slice(&[0x00, 0x00]);
2412        packet.extend_from_slice(&[10, 0, 0, 1]);
2413        packet.extend_from_slice(&[10, 0, 0, 2]);
2414
2415        // GRE header
2416        packet.extend_from_slice(&[0x00, 0x00]);
2417        packet.extend_from_slice(&[0x08, 0x00]); // IPv4
2418
2419        // Inner IPv4
2420        packet.push(0x45);
2421        packet.push(0x00);
2422        packet.extend_from_slice(&28u16.to_be_bytes());
2423        packet.extend_from_slice(&[0x00, 0x00]);
2424        packet.extend_from_slice(&[0x00, 0x00]);
2425        packet.push(64);
2426        packet.push(1); // ICMP
2427        packet.extend_from_slice(&[0x00, 0x00]);
2428        packet.extend_from_slice(&[192, 168, 1, 1]);
2429        packet.extend_from_slice(&[192, 168, 1, 2]);
2430
2431        // ICMP
2432        packet.push(8);
2433        packet.push(0);
2434        packet.extend_from_slice(&[0x00, 0x00]);
2435        packet.extend_from_slice(&[0x00, 0x01]);
2436        packet.extend_from_slice(&[0x00, 0x01]);
2437
2438        let mut iter = PacketIter::new(&packet, LinkType::RawIpv4);
2439
2440        // First: outer IPv4
2441        let h1 = iter.next().unwrap().unwrap();
2442        assert!(matches!(h1, Header::Ipv4(_)));
2443        if let Header::Ipv4(ipv4) = h1 {
2444            assert_eq!(ipv4.protocol(), IpProto::GRE);
2445        }
2446
2447        // Second: GRE
2448        let h2 = iter.next().unwrap().unwrap();
2449        assert!(matches!(h2, Header::Gre(_)));
2450
2451        // Third: inner IPv4
2452        let h3 = iter.next().unwrap().unwrap();
2453        assert!(matches!(h3, Header::Ipv4(_)));
2454        if let Header::Ipv4(ipv4) = h3 {
2455            assert_eq!(ipv4.protocol(), IpProto::ICMP);
2456        }
2457
2458        // Fourth: ICMP
2459        let h4 = iter.next().unwrap().unwrap();
2460        assert!(matches!(h4, Header::Icmp(_)));
2461
2462        // Done
2463        assert!(iter.next().is_none());
2464    }
2465
2466    #[test]
2467    fn test_gre_over_ethernet_ospf_packet() {
2468        // Real captured packet: Ethernet + IPv4 + GRE + inner IPv4 (OSPF)
2469        let packet: Vec<u8> = vec![
2470            0xcc, 0x01, 0x0f, 0x80, 0x00, 0x00, 0xcc, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x08, 0x00,
2471            0x45, 0xc0, 0x00, 0x64, 0x00, 0x0f, 0x00, 0x00, 0xff, 0x2f, 0x16, 0x47, 0xc0, 0xa8,
2472            0x0c, 0x01, 0xc0, 0xa8, 0x17, 0x03, 0x00, 0x00, 0x08, 0x00, 0x45, 0xc0, 0x00, 0x4c,
2473            0x00, 0x27, 0x00, 0x00, 0x01, 0x59, 0x0a, 0xc4, 0xc0, 0xa8, 0x0d, 0x01, 0xe0, 0x00,
2474            0x00, 0x05, 0x02, 0x01, 0x00, 0x2c, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
2475            0xea, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
2476            0xff, 0x00, 0x00, 0x0a, 0x12, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00,
2477            0x00, 0x00, 0x00, 0x00, 0xff, 0xf6, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00,
2478            0x00, 0x01,
2479        ];
2480
2481        let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
2482
2483        // First: Ethernet (EtherType 0x0800 = IPv4)
2484        let h1 = iter.next().unwrap().unwrap();
2485        assert!(matches!(h1, Header::Ethernet(_)));
2486        if let Header::Ethernet(eth) = h1 {
2487            assert_eq!(eth.protocol(), EtherProto::IPV4);
2488        }
2489
2490        // Second: outer IPv4 (protocol 0x2f = 47 = GRE)
2491        let h2 = iter.next().unwrap().unwrap();
2492        assert!(matches!(h2, Header::Ipv4(_)));
2493        if let Header::Ipv4(ipv4) = h2 {
2494            assert_eq!(ipv4.protocol(), IpProto::GRE);
2495        }
2496
2497        // Third: GRE (protocol 0x0800 = IPv4)
2498        let h3 = iter.next().unwrap().unwrap();
2499        assert!(matches!(h3, Header::Gre(_)), "Expected GRE, got {:?}", h3);
2500
2501        // Fourth: inner IPv4 (protocol 0x59 = 89 = OSPF)
2502        let h4 = iter.next().unwrap().unwrap();
2503        assert!(matches!(h4, Header::Ipv4(_)));
2504        if let Header::Ipv4(ipv4) = h4 {
2505            assert_eq!(ipv4.protocol(), IpProto::from(89u8)); // OSPF
2506        }
2507
2508        // Fifth: Unknown (OSPF is not parsed, should be Unknown)
2509        let h5 = iter.next().unwrap().unwrap();
2510        assert!(
2511            matches!(h5, Header::Unknown { .. }),
2512            "Expected Unknown for OSPF, got {:?}",
2513            h5
2514        );
2515    }
2516
2517    #[test]
2518    fn test_ipv4_in_ipv6_tunnel() {
2519        // Real captured packet: Ethernet + IPv6 + IPv4 + TCP (IPv4-in-IPv6 tunnel)
2520        // IPv6 next header = 4 (IPIP = IPv4 encapsulated in IPv6)
2521        let packet: Vec<u8> = vec![
2522            0x00, 0x90, 0x1a, 0x41, 0x65, 0x41, 0x00, 0x16, 0xcf, 0x41, 0x9c, 0x20, 0x86, 0xdd,
2523            0x60, 0x00, 0x00, 0x00, 0x00, 0x28, 0x04, 0x40, 0x20, 0x02, 0x46, 0x37, 0xd5, 0xd3,
2524            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x37, 0xd5, 0xd3, 0x20, 0x01, 0x48, 0x60,
2525            0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x45, 0x00,
2526            0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, 0x3b, 0x6b, 0x46, 0x37, 0xd5, 0xd3,
2527            0xc0, 0x58, 0x63, 0x01, 0x7a, 0x69, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2528            0x00, 0x00, 0x50, 0x02, 0x20, 0x00, 0xd5, 0xc4, 0x00, 0x00,
2529        ];
2530
2531        let mut iter = PacketIter::new(&packet, LinkType::Ethernet);
2532
2533        // First: Ethernet (EtherType 0x86dd = IPv6)
2534        let h1 = iter.next().unwrap().unwrap();
2535        assert!(
2536            matches!(h1, Header::Ethernet(_)),
2537            "Expected Ethernet, got {:?}",
2538            h1
2539        );
2540        if let Header::Ethernet(eth) = h1 {
2541            assert_eq!(eth.protocol(), EtherProto::IPV6);
2542        }
2543
2544        // Second: IP4in6 tunnel (wraps outer IPv6 with next header = 4)
2545        let h2 = iter.next().unwrap().unwrap();
2546        assert!(matches!(h2, Header::Ipip(_)), "Expected Ipip, got {:?}", h2);
2547        if let Header::Ipip(tunnel) = &h2 {
2548            assert_eq!(
2549                tunnel.tunnel_type(),
2550                super::super::tunnel::ipip::IpipType::Ip4in6,
2551                "Expected Ip4in6 tunnel type, got {:?}",
2552                tunnel.tunnel_type()
2553            );
2554            assert!(tunnel.outer_ipv6().is_some());
2555            let outer = tunnel.outer_ipv6().unwrap();
2556            assert_eq!(outer.next_header(), IpProto::from(4u8));
2557        }
2558
2559        // Third: inner IPv4 (protocol 6 = TCP)
2560        let h3 = iter.next().unwrap().unwrap();
2561        assert!(matches!(h3, Header::Ipv4(_)), "Expected Ipv4, got {:?}", h3);
2562        if let Header::Ipv4(ipv4) = h3 {
2563            assert_eq!(ipv4.protocol(), IpProto::TCP);
2564        }
2565
2566        // Fourth: TCP
2567        let h4 = iter.next().unwrap().unwrap();
2568        assert!(matches!(h4, Header::Tcp(_)), "Expected Tcp, got {:?}", h4);
2569
2570        // Done
2571        assert!(iter.next().is_none());
2572    }
2573}