Ipv4Decoder extends AbstractPacketDecoder<EthernetPacketReceived, Ipv4PacketReceived> implements EthernetPacketListener { @Override public Ipv4PacketReceived decode(EthernetPacketReceived ethernetPacketReceived) { Ipv4PacketReceivedBuilder ipv4ReceivedBuilder = new Ipv4PacketReceivedBuilder(); 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(); Ipv4PacketBuilder builder = new Ipv4PacketBuilder(); try { builder.setVersion(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset, 4))); if (builder.getVersion().intValue() != 4) { LOG.debug("Version should be 4, but is {}", builder.getVersion()); } builder.setIhl(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset + 4, 4))); builder.setDscp(new Dscp(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset + 8, 6)))); builder.setEcn(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset + 14, 2))); builder.setIpv4Length(BitBufferHelper.getInt(BitBufferHelper.getBits(data, bitOffset + 16, 16))); builder.setId(BitBufferHelper.getInt(BitBufferHelper.getBits(data, bitOffset + 32, 16))); builder.setReservedFlag(1 == (BitBufferHelper.getBits(data, bitOffset + 48, 1)[0] & 0xff)); if (builder.isReservedFlag()) { LOG.debug("Reserved flag should be 0, but is 1."); } builder.setDfFlag(1 == (BitBufferHelper.getBits(data, bitOffset + 49, 1)[0] & 0xff)); builder.setMfFlag(1 == (BitBufferHelper.getBits(data, bitOffset + 50, 1)[0] & 0xff)); builder.setFragmentOffset(BitBufferHelper.getInt(BitBufferHelper.getBits(data, bitOffset + 51, 13))); builder.setTtl(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset + 64, 8))); builder.setProtocol(KnownIpProtocols .forValue(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset + 72, 8)))); builder.setChecksum(BitBufferHelper.getInt(BitBufferHelper.getBits(data, bitOffset + 80, 16))); builder.setSourceIpv4(Ipv4Address.getDefaultInstance( InetAddress.getByAddress(BitBufferHelper.getBits(data, bitOffset + 96, 32)).getHostAddress())); builder.setDestinationIpv4(Ipv4Address.getDefaultInstance( InetAddress.getByAddress(BitBufferHelper.getBits(data, bitOffset + 128, 32)).getHostAddress())); int optionsSize = (builder.getIhl() - 5) * 32; if (optionsSize > 0) { builder.setIpv4Options(BitBufferHelper.getBits(data, bitOffset + 160, optionsSize)); } int payloadStartInBits = bitOffset + 160 + optionsSize; int payloadEndInBits = data.length * NetUtils.NUM_BITS_IN_A_BYTE - payloadStartInBits - 4 * NetUtils.NUM_BITS_IN_A_BYTE; int start = payloadStartInBits / NetUtils.NUM_BITS_IN_A_BYTE; int end = start + payloadEndInBits / NetUtils.NUM_BITS_IN_A_BYTE; builder.setPayloadOffset(start); builder.setPayloadLength(end - start); } catch (BufferException | UnknownHostException e) { LOG.debug("Exception while decoding IPv4 packet", e.getMessage()); } packetChainList.add(new PacketChainBuilder().setPacket(builder.build()).build()); ipv4ReceivedBuilder.setPacketChain(packetChainList); ipv4ReceivedBuilder.setPayload(ethernetPacketReceived.getPayload()); return ipv4ReceivedBuilder.build(); } Ipv4Decoder(NotificationProviderService notificationProviderService); @Override Ipv4PacketReceived decode(EthernetPacketReceived ethernetPacketReceived); @Override NotificationListener getConsumedNotificationListener(); @Override void onEthernetPacketReceived(EthernetPacketReceived notification); @Override boolean canDecode(EthernetPacketReceived ethernetPacketReceived);  }
@Test public void testDecode() throws Exception { byte[] ethPayload = { 0x01, 0x23, 0x66, 0x67, (byte) 0x89, (byte) 0xab, (byte) 0xcd, (byte) 0xef, 0x01, 0x23, 0x45, 0x67, 0x08, 0x00, 0x45, 0x00, 0x00, 0x1E, 0x01, 0x1E, 0x00, 0x00, 0x12, 0x11, 0x00, 0x00, (byte) 0xc0, (byte) 0xa8, 0x00, 0x01, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, (byte) 0x98, (byte) 0xfe, (byte) 0xdc, (byte) 0xba }; 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()); Ipv4PacketReceived notification = new Ipv4Decoder(npServiceMock).decode( new EthernetPacketReceivedBuilder().setPacketChain(packetChainList).setPayload(ethPayload).build()); Ipv4Packet ipv4Packet = (Ipv4Packet) notification.getPacketChain().get(2).getPacket(); assertEquals(4, ipv4Packet.getVersion().intValue()); assertEquals(5, ipv4Packet.getIhl().intValue()); assertEquals(30, ipv4Packet.getIpv4Length().intValue()); assertEquals(0, ipv4Packet.getDscp().getValue().intValue()); assertEquals(0, ipv4Packet.getEcn().intValue()); assertEquals(30, ipv4Packet.getIpv4Length().intValue()); assertEquals(286, ipv4Packet.getId().intValue()); assertFalse(ipv4Packet.isReservedFlag()); assertFalse(ipv4Packet.isDfFlag()); assertFalse(ipv4Packet.isMfFlag()); assertEquals(0, ipv4Packet.getFragmentOffset().intValue()); assertEquals(18, ipv4Packet.getTtl().intValue()); assertEquals(KnownIpProtocols.Udp, ipv4Packet.getProtocol()); assertEquals(0, ipv4Packet.getChecksum().intValue()); Ipv4Address srcAddress = new Ipv4Address("192.168.0.1"); Ipv4Address dstAddress = new Ipv4Address("1.2.3.4"); assertEquals(srcAddress, ipv4Packet.getSourceIpv4()); assertEquals(dstAddress, ipv4Packet.getDestinationIpv4()); assertEquals(10, ipv4Packet.getPayloadLength().intValue()); assertEquals(34, ipv4Packet.getPayloadOffset().intValue()); assertTrue(Arrays.equals(ethPayload, notification.getPayload())); }
@Test public void testDecode_WithDiffServAndFlagsAndOffset() throws Exception { byte[] ethPayload = { 0x01, 0x23, 0x66, 0x67, (byte) 0x89, (byte) 0xab, (byte) 0xcd, (byte) 0xef, 0x01, 0x23, 0x45, 0x67, (byte) 0x81, 0x00, 0x08, 0x00, 0x45, (byte) 0xff, 0x00, 0x1E, 0x01, 0x1E, (byte) 0xf0, 0x00, 0x12, 0x06, (byte) 0x00, 0x00, (byte) 0xc0, (byte) 0xa8, 0x00, 0x01, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, (byte) 0x98, (byte) 0xfe, (byte) 0xdc, (byte) 0xba }; 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(16).build()).build()); Ipv4PacketReceived notification = new Ipv4Decoder(npServiceMock).decode( new EthernetPacketReceivedBuilder().setPacketChain(packetChainList).setPayload(ethPayload).build()); Ipv4Packet ipv4Packet = (Ipv4Packet) notification.getPacketChain().get(2).getPacket(); assertEquals(4, ipv4Packet.getVersion().intValue()); assertEquals(5, ipv4Packet.getIhl().intValue()); assertEquals(30, ipv4Packet.getIpv4Length().intValue()); assertEquals(63, ipv4Packet.getDscp().getValue().intValue()); assertEquals(3, ipv4Packet.getEcn().intValue()); assertEquals(30, ipv4Packet.getIpv4Length().intValue()); assertEquals(286, ipv4Packet.getId().intValue()); assertTrue(ipv4Packet.isReservedFlag()); assertTrue(ipv4Packet.isDfFlag()); assertTrue(ipv4Packet.isMfFlag()); assertEquals(4096, ipv4Packet.getFragmentOffset().intValue()); assertEquals(18, ipv4Packet.getTtl().intValue()); assertEquals(KnownIpProtocols.Tcp, ipv4Packet.getProtocol()); assertEquals(0, ipv4Packet.getChecksum().intValue()); Ipv4Address srcAddress = new Ipv4Address("192.168.0.1"); Ipv4Address dstAddress = new Ipv4Address("1.2.3.4"); assertEquals(srcAddress, ipv4Packet.getSourceIpv4()); assertEquals(dstAddress, ipv4Packet.getDestinationIpv4()); assertEquals(13, ipv4Packet.getPayloadLength().intValue()); assertEquals(36, ipv4Packet.getPayloadOffset().intValue()); assertTrue(Arrays.equals(ethPayload, notification.getPayload())); }
@Test public void testDecode_AlternatingBits() throws Exception { byte[] ethPayload = { 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xab, (byte) 0xcd, (byte) 0xef, 0x01, 0x23, 0x45, 0x67, (byte) 0x81, 0x00, (byte) 0xff, (byte) 0xff, (byte) 0x86, (byte) 0xdd, (byte) 0xf5, (byte) 0x0f, 0x00, 0x00, (byte) 0xff, (byte) 0xff, (byte) 0x1f, (byte) 0xff, 0x00, 0x06, (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x00, 0x00, 0x00, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, (byte) 0x98, (byte) 0xfe, (byte) 0xdc, (byte) 0xba }; 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(18).build()).build()); Ipv4PacketReceived notification = new Ipv4Decoder(npServiceMock).decode( new EthernetPacketReceivedBuilder().setPacketChain(packetChainList).setPayload(ethPayload).build()); Ipv4Packet ipv4Packet = (Ipv4Packet) notification.getPacketChain().get(2).getPacket(); assertEquals(15, ipv4Packet.getVersion().intValue()); assertEquals(5, ipv4Packet.getIhl().intValue()); assertEquals(0, ipv4Packet.getIpv4Length().intValue()); assertEquals(3, ipv4Packet.getDscp().getValue().intValue()); assertEquals(3, ipv4Packet.getEcn().intValue()); assertEquals(0, ipv4Packet.getIpv4Length().intValue()); assertEquals(65535, ipv4Packet.getId().intValue()); assertFalse(ipv4Packet.isReservedFlag()); assertFalse(ipv4Packet.isDfFlag()); assertFalse(ipv4Packet.isMfFlag()); assertEquals(8191, ipv4Packet.getFragmentOffset().intValue()); assertEquals(0, ipv4Packet.getTtl().intValue()); assertEquals(KnownIpProtocols.Tcp, ipv4Packet.getProtocol()); assertEquals(65535, ipv4Packet.getChecksum().intValue()); Ipv4Address srcAddress = new Ipv4Address("0.0.0.0"); Ipv4Address dstAddress = new Ipv4Address("255.255.255.255"); assertEquals(srcAddress, ipv4Packet.getSourceIpv4()); assertEquals(dstAddress, ipv4Packet.getDestinationIpv4()); assertEquals(10, ipv4Packet.getPayloadLength().intValue()); assertEquals(38, ipv4Packet.getPayloadOffset().intValue()); assertTrue(Arrays.equals(ethPayload, notification.getPayload())); }
@Test public void testDecode_Udp() throws Exception { byte[] ethPayload = { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 0x06, 0x27, 0x25, 0x06, (byte)0x81, (byte)0x81, 0x08, 0x00, 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00, (byte)0x80, 0x11, 0x39, (byte)0x96, 0x00, 0x00, 0x00, 0x00, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 0x00, 0x44, 0x00, 0x43, 0x01, 0x34, 0x2d, (byte)0xf5, 0x01, 0x01, 0x06, 0x00, (byte)0xdf, (byte)0xcc }; 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()); Ipv4PacketReceived notification = new Ipv4Decoder(npServiceMock).decode( new EthernetPacketReceivedBuilder().setPacketChain(packetChainList).setPayload(ethPayload).build()); Ipv4Packet ipv4Packet = (Ipv4Packet) notification.getPacketChain().get(2).getPacket(); assertEquals(4, ipv4Packet.getVersion().intValue()); assertEquals(5, ipv4Packet.getIhl().intValue()); assertEquals(4, ipv4Packet.getDscp().getValue().intValue()); assertEquals(0, ipv4Packet.getEcn().intValue()); assertEquals(328, ipv4Packet.getIpv4Length().intValue()); assertEquals(0, ipv4Packet.getId().intValue()); assertFalse(ipv4Packet.isReservedFlag()); assertFalse(ipv4Packet.isDfFlag()); assertFalse(ipv4Packet.isMfFlag()); assertEquals(0, ipv4Packet.getFragmentOffset().intValue()); assertEquals(128, ipv4Packet.getTtl().intValue()); assertEquals(KnownIpProtocols.Udp, ipv4Packet.getProtocol()); assertEquals(14742, ipv4Packet.getChecksum().intValue()); Ipv4Address srcAddress = new Ipv4Address("0.0.0.0"); Ipv4Address dstAddress = new Ipv4Address("255.255.255.255"); assertEquals(srcAddress, ipv4Packet.getSourceIpv4()); assertEquals(dstAddress, ipv4Packet.getDestinationIpv4()); assertEquals(34, ipv4Packet.getPayloadOffset().intValue()); assertTrue(Arrays.equals(ethPayload, notification.getPayload())); }