ArpDecoder extends AbstractPacketDecoder<EthernetPacketReceived, ArpPacketReceived> implements EthernetPacketListener { @Override public ArpPacketReceived decode(EthernetPacketReceived ethernetPacketReceived) { ArpPacketReceivedBuilder arpReceivedBuilder = new ArpPacketReceivedBuilder(); 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(); ArpPacketBuilder builder = new ArpPacketBuilder(); try { builder.setHardwareType(KnownHardwareType .forValue(BitBufferHelper.getInt(BitBufferHelper.getBits(data, bitOffset + 0, 16)))); builder.setProtocolType( KnownEtherType.forValue(BitBufferHelper.getInt(BitBufferHelper.getBits(data, bitOffset + 16, 16)))); builder.setHardwareLength(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset + 32, 8))); builder.setProtocolLength(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset + 40, 8))); builder.setOperation( KnownOperation.forValue(BitBufferHelper.getInt(BitBufferHelper.getBits(data, bitOffset + 48, 16)))); int indexSrcProtAdd = 64 + 8 * builder.getHardwareLength(); int indexDstHardAdd = indexSrcProtAdd + 8 * builder.getProtocolLength(); int indexDstProtAdd = indexDstHardAdd + 8 * builder.getHardwareLength(); if (builder.getHardwareType().equals(KnownHardwareType.Ethernet)) { builder.setSourceHardwareAddress(HexEncode.bytesToHexStringFormat( BitBufferHelper.getBits(data, bitOffset + 64, 8 * builder.getHardwareLength()))); builder.setDestinationHardwareAddress(HexEncode.bytesToHexStringFormat( BitBufferHelper.getBits(data, bitOffset + indexDstHardAdd, 8 * builder.getHardwareLength()))); } else { LOG.debug( "Unknown HardwareType -- sourceHardwareAddress and destinationHardwareAddress are not decoded"); } if (builder.getProtocolType().equals(KnownEtherType.Ipv4) || builder.getProtocolType().equals(KnownEtherType.Ipv6)) { builder.setSourceProtocolAddress(InetAddress.getByAddress( BitBufferHelper.getBits(data, bitOffset + indexSrcProtAdd, 8 * builder.getProtocolLength())) .getHostAddress()); builder.setDestinationProtocolAddress(InetAddress.getByAddress( BitBufferHelper.getBits(data, bitOffset + indexDstProtAdd, 8 * builder.getProtocolLength())) .getHostAddress()); } else { LOG.debug( "Unknown ProtocolType -- sourceProtocolAddress and destinationProtocolAddress are not decoded"); } } catch (BufferException | UnknownHostException e) { LOG.debug("Exception while decoding APR packet", e.getMessage()); } packetChainList.add(new PacketChainBuilder().setPacket(builder.build()).build()); arpReceivedBuilder.setPacketChain(packetChainList); arpReceivedBuilder.setPayload(ethernetPacketReceived.getPayload()); return arpReceivedBuilder.build(); } ArpDecoder(NotificationProviderService notificationProviderService); @Override ArpPacketReceived decode(EthernetPacketReceived ethernetPacketReceived); @Override NotificationListener getConsumedNotificationListener(); @Override void onEthernetPacketReceived(EthernetPacketReceived notification); @Override boolean canDecode(EthernetPacketReceived ethernetPacketReceived);  }
@Test public void testDecode_RequestIPv4() throws Exception { byte[] packet = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xab, (byte)0xc0, (byte)0xa8, 0x00, 0x01, (byte) 0xcd, (byte) 0xef, 0x01, 0x23, 0x45, 0x67, 0x01, 0x02, 0x03, 0x04 }; NotificationProviderService mock = 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(5).setPayloadLength(33).build()).build()); ArpPacketReceived notification = new ArpDecoder(mock) .decode(new EthernetPacketReceivedBuilder().setPacketChain(packetChainList).setPayload(packet).build()); ArpPacket arpPacket = (ArpPacket) notification.getPacketChain().get(2).getPacket(); assertEquals(KnownHardwareType.Ethernet, arpPacket.getHardwareType()); assertEquals(KnownEtherType.Ipv4, arpPacket.getProtocolType()); assertEquals(6, arpPacket.getHardwareLength().intValue()); assertEquals(4, arpPacket.getProtocolLength().intValue()); assertEquals(KnownOperation.Request, arpPacket.getOperation()); assertEquals("01:23:45:67:89:ab", arpPacket.getSourceHardwareAddress()); assertEquals("192.168.0.1", arpPacket.getSourceProtocolAddress()); assertEquals("cd:ef:01:23:45:67", arpPacket.getDestinationHardwareAddress()); assertEquals("1.2.3.4", arpPacket.getDestinationProtocolAddress()); }
@Test public void testDecode_ReplyIPv4() throws Exception { byte[] packet = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x02, 0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xab, (byte)0xc0, (byte)0xa8, 0x00, 0x01, (byte) 0xcd, (byte) 0xef, 0x01, 0x23, 0x45, 0x67, 0x01, 0x02, 0x03, 0x04 }; NotificationProviderService mock = 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(8).setPayloadLength(36).build()).build()); ArpPacketReceived notification = new ArpDecoder(mock) .decode(new EthernetPacketReceivedBuilder().setPacketChain(packetChainList).setPayload(packet).build()); ArpPacket arpPacket = (ArpPacket) notification.getPacketChain().get(2).getPacket(); assertEquals(KnownHardwareType.Ethernet, arpPacket.getHardwareType()); assertEquals(KnownEtherType.Ipv4, arpPacket.getProtocolType()); assertEquals(6, arpPacket.getHardwareLength().intValue()); assertEquals(4, arpPacket.getProtocolLength().intValue()); assertEquals(KnownOperation.Reply, arpPacket.getOperation()); assertEquals("01:23:45:67:89:ab", arpPacket.getSourceHardwareAddress()); assertEquals("192.168.0.1", arpPacket.getSourceProtocolAddress()); assertEquals("cd:ef:01:23:45:67", arpPacket.getDestinationHardwareAddress()); assertEquals("1.2.3.4", arpPacket.getDestinationProtocolAddress()); }
@Test public void testDecode_Broadcast() throws Exception { byte[] packet = { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xba, 0x43, 0x52, (byte)0xce, 0x09, (byte)0xf4, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, (byte)0xba, 0x43, 0x52, (byte)0xce, 0x09, (byte)0xf4, 0x0a, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x02 }; NotificationProviderService mock = 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()); ArpPacketReceived notification = new ArpDecoder(mock) .decode(new EthernetPacketReceivedBuilder().setPacketChain(packetChainList).setPayload(packet).build()); ArpPacket arpPacket = (ArpPacket) notification.getPacketChain().get(2).getPacket(); assertEquals(KnownHardwareType.Ethernet, arpPacket.getHardwareType()); assertEquals(KnownEtherType.Ipv4, arpPacket.getProtocolType()); assertEquals(6, arpPacket.getHardwareLength().intValue()); assertEquals(4, arpPacket.getProtocolLength().intValue()); assertEquals(KnownOperation.Request, arpPacket.getOperation()); assertEquals("ba:43:52:ce:09:f4", arpPacket.getSourceHardwareAddress()); assertEquals("10.0.0.1", arpPacket.getSourceProtocolAddress()); assertEquals("00:00:00:00:00:00", arpPacket.getDestinationHardwareAddress()); assertEquals("10.0.0.2", arpPacket.getDestinationProtocolAddress()); }