diff --git a/pkts-core/src/main/java/io/pkts/framer/EthernetFramer.java b/pkts-core/src/main/java/io/pkts/framer/EthernetFramer.java index 9455243b..fc92919a 100644 --- a/pkts-core/src/main/java/io/pkts/framer/EthernetFramer.java +++ b/pkts-core/src/main/java/io/pkts/framer/EthernetFramer.java @@ -52,8 +52,13 @@ public MACPacket frame(final PCapPacket parent, final Buffer buffer) throws IOEx try { EtherType etherType = getEtherType(buffer.getByte(12), buffer.getByte(13)); if (etherType == EtherType.Dot1Q) { - getEtherType(buffer.getByte(16), buffer.getByte(17)); - headers = buffer.readBytes(18); + EtherType innerEtherType = getEtherType(buffer.getByte(16), buffer.getByte(17)); + // support QinQ + if (innerEtherType == EtherType.Dot1Q) { + headers = buffer.readBytes(22); + } else { + headers = buffer.readBytes(18); + } } else { headers = buffer.readBytes(14); } diff --git a/pkts-core/src/main/java/io/pkts/packet/impl/MACPacketImpl.java b/pkts-core/src/main/java/io/pkts/packet/impl/MACPacketImpl.java index 9123df02..69a9b591 100644 --- a/pkts-core/src/main/java/io/pkts/packet/impl/MACPacketImpl.java +++ b/pkts-core/src/main/java/io/pkts/packet/impl/MACPacketImpl.java @@ -9,10 +9,7 @@ import io.pkts.framer.EthernetFramer; import io.pkts.framer.IPv4Framer; import io.pkts.framer.IPv6Framer; -import io.pkts.packet.IPPacket; -import io.pkts.packet.MACPacket; -import io.pkts.packet.PCapPacket; -import io.pkts.packet.PacketParseException; +import io.pkts.packet.*; import io.pkts.protocol.Protocol; import java.io.IOException; @@ -199,16 +196,17 @@ public Protocol getNextProtocol() throws IOException { } catch (UnknownEtherType e) { throw new PacketParseException(12, String.format("Unknown Ethernet type 0x%02x%02x", e.getB1(), e.getB2())); } - if (etherType == EthernetFramer.EtherType.Dot1Q) { - try { - etherType = EthernetFramer.getEtherType(headers.getByte(16), headers.getByte(17)); - } catch (UnknownEtherType e) { - throw new PacketParseException(16, String.format("Unknown Ethernet type 0x%02x%02x", e.getB1(), e.getB2())); - } catch (IndexOutOfBoundsException e) { - throw new PacketParseException(14, "Not enough bytes in this header"); + for (int i = 0; i < 2; i++) { + if (etherType == EthernetFramer.EtherType.Dot1Q) { + try { + etherType = EthernetFramer.getEtherType(headers.getByte(16 + i * 4), headers.getByte(17 + i * 4)); + } catch (UnknownEtherType e) { + throw new PacketParseException(16 + i * 4, String.format("Unknown Ethernet type 0x%02x%02x", e.getB1(), e.getB2())); + } catch (IndexOutOfBoundsException e) { + throw new PacketParseException(14, "Not enough bytes in this header"); + } } } - switch (etherType) { case IPv4: return Protocol.IPv4; diff --git a/pkts-core/src/test/java/io/pkts/VLANTest.java b/pkts-core/src/test/java/io/pkts/VLANTest.java new file mode 100644 index 00000000..29d5ae4b --- /dev/null +++ b/pkts-core/src/test/java/io/pkts/VLANTest.java @@ -0,0 +1,50 @@ +package io.pkts; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; +import io.pkts.packet.Packet; +import io.pkts.packet.TCPPacket; +import io.pkts.packet.sip.SipPacket; +import io.pkts.protocol.Protocol; + +import java.io.ByteArrayOutputStream; +import java.io.InputStream; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class VLANTest extends PktsTestBase { + + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + } + + @Override + @After + public void tearDown() throws Exception { + super.tearDown(); + } + + // test QinQ packet + @Test + public void testLoop() throws Exception { + final InputStream stream = PktsTestBase.class.getResourceAsStream("event_waf_152197.pcap"); + final Pcap pcap = Pcap.openStream(stream); + pcap.loop(packet -> { + while (true) { + packet = packet.getNextPacket(); + if (packet == null) { + break; + } + } + return true; + }); + pcap.close(); + } + +} diff --git a/pkts-core/src/test/resources/io/pkts/event_waf_152197.pcap b/pkts-core/src/test/resources/io/pkts/event_waf_152197.pcap new file mode 100644 index 00000000..22e8c399 Binary files /dev/null and b/pkts-core/src/test/resources/io/pkts/event_waf_152197.pcap differ