@@ -16,6 +16,8 @@ use tokio::sync::mpsc::Sender;
1616// Define constants for Linux cooked capture EtherTypes
1717const SLL_IPV4 : u16 = 0x0800 ;
1818const SLL_IPV6 : u16 = 0x86DD ;
19+ // Define constant for 802.1Q VLAN EtherType
20+ const ETHERTYPE_VLAN : u16 = 0x8100 ;
1921
2022pub async fn read_pcap_file < T > (
2123 path : & str ,
8789 . await ;
8890 }
8991 }
92+ EtherTypes :: Vlan => {
93+ // Handle 802.1Q VLAN tagged packets
94+ // VLAN header is 4 bytes: 2 bytes for VLAN tag and 2 bytes for inner EtherType
95+ if ethernet. payload ( ) . len ( ) >= 4 {
96+ let inner_ethertype =
97+ u16:: from_be_bytes ( [ ethernet. payload ( ) [ 2 ] , ethernet. payload ( ) [ 3 ] ] ) ;
98+
99+ match inner_ethertype {
100+ SLL_IPV4 => {
101+ if let Some ( packet) = Ipv4Packet :: new ( & ethernet. payload ( ) [ 4 ..] ) {
102+ process_packet :: < T , Ipv4Packet > (
103+ & packet,
104+ timestamp_us,
105+ & shard_senders,
106+ num_threads,
107+ PacketFeatures :: from_ipv4_packet,
108+ )
109+ . await ;
110+ }
111+ }
112+ SLL_IPV6 => {
113+ if let Some ( packet) = Ipv6Packet :: new ( & ethernet. payload ( ) [ 4 ..] ) {
114+ process_packet :: < T , Ipv6Packet > (
115+ & packet,
116+ timestamp_us,
117+ & shard_senders,
118+ num_threads,
119+ PacketFeatures :: from_ipv6_packet,
120+ )
121+ . await ;
122+ }
123+ }
124+ _ => debug ! (
125+ "Unsupported inner EtherType in VLAN packet: 0x{:04x}" ,
126+ inner_ethertype
127+ ) ,
128+ }
129+ } else {
130+ debug ! ( "VLAN packet too short to contain inner EtherType" ) ;
131+ }
132+ }
90133 _ => {
91134 // Check if it is a Linux cooked capture
92135 let ethertype = u16:: from_be_bytes ( [ packet. data [ 14 ] , packet. data [ 15 ] ] ) ;
@@ -115,6 +158,47 @@ where
115158 . await ;
116159 }
117160 }
161+ ETHERTYPE_VLAN => {
162+ // Handle VLAN in Linux cooked capture
163+ if packet. data . len ( ) >= 20 {
164+ // 16 bytes SLL header + 4 bytes VLAN header
165+ let inner_ethertype =
166+ u16:: from_be_bytes ( [ packet. data [ 18 ] , packet. data [ 19 ] ] ) ;
167+
168+ match inner_ethertype {
169+ SLL_IPV4 => {
170+ if let Some ( packet) = Ipv4Packet :: new ( & packet. data [ 20 ..] ) {
171+ process_packet :: < T , Ipv4Packet > (
172+ & packet,
173+ timestamp_us,
174+ & shard_senders,
175+ num_threads,
176+ PacketFeatures :: from_ipv4_packet,
177+ )
178+ . await ;
179+ }
180+ }
181+ SLL_IPV6 => {
182+ if let Some ( packet) = Ipv6Packet :: new ( & packet. data [ 20 ..] ) {
183+ process_packet :: < T , Ipv6Packet > (
184+ & packet,
185+ timestamp_us,
186+ & shard_senders,
187+ num_threads,
188+ PacketFeatures :: from_ipv6_packet,
189+ )
190+ . await ;
191+ }
192+ }
193+ _ => debug ! (
194+ "Unsupported inner EtherType in VLAN packet: 0x{:04x}" ,
195+ inner_ethertype
196+ ) ,
197+ }
198+ } else {
199+ debug ! ( "VLAN packet in Linux cooked capture too short" ) ;
200+ }
201+ }
118202 _ => debug ! ( "Failed to parse packet as IPv4 or IPv6..." ) ,
119203 }
120204 }
0 commit comments