IPv6 extends BasePacket { @Override public IPacket deserialize(byte[] data, int offset, int length) throws PacketParsingException { ByteBuffer bb = ByteBuffer.wrap(data, offset, length); byte firstByte = bb.get(); byte secondByte = bb.get(); this.version = (byte) ((firstByte & 0xF0) >>> 4); if (this.version != 6) { throw new PacketParsingException( "Invalid version for IPv6 packet: " + this.version); } this.trafficClass = (byte) (((firstByte & 0xF) << 4) | ((secondByte & 0xF0) >>> 4)); this.flowLabel = ((secondByte & 0xF) << 16) | (bb.getShort() & 0xFFFF); this.payloadLength = bb.getShort(); this.nextHeader = IpProtocol.of(bb.get()); this.hopLimit = bb.get(); byte[] sourceAddress = new byte[16]; bb.get(sourceAddress, 0, 16); byte[] destinationAddress = new byte[16]; bb.get(destinationAddress, 0, 16); this.sourceAddress = IPv6Address.of(sourceAddress); this.destinationAddress = IPv6Address.of(destinationAddress); IPacket payload; if (IPv6.nextHeaderClassMap.containsKey(this.nextHeader)) { Class<? extends IPacket> clazz = IPv6.nextHeaderClassMap.get(this.nextHeader); try { payload = clazz.newInstance(); } catch (Exception e) { throw new RuntimeException("Error parsing payload for IPv6 packet", e); } } else { payload = new Data(); } this.payload = payload.deserialize(data, bb.position(), Math.min(this.payloadLength, bb.limit() - bb.position())); this.payload.setParent(this); return this; } IPv6(); byte getVersion(); IPv6 setVersion(byte version); byte getTrafficClass(); IPv6 setTrafficClass(byte trafficClass); int getFlowLabel(); IPv6 setFlowLabel(int flowLabel); short getPayloadLength(); IPv6 setPayloadLength(short payloadLength); IpProtocol getNextHeader(); IPv6 setNextHeader(IpProtocol nextHeader); byte getHopLimit(); IPv6 setHopLimit(byte hopLimit); IPv6Address getSourceAddress(); IPv6 setSourceAddress(IPv6Address sourceAddress); IPv6Address getDestinationAddress(); IPv6 setDestinationAddress(IPv6Address destinationAddress); @Override byte[] serialize(); @Override String toString(); @Override IPacket deserialize(byte[] data, int offset, int length); @Override int hashCode(); @Override boolean equals(Object obj); static Map<IpProtocol, Class<? extends IPacket>> nextHeaderClassMap; static final int HEADER_LENGTH; }
@Test public void testDeserialize() throws PacketParsingException { byte[] spudPacket = { 0x64, 0x2B, 0x16, (byte) 0x95, 0x00, 0x15, 0x11, (byte) 0xE1, (byte) 0xFE, (byte) 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7A, (byte) 0xC5, (byte) 0xFF, (byte) 0xFE, 0x2E, 0x77, 0x35, (byte) 0xFE, (byte) 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x5D, (byte) 0xFF, (byte) 0xFE, (byte) 0xC2, 0x30, (byte) 0xFD, (byte) 0xD2, 0x01, 0x05, 0x7A, 0x00, 0x15, (byte) 0xF6, (byte) 0xC8, (byte) 0xD8, 0x00, 0x00, (byte) 0xD8, 0x4A, (byte) 0xC3, (byte) 0xF2, 0x02, 0x44, 0x75, (byte) 0x97, 0x69, 0x40 }; IPv6 packet = new IPv6(); packet.deserialize(spudPacket, 0, spudPacket.length); byte[] packetSerialized = packet.serialize(); assertTrue(Arrays.equals(spudPacket, packetSerialized)); }