package org.zarroboogs.smartzpn.tcpip;
import org.zarroboogs.smartzpn.utils.ProxyUtils;
import java.util.Locale;
public class IPHeader {
public static final short IP = 0x0800;
public static final byte ICMP = 1;
public static final byte TCP = 6;
public static final byte UDP = 17;
private static final byte offset_ver_ihl = 0; // 0: Version (4 bits) + Internet header length (4// bits)
private static final byte offset_tos = 1; // 1: Type of service
private static final short offset_tlen = 2; // 2: Total length
private static final short offset_identification = 4; // :4 Identification
private static final short offset_flags_fo = 6; // 6: Flags (3 bits) + Fragment offset (13 bits)
private static final byte offset_ttl = 8; // 8: Time to live
public static final byte offset_proto = 9; // 9: Protocol
public static final short offset_crc = 10; // 10: Header checksum
public static final int offset_src_ip = 12; // 12: Source address
public static final int offset_dest_ip = 16; // 16: Destination address
public static final int offset_op_pad = 20; // 20: Option + Padding
public byte[] mData;
public int mOffset;
public IPHeader(byte[] data, int offset) {
this.mData = data;
this.mOffset = offset;
}
public void Default() {
setHeaderLength(20);
setTos((byte) 0);
setTotalLength(0);
setIdentification(0);
setFlagsAndOffset((short) 0);
setTTL((byte) 64);
}
public int getDataLength() {
return this.getTotalLength() - this.getHeaderLength();
}
public int getHeaderLength() {
return (mData[mOffset + offset_ver_ihl] & 0x0F) * 4;
}
public void setHeaderLength(int value) {
mData[mOffset + offset_ver_ihl] = (byte) ((4 << 4) | (value / 4));
}
public byte getTos() {
return mData[mOffset + offset_tos];
}
public void setTos(byte value) {
mData[mOffset + offset_tos] = value;
}
public int getTotalLength() {
return ProxyUtils.readShort(mData, mOffset + offset_tlen) & 0xFFFF;
}
public void setTotalLength(int value) {
ProxyUtils.writeShort(mData, mOffset + offset_tlen, (short) value);
}
public int getIdentification() {
return ProxyUtils.readShort(mData, mOffset + offset_identification) & 0xFFFF;
}
public void setIdentification(int value) {
ProxyUtils.writeShort(mData, mOffset + offset_identification, (short) value);
}
public short getFlagsAndOffset() {
return ProxyUtils.readShort(mData, mOffset + offset_flags_fo);
}
public void setFlagsAndOffset(short value) {
ProxyUtils.writeShort(mData, mOffset + offset_flags_fo, value);
}
public byte getTTL() {
return mData[mOffset + offset_ttl];
}
public void setTTL(byte value) {
mData[mOffset + offset_ttl] = value;
}
public byte getProtocol() {
return mData[mOffset + offset_proto];
}
public void setProtocol(byte value) {
mData[mOffset + offset_proto] = value;
}
public short getCrc() {
return ProxyUtils.readShort(mData, mOffset + offset_crc);
}
public void setCrc(short value) {
ProxyUtils.writeShort(mData, mOffset + offset_crc, value);
}
public int getSourceIP() {
return ProxyUtils.readInt(mData, mOffset + offset_src_ip);
}
public void setSourceIP(int value) {
ProxyUtils.writeInt(mData, mOffset + offset_src_ip, value);
}
public int getDestinationIP() {
return ProxyUtils.readInt(mData, mOffset + offset_dest_ip);
}
public void setDestinationIP(int value) {
ProxyUtils.writeInt(mData, mOffset + offset_dest_ip, value);
}
@Override
public String toString() {
return String.format(Locale.ENGLISH, "%s->%s Pro=%s,HLen=%d", ProxyUtils.ipIntToString(getSourceIP()), ProxyUtils.ipIntToString(getDestinationIP()), getProtocol(), getHeaderLength());
}
}