forked from KNEMC/KLALB
168 lines
3.9 KiB
Java
168 lines
3.9 KiB
Java
package org.kne.cloud.network.srv6;
|
|
|
|
import java.io.EOFException;
|
|
import java.io.IOException;
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.channels.ReadableByteChannel;
|
|
import java.nio.channels.WritableByteChannel;
|
|
|
|
import org.kne.cloud.network.NetworkPacket;
|
|
import org.kne.cloud.network.klalb.KLALBPacket;
|
|
|
|
public class IPv6SegmentRoutingTLV extends NetworkPacket {
|
|
public static final int PAD1=0;
|
|
public static final int PADN=4;
|
|
public static final int HMAC=5;
|
|
public static final int SEQS=7;
|
|
public static final int ACKSEQS=8;
|
|
|
|
private int headerLength=2;
|
|
|
|
public int getHeaderLength() {
|
|
return headerLength;
|
|
}
|
|
|
|
private boolean isDefault;
|
|
|
|
protected volatile ByteBuffer header;
|
|
|
|
private ByteBuffer data;
|
|
|
|
public IPv6SegmentRoutingTLV(ByteBuffer header ) {
|
|
this(header,true);
|
|
}
|
|
|
|
public ByteBuffer getData() {
|
|
return data;
|
|
}
|
|
|
|
public IPv6SegmentRoutingTLV(ByteBuffer header ,boolean isDefault ) {
|
|
super();
|
|
this.header = header;
|
|
this.isDefault=isDefault;
|
|
if(getType()==PAD1)
|
|
headerLength=1;
|
|
if(isDefault&&(headerLength>1)) {
|
|
data=ByteBuffer.allocate(512);
|
|
}
|
|
}
|
|
public IPv6SegmentRoutingTLV(int type) {
|
|
this(type,true);
|
|
}
|
|
public IPv6SegmentRoutingTLV(int type,boolean isDefault) {
|
|
super();
|
|
this.header=ByteBuffer.allocate(2);
|
|
this.isDefault=isDefault;
|
|
header.put((byte) type);
|
|
if(type==PAD1) {
|
|
headerLength=1;
|
|
}
|
|
if(isDefault&&(headerLength>1)) {
|
|
data=ByteBuffer.allocate(512);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public long getLength() {
|
|
return headerLength+(isDefault?data.limit():0);
|
|
}
|
|
|
|
public static IPv6SegmentRoutingTLV readIPv6SegmentRoutingTLVFromChannel(ReadableByteChannel din) throws IOException {
|
|
ByteBuffer bbf= ByteBuffer.allocate(2);
|
|
bbf.limit(1);
|
|
while (bbf.hasRemaining()) {
|
|
if (din.read(bbf) == -1) {
|
|
return null;
|
|
}
|
|
}
|
|
int type=bbf.get(0)&0xff;
|
|
IPv6SegmentRoutingTLV rtlv;
|
|
switch(type) {
|
|
case PAD1:
|
|
rtlv=new PAD1SegmentRoutingTLV(bbf);
|
|
rtlv.readFromChannel(din);
|
|
return rtlv;
|
|
case PADN:
|
|
rtlv=new PADNSegmentRoutingTLV(bbf);
|
|
rtlv.readFromChannel(din);
|
|
return rtlv;
|
|
case SEQS:
|
|
rtlv=new SEQSSegmentRoutingTLV(bbf);
|
|
rtlv.readFromChannel(din);
|
|
return rtlv;
|
|
case ACKSEQS:
|
|
rtlv=new ACKSEQSSegmentRoutingTLV(bbf);
|
|
rtlv.readFromChannel(din);
|
|
return rtlv;
|
|
default:
|
|
rtlv=new IPv6SegmentRoutingTLV(bbf);
|
|
rtlv.readFromChannel(din);
|
|
return rtlv;
|
|
}
|
|
}
|
|
public static void writeIPv6SegmentRoutingTLVToChannel(WritableByteChannel dto,IPv6SegmentRoutingTLV tlv) throws IOException {
|
|
tlv.writeToChannel(dto);
|
|
}
|
|
@Override
|
|
public void writeToChannel(WritableByteChannel dto) throws IOException {
|
|
if(isDefault&&(headerLength>1)) {
|
|
setDataLength(data.limit());
|
|
}
|
|
header.limit(headerLength);
|
|
dto.write(header.slice(0,header.limit()));
|
|
if(isDefault&&(headerLength>1)) {
|
|
dto.write(data.slice(0, data.limit()));
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
|
header.limit(1);
|
|
while (header.hasRemaining()) {
|
|
if (din.read(header) == -1) {
|
|
throw new EOFException();
|
|
}
|
|
}
|
|
if(headerLength>1) {
|
|
header.limit(2);
|
|
while (header.hasRemaining()) {
|
|
if (din.read(header) == -1) {
|
|
throw new EOFException();
|
|
}
|
|
}
|
|
}
|
|
header.flip();
|
|
|
|
if(isDefault&&(headerLength>1)) {
|
|
data.clear();
|
|
data.limit(getDataLength());
|
|
while(data.hasRemaining()){
|
|
if(din.read(data)==-1) {
|
|
throw new EOFException();
|
|
}
|
|
}
|
|
data.flip();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected boolean needEndPosition() {
|
|
return false;
|
|
}
|
|
|
|
public int getType() {
|
|
return header.get(0)&0xff;
|
|
}
|
|
public void setType(int type) {
|
|
header.put(0,(byte) type);
|
|
}
|
|
|
|
public int getDataLength() {
|
|
return header.get(1)&0xff;
|
|
}
|
|
|
|
public void setDataLength(int dataLength) {
|
|
header.put(1,(byte) dataLength);
|
|
}
|
|
}
|