From fcb42b5f97f88eb330016d71c00336ca6721a820 Mon Sep 17 00:00:00 2001 From: Tomas Kunovsky Date: Tue, 2 Feb 2021 21:27:41 +0100 Subject: [PATCH 1/5] Support for ivp6 defragmentation --- .../main/java/org/pcap4j/util/IpV6Helper.java | 141 ++++++++++++++++++ .../org/pcap4j/test/core/IpV6HelperTest.pcap | Bin 0 -> 196 bytes .../org/pcap4j/test/core/IpV6HelperTest.pcap | Bin 0 -> 196 bytes .../org/pcap4j/test/util/IpV6HelperTest.java | 95 ++++++++++++ 4 files changed, 236 insertions(+) create mode 100644 pcap4j-core/src/main/java/org/pcap4j/util/IpV6Helper.java create mode 100644 pcap4j-packetfactory-propertiesbased/src/test/resources/org/pcap4j/test/core/IpV6HelperTest.pcap create mode 100644 pcap4j-packetfactory-static/src/test/resources/org/pcap4j/test/core/IpV6HelperTest.pcap create mode 100644 pcap4j-packettest/src/test/java/org/pcap4j/test/util/IpV6HelperTest.java diff --git a/pcap4j-core/src/main/java/org/pcap4j/util/IpV6Helper.java b/pcap4j-core/src/main/java/org/pcap4j/util/IpV6Helper.java new file mode 100644 index 000000000..d0ccd6149 --- /dev/null +++ b/pcap4j-core/src/main/java/org/pcap4j/util/IpV6Helper.java @@ -0,0 +1,141 @@ +/*_########################################################################## + _## + _## Copyright (C) 2012 Pcap4J.org + _## + _########################################################################## +*/ + +package org.pcap4j.util; + +import java.util.Comparator; +import java.util.List; +import org.pcap4j.packet.*; +import org.pcap4j.packet.factory.PacketFactories; +import org.pcap4j.packet.namednumber.IpNumber; + +/** @author tkunovsky */ +public final class IpV6Helper { + private static final Comparator comparator = new ComparatorImpl(); + + private IpV6Helper() { + throw new AssertionError(); + } + + /** + * @param ipV6Packet fragmented ivp6 packet + * @return payload length of the fragmented packet + */ + private static int computePayloadLength(IpV6Packet ipV6Packet) { + return ipV6Packet.getHeader().getPayloadLength() - computeExtHeaderSizes(ipV6Packet); + } + + private static int computeExtHeaderSizes(Packet packet) { + Packet payload = packet.getPayload(); + if (payload instanceof IpV6ExtOptionsPacket) { + IpV6ExtOptionsPacket ipV6ExtOptionsPacket = (IpV6ExtOptionsPacket) payload; + return ((ipV6ExtOptionsPacket.getHeader().getHdrExtLenAsInt() + 1) * 8) + + computeExtHeaderSizes(payload); + } else if (payload instanceof IpV6ExtFragmentPacket) { + IpV6ExtFragmentPacket ipV6ExtFragmentPacket = (IpV6ExtFragmentPacket) payload; + return (ipV6ExtFragmentPacket.getHeader().length()); + } else if (payload instanceof IpV6ExtRoutingPacket) { + IpV6ExtRoutingPacket ipV6ExtRoutingPacket = (IpV6ExtRoutingPacket) payload; + return ((ipV6ExtRoutingPacket.getHeader().getHdrExtLenAsInt() + 1) * 8) + + computeExtHeaderSizes(payload); + } else { + throw new IllegalArgumentException("Can't find IpV6 fragment packet: " + packet); + } + } + + /** + * @param outerOfFragment builder of packet which is previous for ext. fragment header + * @param ipNumber new ip number for the packet + */ + private static void fixIpNumber(Packet.Builder outerOfFragment, IpNumber ipNumber) { + if (outerOfFragment instanceof IpV6Packet.Builder) { + IpV6Packet.Builder builder = (IpV6Packet.Builder) outerOfFragment; + builder.nextHeader(ipNumber); + } else if (outerOfFragment instanceof IpV6ExtOptionsPacket.Builder) { + IpV6ExtOptionsPacket.Builder builder = (IpV6ExtOptionsPacket.Builder) outerOfFragment; + builder.nextHeader(ipNumber); + } else if (outerOfFragment instanceof IpV6ExtRoutingPacket.Builder) { + IpV6ExtRoutingPacket.Builder builder = (IpV6ExtRoutingPacket.Builder) outerOfFragment; + builder.nextHeader(ipNumber); + } else { + throw new IllegalArgumentException("Can't defragment, unexpected header: " + outerOfFragment); + } + } + + /** + * @param list list + * @return a defragmented packet. + */ + public static IpV6Packet defragment(List list) { + list.sort(comparator); + IpV6Packet lastPacket = list.get(list.size() - 1); + IpV6ExtFragmentPacket ipV6LastFragmentPacket = lastPacket.get(IpV6ExtFragmentPacket.class); + if (ipV6LastFragmentPacket == null) { + throw new IllegalArgumentException("Can't defragment: " + lastPacket); + } + + int payloadTotalLength = + ipV6LastFragmentPacket.getHeader().getFragmentOffset() * 8 + + computePayloadLength(lastPacket); + + if (payloadTotalLength <= 0) { + throw new IllegalArgumentException("Can't defragment: " + list); + } + + final byte[] defragmentedPayload = new byte[payloadTotalLength]; + int destPos = 0; + try { + for (IpV6Packet p : list) { + IpV6ExtFragmentPacket fragmentPacket = p.get(IpV6ExtFragmentPacket.class); + byte[] rawPayload = fragmentPacket.getPayload().getRawData(); + System.arraycopy(rawPayload, 0, defragmentedPayload, destPos, rawPayload.length); + destPos += rawPayload.length; + } + } catch (NullPointerException e) { + throw new IllegalArgumentException("Can't defragment: " + list, e); + } catch (ArrayStoreException e) { + throw new IllegalArgumentException("Can't defragment: " + list, e); + } catch (IndexOutOfBoundsException e) { + throw new IllegalArgumentException("Can't defragment: " + list, e); + } + + IpV6Packet firstPacket = list.get(0); + IpV6ExtFragmentPacket ipV6FirstFragmentPacket = firstPacket.get(IpV6ExtFragmentPacket.class); + IpV6Packet.Builder builder = firstPacket.getBuilder(); + Packet.Builder outerOfFragmentb = builder.getOuterOf(IpV6ExtFragmentPacket.Builder.class); + outerOfFragmentb.payloadBuilder( + new SimpleBuilder( + PacketFactories.getFactory(Packet.class, IpNumber.class) + .newInstance( + defragmentedPayload, + 0, + defragmentedPayload.length, + ipV6FirstFragmentPacket.getHeader().getNextHeader()))); + fixIpNumber(outerOfFragmentb, ipV6FirstFragmentPacket.getHeader().getNextHeader()); + builder.correctLengthAtBuild(true); + return builder.build(); + } + + private static final class ComparatorImpl implements Comparator { + + @Override + public int compare(IpV6Packet p1, IpV6Packet p2) { + IpV6ExtFragmentPacket fp1 = p1.get(IpV6ExtFragmentPacket.class); + IpV6ExtFragmentPacket fp2 = p2.get(IpV6ExtFragmentPacket.class); + + if (fp1 == null) { + throw new IllegalArgumentException("Can't defragment: " + p1); + } + + if (fp2 == null) { + throw new IllegalArgumentException("Can't defragment: " + p2); + } + + return fp1.getHeader().getFragmentOffset() - fp2.getHeader().getFragmentOffset(); + } + } +} diff --git a/pcap4j-packetfactory-propertiesbased/src/test/resources/org/pcap4j/test/core/IpV6HelperTest.pcap b/pcap4j-packetfactory-propertiesbased/src/test/resources/org/pcap4j/test/core/IpV6HelperTest.pcap new file mode 100644 index 0000000000000000000000000000000000000000..87845811d310184a28d6f1d6e9d21ccf65482c80 GIT binary patch literal 196 zcmca|c+)~A1{MYcU}RuKa2VWxY!Lnj5@Q0BjBR%l6_s5X1awjq7Q3>4@5{gGi2P=&zsxgdogK(VP@U{e{Hm|0la*a3=H7v literal 0 HcmV?d00001 diff --git a/pcap4j-packetfactory-static/src/test/resources/org/pcap4j/test/core/IpV6HelperTest.pcap b/pcap4j-packetfactory-static/src/test/resources/org/pcap4j/test/core/IpV6HelperTest.pcap new file mode 100644 index 0000000000000000000000000000000000000000..87845811d310184a28d6f1d6e9d21ccf65482c80 GIT binary patch literal 196 zcmca|c+)~A1{MYcU}RuKa2VWxY!Lnj5@Q0BjBR%l6_s5X1awjq7Q3>4@5{gGi2P=&zsxgdogK(VP@U{e{Hm|0la*a3=H7v literal 0 HcmV?d00001 diff --git a/pcap4j-packettest/src/test/java/org/pcap4j/test/util/IpV6HelperTest.java b/pcap4j-packettest/src/test/java/org/pcap4j/test/util/IpV6HelperTest.java new file mode 100644 index 000000000..c197e7c94 --- /dev/null +++ b/pcap4j-packettest/src/test/java/org/pcap4j/test/util/IpV6HelperTest.java @@ -0,0 +1,95 @@ +package org.pcap4j.test.util; + +import static org.junit.Assert.*; + +import java.io.EOFException; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.util.*; +import java.util.concurrent.TimeoutException; +import org.junit.Test; +import org.pcap4j.core.PcapHandle; +import org.pcap4j.core.Pcaps; +import org.pcap4j.packet.*; +import org.pcap4j.packet.namednumber.*; +import org.pcap4j.util.IpV6Helper; +import org.pcap4j.util.MacAddress; + +@SuppressWarnings("javadoc") +public class IpV6HelperTest { + private static final String PCAP_FILE_KEY = IpV6HelperTest.class.getName() + ".pcapFile"; + private static final String PCAP_FILE = + System.getProperty( + PCAP_FILE_KEY, + "src/test/resources/org/pcap4j/test/core/" + + IpV6HelperTest.class.getSimpleName() + + ".pcap"); + + @Test + public void testFragmentDefragment() throws Exception { + UnknownPacket.Builder unknownb = new UnknownPacket.Builder(); + unknownb.rawData(new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); + + Inet6Address srcIp = (Inet6Address) InetAddress.getByName("2001:db8::3:2:1"); + Inet6Address dstIp = (Inet6Address) InetAddress.getByName("2001:db8::3:2:2"); + + UdpPacket.Builder udpb = new UdpPacket.Builder(); + udpb.srcPort(UdpPort.SNMP_TRAP) + .dstPort(UdpPort.getInstance((short) 0)) + .payloadBuilder(unknownb) + .correctChecksumAtBuild(true) + .correctLengthAtBuild(true) + .srcAddr(srcIp) + .dstAddr(dstIp); + + IpV6Packet.Builder ipv6b = new IpV6Packet.Builder(); + ipv6b + .version(IpVersion.IPV6) + .hopLimit((byte) 100) + .trafficClass(IpV6SimpleTrafficClass.newInstance((byte) 0x12)) + .flowLabel(IpV6SimpleFlowLabel.newInstance(0x12345)) + .nextHeader(IpNumber.UDP) + .srcAddr(srcIp) + .dstAddr(dstIp) + .payloadBuilder(udpb) + .correctLengthAtBuild(true); + + EthernetPacket.Builder eb = new EthernetPacket.Builder(); + eb.dstAddr(MacAddress.getByName("fe:00:00:00:00:02")) + .srcAddr(MacAddress.getByName("fe:00:00:00:00:01")) + .type(EtherType.IPV6) + .payloadBuilder(ipv6b) + .paddingAtBuild(true); + + EthernetPacket expectedPacket = eb.build(); + + PcapHandle handle = Pcaps.openOffline(PCAP_FILE); + List ipV6Packets = new ArrayList(); + Packet firstPacket = null; + + while (true) { + try { + Packet packet = handle.getNextPacketEx(); + if (firstPacket == null) { + firstPacket = packet; + } + ipV6Packets.add(packet.get(IpV6Packet.class)); + } catch (TimeoutException e) { + continue; + } catch (EOFException e) { + break; + } + } + handle.close(); + + Collections.shuffle(ipV6Packets); + + IpV6Packet defragmentedIpV6Packet = IpV6Helper.defragment(ipV6Packets); + Packet.Builder actualb = firstPacket.getBuilder(); + actualb + .getOuterOf(IpV6Packet.Builder.class) + .payloadBuilder(new SimpleBuilder(defragmentedIpV6Packet)); + + assertEquals(expectedPacket, actualb.build()); + } +} From e3d1e97748cd4e9e18fe1640da1a2b613aa96cae Mon Sep 17 00:00:00 2001 From: Tomas Kunovsky Date: Tue, 2 Feb 2021 21:33:54 +0100 Subject: [PATCH 2/5] fix test name --- .../src/test/java/org/pcap4j/test/util/IpV6HelperTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcap4j-packettest/src/test/java/org/pcap4j/test/util/IpV6HelperTest.java b/pcap4j-packettest/src/test/java/org/pcap4j/test/util/IpV6HelperTest.java index c197e7c94..09f7c4084 100644 --- a/pcap4j-packettest/src/test/java/org/pcap4j/test/util/IpV6HelperTest.java +++ b/pcap4j-packettest/src/test/java/org/pcap4j/test/util/IpV6HelperTest.java @@ -26,7 +26,7 @@ public class IpV6HelperTest { + ".pcap"); @Test - public void testFragmentDefragment() throws Exception { + public void testDefragment() throws Exception { UnknownPacket.Builder unknownb = new UnknownPacket.Builder(); unknownb.rawData(new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); From 4c3182cba82d3f5f05604da2c68bb1a3f378e083 Mon Sep 17 00:00:00 2001 From: Tomas Kunovsky Date: Wed, 3 Feb 2021 09:01:01 +0100 Subject: [PATCH 3/5] copyright fix --- .../src/test/java/org/pcap4j/test/util/IpV6HelperTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pcap4j-packettest/src/test/java/org/pcap4j/test/util/IpV6HelperTest.java b/pcap4j-packettest/src/test/java/org/pcap4j/test/util/IpV6HelperTest.java index 09f7c4084..3e4b2a4d1 100644 --- a/pcap4j-packettest/src/test/java/org/pcap4j/test/util/IpV6HelperTest.java +++ b/pcap4j-packettest/src/test/java/org/pcap4j/test/util/IpV6HelperTest.java @@ -1,3 +1,10 @@ +/*_########################################################################## + _## + _## Copyright (C) 2012 Pcap4J.org + _## + _########################################################################## +*/ + package org.pcap4j.test.util; import static org.junit.Assert.*; From 38f51792841bca77146126acef05c672c2d36f11 Mon Sep 17 00:00:00 2001 From: Tomas Kunovsky Date: Wed, 3 Feb 2021 20:26:13 +0100 Subject: [PATCH 4/5] More tests for Ivp6 defragmentation --- .../main/java/org/pcap4j/util/IpV6Helper.java | 8 +- .../org/pcap4j/test/util/IpV6HelperTest.java | 93 +++++++++++++++++-- 2 files changed, 87 insertions(+), 14 deletions(-) diff --git a/pcap4j-core/src/main/java/org/pcap4j/util/IpV6Helper.java b/pcap4j-core/src/main/java/org/pcap4j/util/IpV6Helper.java index d0ccd6149..f31e3abc8 100644 --- a/pcap4j-core/src/main/java/org/pcap4j/util/IpV6Helper.java +++ b/pcap4j-core/src/main/java/org/pcap4j/util/IpV6Helper.java @@ -13,13 +13,10 @@ import org.pcap4j.packet.factory.PacketFactories; import org.pcap4j.packet.namednumber.IpNumber; -/** @author tkunovsky */ public final class IpV6Helper { private static final Comparator comparator = new ComparatorImpl(); - private IpV6Helper() { - throw new AssertionError(); - } + private IpV6Helper() {} /** * @param ipV6Packet fragmented ivp6 packet @@ -74,9 +71,6 @@ public static IpV6Packet defragment(List list) { list.sort(comparator); IpV6Packet lastPacket = list.get(list.size() - 1); IpV6ExtFragmentPacket ipV6LastFragmentPacket = lastPacket.get(IpV6ExtFragmentPacket.class); - if (ipV6LastFragmentPacket == null) { - throw new IllegalArgumentException("Can't defragment: " + lastPacket); - } int payloadTotalLength = ipV6LastFragmentPacket.getHeader().getFragmentOffset() * 8 diff --git a/pcap4j-packettest/src/test/java/org/pcap4j/test/util/IpV6HelperTest.java b/pcap4j-packettest/src/test/java/org/pcap4j/test/util/IpV6HelperTest.java index 3e4b2a4d1..f6f88fe74 100644 --- a/pcap4j-packettest/src/test/java/org/pcap4j/test/util/IpV6HelperTest.java +++ b/pcap4j-packettest/src/test/java/org/pcap4j/test/util/IpV6HelperTest.java @@ -8,10 +8,10 @@ package org.pcap4j.test.util; import static org.junit.Assert.*; - import java.io.EOFException; import java.net.Inet6Address; import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.*; import java.util.concurrent.TimeoutException; import org.junit.Test; @@ -32,8 +32,7 @@ public class IpV6HelperTest { + IpV6HelperTest.class.getSimpleName() + ".pcap"); - @Test - public void testDefragment() throws Exception { + private EthernetPacket getPacket(boolean fragmented) throws UnknownHostException { UnknownPacket.Builder unknownb = new UnknownPacket.Builder(); unknownb.rawData(new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); @@ -49,16 +48,23 @@ public void testDefragment() throws Exception { .srcAddr(srcIp) .dstAddr(dstIp); + IpV6ExtFragmentPacket.Builder fragHeadb = new IpV6ExtFragmentPacket.Builder(); + fragHeadb + .fragmentOffset((short) 0) + .identification(123) + .nextHeader(IpNumber.UDP) + .payloadBuilder(udpb); + IpV6Packet.Builder ipv6b = new IpV6Packet.Builder(); ipv6b .version(IpVersion.IPV6) .hopLimit((byte) 100) .trafficClass(IpV6SimpleTrafficClass.newInstance((byte) 0x12)) .flowLabel(IpV6SimpleFlowLabel.newInstance(0x12345)) - .nextHeader(IpNumber.UDP) + .nextHeader(fragmented ? IpNumber.IPV6_FRAG : IpNumber.UDP) .srcAddr(srcIp) .dstAddr(dstIp) - .payloadBuilder(udpb) + .payloadBuilder(fragmented ? fragHeadb : udpb) .correctLengthAtBuild(true); EthernetPacket.Builder eb = new EthernetPacket.Builder(); @@ -68,7 +74,65 @@ public void testDefragment() throws Exception { .payloadBuilder(ipv6b) .paddingAtBuild(true); - EthernetPacket expectedPacket = eb.build(); + return eb.build(); + } + + private Packet addExtRoutingHeader(Packet packet, boolean isFragmented) + throws IllegalRawDataException, UnknownHostException { + + IpV6ExtRoutingPacket.Builder ipV6ExtRoutingPacketb = new IpV6ExtRoutingPacket.Builder(); + ipV6ExtRoutingPacketb + .nextHeader(isFragmented ? IpNumber.IPV6_FRAG : IpNumber.UDP) + .correctLengthAtBuild(true) + .routingType(IpV6RoutingType.NIMROD) + .segmentsLeft((byte) 2) + .data( + new IpV6RoutingSourceRouteData( + 0, + new ArrayList( + Arrays.asList( + new Inet6Address[] { + (Inet6Address) InetAddress.getByName("2200::210:2:0:0:4") + })))) + .payloadBuilder( + isFragmented + ? packet.get(IpV6ExtFragmentPacket.class).getBuilder() + : packet.get(UdpPacket.class).getBuilder()); + + Packet.Builder packetb = packet.getBuilder(); + packetb + .get(IpV6Packet.Builder.class) + .correctLengthAtBuild(true) + .payloadBuilder(ipV6ExtRoutingPacketb) + .nextHeader(IpNumber.IPV6_ROUTE); + + return packetb.build(); + } + + @Test(expected = IllegalArgumentException.class) + public void twoNoFragmentedPackets() throws UnknownHostException { + List ipV6Packets = new ArrayList(); + IpV6Packet ipV6Packet = getPacket(false).get(IpV6Packet.class); + ipV6Packets.add(ipV6Packet); + ipV6Packets.add(ipV6Packet); + IpV6Helper.defragment(ipV6Packets); + } + + @Test(expected = IllegalArgumentException.class) + public void oneNoFragmentedPacket() throws UnknownHostException { + List ipV6Packets = new ArrayList(); + ipV6Packets.add(getPacket(true).get(IpV6Packet.class)); + ipV6Packets.add(getPacket(false).get(IpV6Packet.class)); + IpV6Helper.defragment(ipV6Packets); + } + + private void testDefragment(boolean routingHeader) throws Exception { + EthernetPacket expectedPacket; + if (routingHeader) { + expectedPacket = (EthernetPacket) addExtRoutingHeader(getPacket(false), false); + } else { + expectedPacket = getPacket(false); + } PcapHandle handle = Pcaps.openOffline(PCAP_FILE); List ipV6Packets = new ArrayList(); @@ -76,7 +140,12 @@ public void testDefragment() throws Exception { while (true) { try { - Packet packet = handle.getNextPacketEx(); + Packet packet; + if (routingHeader) { + packet = addExtRoutingHeader(handle.getNextPacketEx(), true); + } else { + packet = handle.getNextPacketEx(); + } if (firstPacket == null) { firstPacket = packet; } @@ -99,4 +168,14 @@ public void testDefragment() throws Exception { assertEquals(expectedPacket, actualb.build()); } + + @Test + public void testDefragmentWithRoutingHeader() throws Exception { + testDefragment(true); + } + + @Test + public void testDefragmentWithoutExtHeaders() throws Exception { + testDefragment(false); + } } From b4d3557c17b49ea1f424a306b64cbb82d0272986 Mon Sep 17 00:00:00 2001 From: Tomas Kunovsky Date: Thu, 4 Feb 2021 19:45:02 +0100 Subject: [PATCH 5/5] More tests for ipv6 defragmentation --- .../main/java/org/pcap4j/util/IpV6Helper.java | 6 +- .../org/pcap4j/test/util/IpV6HelperTest.java | 57 +++++++++++++++++-- 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/pcap4j-core/src/main/java/org/pcap4j/util/IpV6Helper.java b/pcap4j-core/src/main/java/org/pcap4j/util/IpV6Helper.java index f31e3abc8..1ba32e9ff 100644 --- a/pcap4j-core/src/main/java/org/pcap4j/util/IpV6Helper.java +++ b/pcap4j-core/src/main/java/org/pcap4j/util/IpV6Helper.java @@ -89,11 +89,7 @@ public static IpV6Packet defragment(List list) { System.arraycopy(rawPayload, 0, defragmentedPayload, destPos, rawPayload.length); destPos += rawPayload.length; } - } catch (NullPointerException e) { - throw new IllegalArgumentException("Can't defragment: " + list, e); - } catch (ArrayStoreException e) { - throw new IllegalArgumentException("Can't defragment: " + list, e); - } catch (IndexOutOfBoundsException e) { + } catch (Throwable e) { throw new IllegalArgumentException("Can't defragment: " + list, e); } diff --git a/pcap4j-packettest/src/test/java/org/pcap4j/test/util/IpV6HelperTest.java b/pcap4j-packettest/src/test/java/org/pcap4j/test/util/IpV6HelperTest.java index f6f88fe74..6653e37ca 100644 --- a/pcap4j-packettest/src/test/java/org/pcap4j/test/util/IpV6HelperTest.java +++ b/pcap4j-packettest/src/test/java/org/pcap4j/test/util/IpV6HelperTest.java @@ -8,6 +8,7 @@ package org.pcap4j.test.util; import static org.junit.Assert.*; + import java.io.EOFException; import java.net.Inet6Address; import java.net.InetAddress; @@ -32,6 +33,12 @@ public class IpV6HelperTest { + IpV6HelperTest.class.getSimpleName() + ".pcap"); + enum ExtHeader { + DESTINATION, + ROUTING, + NO_HEADER + }; + private EthernetPacket getPacket(boolean fragmented) throws UnknownHostException { UnknownPacket.Builder unknownb = new UnknownPacket.Builder(); unknownb.rawData(new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); @@ -109,6 +116,37 @@ private Packet addExtRoutingHeader(Packet packet, boolean isFragmented) return packetb.build(); } + private Packet addExtDestinationHeader(Packet packet, boolean isFragmented) + throws IllegalRawDataException, UnknownHostException { + IpV6ExtDestinationOptionsPacket.Builder ipV6ExtDestinationOptionsPacketb = + new IpV6ExtDestinationOptionsPacket.Builder(); + ipV6ExtDestinationOptionsPacketb + .nextHeader(isFragmented ? IpNumber.IPV6_FRAG : IpNumber.UDP) + .correctLengthAtBuild(true) + .options( + new ArrayList( + Arrays.asList( + new IpV6ExtOptionsPacket.IpV6Option[] { + new IpV6PadNOption.Builder() + .correctLengthAtBuild(true) + .data(new byte[] {0, 0, 0, 0}) + .build() + }))) + .payloadBuilder( + isFragmented + ? packet.get(IpV6ExtFragmentPacket.class).getBuilder() + : packet.get(UdpPacket.class).getBuilder()); + + Packet.Builder packetb = packet.getBuilder(); + packetb + .get(IpV6Packet.Builder.class) + .correctLengthAtBuild(true) + .payloadBuilder(ipV6ExtDestinationOptionsPacketb) + .nextHeader(IpNumber.IPV6_ROUTE); + + return packetb.build(); + } + @Test(expected = IllegalArgumentException.class) public void twoNoFragmentedPackets() throws UnknownHostException { List ipV6Packets = new ArrayList(); @@ -126,10 +164,12 @@ public void oneNoFragmentedPacket() throws UnknownHostException { IpV6Helper.defragment(ipV6Packets); } - private void testDefragment(boolean routingHeader) throws Exception { + private void testDefragment(ExtHeader extHeader) throws Exception { EthernetPacket expectedPacket; - if (routingHeader) { + if (extHeader == ExtHeader.ROUTING) { expectedPacket = (EthernetPacket) addExtRoutingHeader(getPacket(false), false); + } else if (extHeader == ExtHeader.DESTINATION) { + expectedPacket = (EthernetPacket) addExtDestinationHeader(getPacket(false), false); } else { expectedPacket = getPacket(false); } @@ -141,8 +181,10 @@ private void testDefragment(boolean routingHeader) throws Exception { while (true) { try { Packet packet; - if (routingHeader) { + if (extHeader == ExtHeader.ROUTING) { packet = addExtRoutingHeader(handle.getNextPacketEx(), true); + } else if (extHeader == ExtHeader.DESTINATION) { + packet = addExtDestinationHeader(handle.getNextPacketEx(), true); } else { packet = handle.getNextPacketEx(); } @@ -171,11 +213,16 @@ private void testDefragment(boolean routingHeader) throws Exception { @Test public void testDefragmentWithRoutingHeader() throws Exception { - testDefragment(true); + testDefragment(ExtHeader.ROUTING); } @Test public void testDefragmentWithoutExtHeaders() throws Exception { - testDefragment(false); + testDefragment(ExtHeader.NO_HEADER); + } + + @Test + public void testDefragmentWithDestinationExtHeaders() throws Exception { + testDefragment(ExtHeader.DESTINATION); } }