package com.netifera.platform.net.packets.tcpip;
import com.netifera.platform.net.packets.AbstractPacket;
import com.netifera.platform.net.packets.IPacketHeader;
import com.netifera.platform.net.packets.PacketPayload;
import com.netifera.platform.util.NetworkConstants;
public class IPv6Fragment extends AbstractPacket implements IPFragment, IPv6Encapsulable {
private int nexthdr; // 8-bit selector.
private int reserved; // 8-bit reserved field.
private int frag_off = 0; // 13-bit unsigned integer.
//private int RF = 0; // 2-bit reserved field.
private int identification; // 32 bits.
/**
* The More-Fragments Flag carried in the header flags field.
*
* false = Last Fragment,
* true = More Fragments.
*/
private boolean MF = false;
public IPv6Fragment() {};
public IPv6Fragment(IPacketHeader payload) {
super(payload);
}
public IPv6 createPacket() {
return new IPv6();
}
@Override
protected int minimumHeaderLength() {
return 8;
}
@Override
protected void packHeader() {
pack8(nexthdr);
pack8(reserved);
pack16(packFlagsFragment());
pack32(identification);
}
@Override
protected void unpackHeader() {
nexthdr = unpack8();
reserved = unpack8();
unpackFlagsFragment(unpack16());
identification = unpack32();
}
private int packFlagsFragment() {
int n = frag_off / 8;
// TODO RF
if (MF) {
n |= FL_MF;
}
return n;
}
private void unpackFlagsFragment(int value) {
frag_off = (value & FRAGMENT_MASK) * 8;
//RF = (value & FL_RESERVED);
MF = ((value & FL_MF) != 0);
}
@Override
public String toString() {
StringBuffer out = new StringBuffer();
out.append("IPv6 Fragment ");
if (hasMoreFragments()) out.append(" (MF)");
out.append(" offset="+getFragmentOffset()+" length="+getLength());
return out.toString();
}
/**
* Identifies the initial header type of the Fragmentable Part of the
* original packet.
* Uses the same values as the IPv4 Protocol field
*/
@Override
protected int nextProtocol() {
return nexthdr;
}
@Override
public PacketPayload payload() {
return new PacketPayload(headerBufferSlice(getHeaderLength()));
}
public void setIdentification(int value) {
identification = value;
}
public int getIdentification() {
return identification;
}
public int protocolOverIPv6() {
return NetworkConstants.IPPROTO_IPv6Fragment;
}
public int getFragmentOffset() {
return frag_off;
}
public void setFragmentOffset(int value) {
verifyMaximum(value, FRAGMENT_MASK);
frag_off = value;
}
public boolean hasMoreFragments() {
return MF;
}
public void setMoreFragments(boolean value) {
MF = value;
}
public void setReserved(int value) {
reserved = value;
}
public int getReserved() {
return reserved;
}
}