Ipv6Decoder extends AbstractPacketDecoder<EthernetPacketReceived, Ipv6PacketReceived> implements EthernetPacketListener { @Override public Ipv6PacketReceived decode(EthernetPacketReceived ethernetPacketReceived) { Ipv6PacketReceivedBuilder ipv6ReceivedBuilder = new Ipv6PacketReceivedBuilder(); List<PacketChain> packetChainList = ethernetPacketReceived.getPacketChain(); EthernetPacket ethernetPacket = (EthernetPacket) packetChainList.get(packetChainList.size() - 1).getPacket(); int bitOffset = ethernetPacket.getPayloadOffset() * NetUtils.NUM_BITS_IN_A_BYTE; byte[] data = ethernetPacketReceived.getPayload(); Ipv6PacketBuilder builder = new Ipv6PacketBuilder(); try { builder.setVersion(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset, 4))); if (builder.getVersion().intValue() != 6) { LOG.debug("Version should be 6, but is {}", builder.getVersion()); } builder.setDscp(new Dscp(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset + 4, 6)))); builder.setEcn(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset + 10, 2))); builder.setFlowLabel(BitBufferHelper.getLong(BitBufferHelper.getBits(data, bitOffset + 12, 20))); builder.setIpv6Length(BitBufferHelper.getInt(BitBufferHelper.getBits(data, bitOffset + 32, 16))); builder.setNextHeader(KnownIpProtocols .forValue(BitBufferHelper.getInt(BitBufferHelper.getBits(data, bitOffset + 48, 8)))); builder.setHopLimit(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset + 56, 8))); builder.setSourceIpv6(Ipv6Address.getDefaultInstance( InetAddress.getByAddress(BitBufferHelper.getBits(data, bitOffset + 64, 128)).getHostAddress())); builder.setDestinationIpv6(Ipv6Address.getDefaultInstance( InetAddress.getByAddress(BitBufferHelper.getBits(data, bitOffset + 192, 128)).getHostAddress())); builder.setPayloadOffset((320 + bitOffset) / NetUtils.NUM_BITS_IN_A_BYTE); builder.setPayloadLength(builder.getIpv6Length()); List<ExtensionHeaders> extensionHeaders = new ArrayList<>(); KnownIpProtocols nextHeader = builder.getNextHeader(); int extHeaderOffset = 0; while (nextHeader != null && !nextHeader.equals(KnownIpProtocols.Tcp) && !nextHeader.equals(KnownIpProtocols.Udp)) { short nextHeaderType = BitBufferHelper .getShort(BitBufferHelper.getBits(data, 320 + extHeaderOffset + bitOffset, 8)); nextHeader = KnownIpProtocols.forValue(nextHeaderType); int octetLength = BitBufferHelper .getInt(BitBufferHelper.getBits(data, 328 + extHeaderOffset + bitOffset, 8)); int start = (336 + extHeaderOffset + bitOffset) / NetUtils.NUM_BITS_IN_A_BYTE; int end = start + 6 + octetLength; extensionHeaders.add(new ExtensionHeadersBuilder().setNextHeader(nextHeader).setLength(octetLength) .setData(Arrays.copyOfRange(data, start, end)).build()); extHeaderOffset += 64 + octetLength * NetUtils.NUM_BITS_IN_A_BYTE; } if (!extensionHeaders.isEmpty()) { builder.setExtensionHeaders(extensionHeaders); } } catch (BufferException | UnknownHostException e) { LOG.debug("Exception while decoding IPv4 packet", e.getMessage()); } packetChainList.add(new PacketChainBuilder().setPacket(builder.build()).build()); ipv6ReceivedBuilder.setPacketChain(packetChainList); ipv6ReceivedBuilder.setPayload(ethernetPacketReceived.getPayload()); return ipv6ReceivedBuilder.build(); } Ipv6Decoder(NotificationProviderService notificationProviderService); @Override Ipv6PacketReceived decode(EthernetPacketReceived ethernetPacketReceived); @Override NotificationListener getConsumedNotificationListener(); @Override void onEthernetPacketReceived(EthernetPacketReceived notification); @Override boolean canDecode(EthernetPacketReceived ethernetPacketReceived);  }
@Test public void testDecode() throws Exception { byte[] payload = { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xab, (byte) 0xcd, (byte) 0xef, 0x01, 0x23, 0x45, 0x67, (byte)0x86, (byte)0xdd, 0x60, (byte)0xf0, 0x00, 0x01, 0x00, 0x05, 0x11, (byte)0x0f, 0x01, 0x23, 0x45, 0x67, (byte)0x89, (byte)0xab, (byte)0xcd, (byte)0xef, (byte)0xfe, (byte)0xdc, (byte)0xba, (byte)0x98, 0x76, 0x54, 0x32, 0x10, (byte)0xfe, (byte)0xdc, (byte)0xba, (byte)0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, (byte)0x89, (byte)0xab, (byte)0xcd, (byte)0xef, 0x01, 0x02, 0x03, 0x04, 0x05, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }; NotificationProviderService npServiceMock = Mockito.mock(NotificationProviderService.class); ArrayList<PacketChain> packetChainList = new ArrayList<>(); packetChainList.add(new PacketChainBuilder().setPacket(new RawPacketBuilder().build()).build()); packetChainList.add( new PacketChainBuilder().setPacket(new EthernetPacketBuilder().setPayloadOffset(14).build()).build()); Ipv6PacketReceived notification = new Ipv6Decoder(npServiceMock).decode( new EthernetPacketReceivedBuilder().setPacketChain(packetChainList).setPayload(payload).build()); Ipv6Packet ipv6Packet = (Ipv6Packet) notification.getPacketChain().get(2).getPacket(); assertEquals(6, ipv6Packet.getVersion().intValue()); assertEquals(3, ipv6Packet.getDscp().getValue().intValue()); assertEquals(3, ipv6Packet.getEcn().intValue()); assertEquals(1, ipv6Packet.getFlowLabel().intValue()); assertEquals(5, ipv6Packet.getIpv6Length().intValue()); assertEquals(KnownIpProtocols.Udp, ipv6Packet.getNextHeader()); assertEquals(15, ipv6Packet.getHopLimit().intValue()); assertEquals("123:4567:89ab:cdef:fedc:ba98:7654:3210", ipv6Packet.getSourceIpv6().getValue()); assertEquals("fedc:ba98:7654:3210:123:4567:89ab:cdef", ipv6Packet.getDestinationIpv6().getValue()); assertNull(ipv6Packet.getExtensionHeaders()); assertEquals(54, ipv6Packet.getPayloadOffset().intValue()); assertEquals(5, ipv6Packet.getPayloadLength().intValue()); assertTrue(Arrays.equals(payload, notification.getPayload())); }
@Test public void testDecode_ExtensionHeader() throws Exception { byte[] payload = { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xab, (byte) 0xcd, (byte) 0xef, 0x01, 0x23, 0x45, 0x67, (byte)0x86, (byte)0xdd, 0x60, (byte)0xf0, 0x00, 0x01, 0x00, 0x0d, 0x00, (byte)0x0f, 0x01, 0x23, 0x45, 0x67, (byte)0x89, (byte)0xab, (byte)0xcd, (byte)0xef, (byte)0xfe, (byte)0xdc, (byte)0xba, (byte)0x98, 0x76, 0x54, 0x32, 0x10, (byte)0xfe, (byte)0xdc, (byte)0xba, (byte)0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, (byte)0x89, (byte)0xab, (byte)0xcd, (byte)0xef, 0x11, 0x00, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 0x01, 0x02, 0x03, 0x04, 0x05, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }; NotificationProviderService npServiceMock = Mockito.mock(NotificationProviderService.class); ArrayList<PacketChain> packetChainList = new ArrayList<>(); packetChainList.add(new PacketChainBuilder().setPacket(new RawPacketBuilder().build()).build()); packetChainList.add( new PacketChainBuilder().setPacket(new EthernetPacketBuilder().setPayloadOffset(14).build()).build()); Ipv6PacketReceived notification = new Ipv6Decoder(npServiceMock).decode( new EthernetPacketReceivedBuilder().setPacketChain(packetChainList).setPayload(payload).build()); Ipv6Packet ipv6Packet = (Ipv6Packet) notification.getPacketChain().get(2).getPacket(); assertEquals(6, ipv6Packet.getVersion().intValue()); assertEquals(3, ipv6Packet.getDscp().getValue().intValue()); assertEquals(3, ipv6Packet.getEcn().intValue()); assertEquals(1, ipv6Packet.getFlowLabel().intValue()); assertEquals(13, ipv6Packet.getIpv6Length().intValue()); assertEquals(KnownIpProtocols.Hopopt, ipv6Packet.getNextHeader()); assertEquals(15, ipv6Packet.getHopLimit().intValue()); assertEquals("123:4567:89ab:cdef:fedc:ba98:7654:3210", ipv6Packet.getSourceIpv6().getValue()); assertEquals("fedc:ba98:7654:3210:123:4567:89ab:cdef", ipv6Packet.getDestinationIpv6().getValue()); assertEquals(KnownIpProtocols.Udp, ipv6Packet.getExtensionHeaders().get(0).getNextHeader()); assertEquals(0, ipv6Packet.getExtensionHeaders().get(0).getLength().intValue()); assertTrue( Arrays.equals(ipv6Packet.getExtensionHeaders().get(0).getData(), Arrays.copyOfRange(payload, 56, 62))); assertEquals(54, ipv6Packet.getPayloadOffset().intValue()); assertEquals(13, ipv6Packet.getPayloadLength().intValue()); assertTrue(Arrays.equals(payload, notification.getPayload())); }
@Test public void testDecode_ExtensionHeaders() throws Exception { byte[] payload = { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xab, (byte) 0xcd, (byte) 0xef, 0x01, 0x23, 0x45, 0x67, (byte)0x86, (byte)0xdd, 0x60, (byte)0xf0, 0x00, 0x01, 0x00, 0x15, 0x00, (byte)0x0f, 0x01, 0x23, 0x45, 0x67, (byte)0x89, (byte)0xab, (byte)0xcd, (byte)0xef, (byte)0xfe, (byte)0xdc, (byte)0xba, (byte)0x98, 0x76, 0x54, 0x32, 0x10, (byte)0xfe, (byte)0xdc, (byte)0xba, (byte)0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, (byte)0x89, (byte)0xab, (byte)0xcd, (byte)0xef, 0x2b, 0x00, (byte)0xab, (byte)0xcd, (byte)0xef, (byte)0x12, (byte)0x34, (byte)0x56, 0x11, 0x00, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 0x01, 0x02, 0x03, 0x04, 0x05, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }; NotificationProviderService npServiceMock = Mockito.mock(NotificationProviderService.class); ArrayList<PacketChain> packetChainList = new ArrayList<>(); packetChainList.add(new PacketChainBuilder().setPacket(new RawPacketBuilder().build()).build()); packetChainList.add( new PacketChainBuilder().setPacket(new EthernetPacketBuilder().setPayloadOffset(14).build()).build()); Ipv6PacketReceived notification = new Ipv6Decoder(npServiceMock).decode( new EthernetPacketReceivedBuilder().setPacketChain(packetChainList).setPayload(payload).build()); Ipv6Packet ipv6Packet = (Ipv6Packet) notification.getPacketChain().get(2).getPacket(); assertEquals(6, ipv6Packet.getVersion().intValue()); assertEquals(3, ipv6Packet.getDscp().getValue().intValue()); assertEquals(3, ipv6Packet.getEcn().intValue()); assertEquals(1, ipv6Packet.getFlowLabel().intValue()); assertEquals(21, ipv6Packet.getIpv6Length().intValue()); assertEquals(KnownIpProtocols.Hopopt, ipv6Packet.getNextHeader()); assertEquals(15, ipv6Packet.getHopLimit().intValue()); assertEquals("123:4567:89ab:cdef:fedc:ba98:7654:3210", ipv6Packet.getSourceIpv6().getValue()); assertEquals("fedc:ba98:7654:3210:123:4567:89ab:cdef", ipv6Packet.getDestinationIpv6().getValue()); assertEquals(KnownIpProtocols.Ipv6Route, ipv6Packet.getExtensionHeaders().get(0).getNextHeader()); assertEquals(0, ipv6Packet.getExtensionHeaders().get(0).getLength().intValue()); assertTrue( Arrays.equals(ipv6Packet.getExtensionHeaders().get(0).getData(), Arrays.copyOfRange(payload, 56, 62))); assertEquals(KnownIpProtocols.Udp, ipv6Packet.getExtensionHeaders().get(1).getNextHeader()); assertEquals(0, ipv6Packet.getExtensionHeaders().get(1).getLength().intValue()); assertTrue( Arrays.equals(ipv6Packet.getExtensionHeaders().get(1).getData(), Arrays.copyOfRange(payload, 64, 70))); assertEquals(54, ipv6Packet.getPayloadOffset().intValue()); assertEquals(21, ipv6Packet.getPayloadLength().intValue()); assertTrue(Arrays.equals(payload, notification.getPayload())); }
@Test public void testDecode_Udp() throws Exception { byte[] payload = { 0x33, 0x33, 0x00, 0x00, 0x00, (byte)0xfb, (byte)0xa2, (byte)0xe6, (byte)0xda, 0x67, (byte)0xef, (byte)0x95, (byte)0x86, (byte)0xdd, 0x60, 0x00, 0x00, 0x00, 0x00, 0x35, 0x11, (byte)0xff, (byte)0xfe, (byte)0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)0xa0, (byte)0xe6, (byte)0xda, (byte)0xff, (byte)0xfe, 0x67, (byte)0xef, (byte)0x95, (byte)0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)0xfb, 0x14, (byte)0xe9, 0x14, (byte)0xe9, 0x00, 0x35, 0x6b, (byte)0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, 0x69, 0x70, 0x70, 0x73, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x04, 0x5f, 0x69, 0x70, 0x70, (byte)0xc0, 0x12, 0x00, 0x0c, 0x00, 0x01 }; NotificationProviderService npServiceMock = Mockito.mock(NotificationProviderService.class); ArrayList<PacketChain> packetChainList = new ArrayList<>(); packetChainList.add(new PacketChainBuilder().setPacket(new RawPacketBuilder().build()).build()); packetChainList.add( new PacketChainBuilder().setPacket(new EthernetPacketBuilder().setPayloadOffset(14).build()).build()); Ipv6PacketReceived notification = new Ipv6Decoder(npServiceMock).decode( new EthernetPacketReceivedBuilder().setPacketChain(packetChainList).setPayload(payload).build()); Ipv6Packet ipv6Packet = (Ipv6Packet) notification.getPacketChain().get(2).getPacket(); assertEquals(6, ipv6Packet.getVersion().intValue()); assertEquals(0, ipv6Packet.getDscp().getValue().intValue()); assertEquals(0, ipv6Packet.getEcn().intValue()); assertEquals(0, ipv6Packet.getFlowLabel().intValue()); assertEquals(53, ipv6Packet.getIpv6Length().intValue()); assertEquals(KnownIpProtocols.Udp, ipv6Packet.getNextHeader()); assertEquals(255, ipv6Packet.getHopLimit().intValue()); assertEquals("fe80:0:0:0:a0e6:daff:fe67:ef95", ipv6Packet.getSourceIpv6().getValue()); assertEquals("ff02:0:0:0:0:0:0:fb", ipv6Packet.getDestinationIpv6().getValue()); assertNull(ipv6Packet.getExtensionHeaders()); assertEquals(54, ipv6Packet.getPayloadOffset().intValue()); assertEquals(53, ipv6Packet.getPayloadLength().intValue()); assertTrue(Arrays.equals(payload, notification.getPayload())); }
@Test public void testDecode_AlternatingBits() throws Exception { byte[] payload = { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xab, (byte) 0xcd, (byte) 0xef, 0x01, 0x23, 0x45, 0x67, (byte)0x86, (byte)0xdd, 0x60, (byte)0x30, 0x00, 0x00, 0x00, 0x07, 0x06, (byte)0x0f, 0x01, 0x23, 0x45, 0x67, (byte)0x89, (byte)0xab, (byte)0xcd, (byte)0xef, (byte)0xfe, (byte)0xdc, (byte)0xba, (byte)0x98, 0x76, 0x54, 0x32, 0x10, (byte)0xfe, (byte)0xdc, (byte)0xba, (byte)0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, (byte)0x89, (byte)0xab, (byte)0xcd, (byte)0xef, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }; NotificationProviderService npServiceMock = Mockito.mock(NotificationProviderService.class); ArrayList<PacketChain> packetChainList = new ArrayList<>(); packetChainList.add(new PacketChainBuilder().setPacket(new RawPacketBuilder().build()).build()); packetChainList.add( new PacketChainBuilder().setPacket(new EthernetPacketBuilder().setPayloadOffset(14).build()).build()); Ipv6PacketReceived notification = new Ipv6Decoder(npServiceMock).decode( new EthernetPacketReceivedBuilder().setPacketChain(packetChainList).setPayload(payload).build()); Ipv6Packet ipv6Packet = (Ipv6Packet) notification.getPacketChain().get(2).getPacket(); assertEquals(6, ipv6Packet.getVersion().intValue()); assertEquals(0, ipv6Packet.getDscp().getValue().intValue()); assertEquals(3, ipv6Packet.getEcn().intValue()); assertEquals(0, ipv6Packet.getFlowLabel().intValue()); assertEquals(7, ipv6Packet.getIpv6Length().intValue()); assertEquals(KnownIpProtocols.Tcp, ipv6Packet.getNextHeader()); assertEquals(15, ipv6Packet.getHopLimit().intValue()); assertEquals("123:4567:89ab:cdef:fedc:ba98:7654:3210", ipv6Packet.getSourceIpv6().getValue()); assertEquals("fedc:ba98:7654:3210:123:4567:89ab:cdef", ipv6Packet.getDestinationIpv6().getValue()); assertNull(ipv6Packet.getExtensionHeaders()); assertEquals(54, ipv6Packet.getPayloadOffset().intValue()); assertEquals(7, ipv6Packet.getPayloadLength().intValue()); assertTrue(Arrays.equals(payload, notification.getPayload())); }