package com.netifera.platform.net.packets.decoders; import java.nio.ByteBuffer; import com.netifera.platform.net.packets.IPacketDecoder; import com.netifera.platform.net.packets.IPacketHeader; import com.netifera.platform.net.packets.PacketPayload; import com.netifera.platform.net.packets.tcpip.IP; abstract public class AbstractIPDecoder implements IPacketDecoder { public IPacketHeader decode(ByteBuffer buffer) { final IP ip = createIP(); final ByteBuffer ipBuffer = buffer.slice(); if(!ip.unpack(ipBuffer)) { return new PacketPayload(ipBuffer); } final int ipPayloadLength = ip.getTotalLength() - ip.getHeaderLength(); if(ipPayloadLength < 0) { throw new IllegalStateException("isValidHeader() is broken for " + ip.getClass().getCanonicalName()); } /* If packet is longer than IP header expects, then just trim it to the right length */ if(ipPayloadLength < ipBuffer.remaining()) { final int trimCount = ipBuffer.remaining() - ipPayloadLength; ipBuffer.limit(ipBuffer.limit() - trimCount); } ip.setNextPacket(decodeNext(ip.getNextProtocol(), ipBuffer.slice())); return ip; } protected abstract IP createIP(); protected abstract IPacketHeader decodeNext(int protocol, ByteBuffer buffer); }