org.pcap4j.packet.IpV4Packet Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pcap4j-core Show documentation
Show all versions of pcap4j-core Show documentation
The core module of Pcap4J.
/*_##########################################################################
_##
_## Copyright (C) 2011-2014 Pcap4J.org
_##
_##########################################################################
*/
package org.pcap4j.packet;
import static org.pcap4j.util.ByteArrays.*;
import java.io.Serializable;
import java.net.Inet4Address;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.pcap4j.packet.factory.PacketFactories;
import org.pcap4j.packet.namednumber.IpNumber;
import org.pcap4j.packet.namednumber.IpV4OptionType;
import org.pcap4j.packet.namednumber.IpVersion;
import org.pcap4j.packet.namednumber.NotApplicable;
import org.pcap4j.util.ByteArrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Kaito Yamada
* @since pcap4j 0.9.1
*/
public final class IpV4Packet extends AbstractPacket {
// http://tools.ietf.org/html/rfc791
/**
*
*/
private static final long serialVersionUID = 5348211496230027548L;
private static final Logger logger = LoggerFactory.getLogger(IpV4Packet.class);
private final IpV4Header header;
private final Packet payload;
/**
* A static factory method.
* This method validates the arguments by {@link ByteArrays#validateBounds(byte[], int, int)},
* which may throw exceptions undocumented here.
*
* @param rawData rawData
* @param offset offset
* @param length length
* @return a new IpV4Packet object.
* @throws IllegalRawDataException if parsing the raw data fails.
*/
public static IpV4Packet newPacket(
byte[] rawData, int offset, int length
) throws IllegalRawDataException {
ByteArrays.validateBounds(rawData, offset, length);
return new IpV4Packet(rawData, offset, length);
}
private IpV4Packet(byte[] rawData, int offset, int length) throws IllegalRawDataException {
this.header = new IpV4Header(rawData, offset, length);
int remainingRawDataLength = length - header.length();
int totalLength = header.getTotalLengthAsInt();
int payloadLength;
if (totalLength == 0) {
logger.debug("Total Length is 0. Assuming segmentation offload to be working.");
payloadLength = remainingRawDataLength;
}
else {
payloadLength = totalLength - header.length();
if (payloadLength < 0) {
throw new IllegalRawDataException(
"The value of total length field seems to be wrong: " + totalLength
);
}
if (payloadLength > remainingRawDataLength) {
payloadLength = remainingRawDataLength;
}
}
if (payloadLength != 0) { // payloadLength is positive.
if (header.getMoreFragmentFlag() || header.getFragmentOffset() != 0) {
this.payload
= PacketFactories.getFactory(Packet.class, NotApplicable.class)
.newInstance(rawData, header.length() + offset, payloadLength, NotApplicable.FRAGMENTED);
}
else {
this.payload
= PacketFactories.getFactory(Packet.class, IpNumber.class)
.newInstance(rawData, header.length() + offset, payloadLength, header.getProtocol());
}
}
else {
this.payload = null;
}
}
private IpV4Packet(Builder builder) {
if (
builder == null
|| builder.version == null
|| builder.tos == null
|| builder.protocol == null
|| builder.srcAddr == null
|| builder.dstAddr == null
) {
StringBuilder sb = new StringBuilder();
sb.append("builder: ").append(builder)
.append(" builder.version: ").append(builder.version)
.append(" builder.tos: ").append(builder.tos)
.append(" builder.protocol: ").append(builder.protocol)
.append(" builder.srcAddr: ").append(builder.srcAddr)
.append(" builder.dstAddr: ").append(builder.dstAddr);
throw new NullPointerException(sb.toString());
}
this.payload = builder.payloadBuilder != null ? builder.payloadBuilder.build() : null;
this.header = new IpV4Header(builder, payload);
}
@Override
public IpV4Header getHeader() {
return header;
}
@Override
public Packet getPayload() {
return payload;
}
@Override
public Builder getBuilder() {
return new Builder(this);
}
/**
* @author Kaito Yamada
* @since pcap4j 0.9.1
*/
public static final
class Builder extends AbstractBuilder
implements ChecksumBuilder, LengthBuilder {
private IpVersion version;
private byte ihl;
private IpV4Tos tos;
private short totalLength;
private short identification;
private boolean reservedFlag;
private boolean dontFragmentFlag;
private boolean moreFragmentFlag;
private short fragmentOffset;
private byte ttl;
private IpNumber protocol;
private short headerChecksum;
private Inet4Address srcAddr;
private Inet4Address dstAddr;
private List options;
private byte[] padding;
private Packet.Builder payloadBuilder;
private boolean correctChecksumAtBuild;
private boolean correctLengthAtBuild;
private boolean paddingAtBuild;
/**
*
*/
public Builder() {}
/**
*
* @param packet packet
*/
public Builder(IpV4Packet packet) {
this.version = packet.header.version;
this.ihl = packet.header.ihl;
this.tos = packet.header.tos;
this.totalLength = packet.header.totalLength;
this.identification = packet.header.identification;
this.reservedFlag = packet.header.reservedFlag;
this.dontFragmentFlag = packet.header.dontFragmentFlag;
this.moreFragmentFlag = packet.header.moreFragmentFlag;
this.fragmentOffset = packet.header.fragmentOffset;
this.ttl = packet.header.ttl;
this.protocol = packet.header.protocol;
this.headerChecksum = packet.header.headerChecksum;
this.srcAddr = packet.header.srcAddr;
this.dstAddr = packet.header.dstAddr;
this.options = packet.header.options;
this.padding = packet.header.padding;
this.payloadBuilder = packet.payload != null ? packet.payload.getBuilder() : null;
}
/**
*
* @param version version
* @return this Builder object for method chaining.
*/
public Builder version(IpVersion version) {
this.version = version;
return this;
}
/**
*
* @param ihl ihl
* @return this Builder object for method chaining.
*/
public Builder ihl(byte ihl) {
this.ihl = ihl;
return this;
}
/**
*
* @param tos tos
* @return this Builder object for method chaining.
*/
public Builder tos(IpV4Tos tos) {
this.tos = tos;
return this;
}
/**
*
* @param totalLength totalLength
* @return this Builder object for method chaining.
*/
public Builder totalLength(short totalLength) {
this.totalLength = totalLength;
return this;
}
/**
*
* @param identification identification
* @return this Builder object for method chaining.
*/
public Builder identification(short identification) {
this.identification = identification;
return this;
}
/**
*
* @param reservedFlag reservedFlag
* @return this Builder object for method chaining.
*/
public Builder reservedFlag(boolean reservedFlag) {
this.reservedFlag = reservedFlag;
return this;
}
/**
*
* @param dontFragmentFlag dontFragmentFlag
* @return this Builder object for method chaining.
*/
public Builder dontFragmentFlag(boolean dontFragmentFlag) {
this.dontFragmentFlag = dontFragmentFlag;
return this;
}
/**
*
* @param moreFragmentFlag moreFragmentFlag
* @return this Builder object for method chaining.
*/
public Builder moreFragmentFlag(boolean moreFragmentFlag) {
this.moreFragmentFlag = moreFragmentFlag;
return this;
}
/**
*
* @param fragmentOffset fragmentOffset
* @return this Builder object for method chaining.
*/
public Builder fragmentOffset(short fragmentOffset) {
this.fragmentOffset = fragmentOffset;
return this;
}
/**
*
* @param ttl ttl
* @return this Builder object for method chaining.
*/
public Builder ttl(byte ttl) {
this.ttl = ttl;
return this;
}
/**
*
* @param protocol protocol
* @return this Builder object for method chaining.
*/
public Builder protocol(IpNumber protocol) {
this.protocol = protocol;
return this;
}
/**
*
* @param headerChecksum headerChecksum
* @return this Builder object for method chaining.
*/
public Builder headerChecksum(short headerChecksum) {
this.headerChecksum = headerChecksum;
return this;
}
/**
*
* @param srcAddr srcAddr
* @return this Builder object for method chaining.
*/
public Builder srcAddr(Inet4Address srcAddr) {
this.srcAddr = srcAddr;
return this;
}
/**
*
* @param dstAddr dstAddr
* @return this Builder object for method chaining.
*/
public Builder dstAddr(Inet4Address dstAddr) {
this.dstAddr = dstAddr;
return this;
}
/**
*
* @param options options
* @return this Builder object for method chaining.
*/
public Builder options(List options) {
this.options = options;
return this;
}
/**
*
* @param padding padding
* @return this Builder object for method chaining.
*/
public Builder padding(byte[] padding) {
this.padding = padding;
return this;
}
@Override
public Builder payloadBuilder(Packet.Builder payloadBuilder) {
this.payloadBuilder = payloadBuilder;
return this;
}
@Override
public Packet.Builder getPayloadBuilder() {
return payloadBuilder;
}
@Override
public Builder correctChecksumAtBuild(boolean correctChecksumAtBuild) {
this.correctChecksumAtBuild = correctChecksumAtBuild;
return this;
}
@Override
public Builder correctLengthAtBuild(boolean correctLengthAtBuild) {
this.correctLengthAtBuild = correctLengthAtBuild;
return this;
}
/**
*
* @param paddingAtBuild paddingAtBuild
* @return this Builder object for method chaining.
*/
public Builder paddingAtBuild(boolean paddingAtBuild) {
this.paddingAtBuild = paddingAtBuild;
return this;
}
@Override
public IpV4Packet build() {
return new IpV4Packet(this);
}
}
/**
* @author Kaito Yamada
* @since pcap4j 0.9.1
*/
public static final class IpV4Header extends AbstractHeader {
/* 0 16 31
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |Version| IHL |Type of Service| Total Length |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Identification |Flags| Fragment Offset |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Time to Live | Protocol | Header Checksum |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Source Address |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Destination Address |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Options | Padding |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
/**
*
*/
private static final long serialVersionUID = -7583326842445453539L;
private static final int VERSION_AND_IHL_OFFSET
= 0;
private static final int VERSION_AND_IHL_SIZE
= BYTE_SIZE_IN_BYTES;
private static final int TOS_OFFSET
= VERSION_AND_IHL_OFFSET + VERSION_AND_IHL_SIZE;
private static final int TOS_SIZE
= BYTE_SIZE_IN_BYTES;
private static final int TOTAL_LENGTH_OFFSET
= TOS_OFFSET + TOS_SIZE;
private static final int TOTAL_LENGTH_SIZE
= SHORT_SIZE_IN_BYTES;
private static final int IDENTIFICATION_OFFSET
= TOTAL_LENGTH_OFFSET + TOTAL_LENGTH_SIZE;
private static final int IDENTIFICATION_SIZE
= SHORT_SIZE_IN_BYTES;
private static final int FLAGS_AND_FRAGMENT_OFFSET_OFFSET
= IDENTIFICATION_OFFSET + IDENTIFICATION_SIZE;
private static final int FLAGS_AND_FRAGMENT_OFFSET_SIZE
= SHORT_SIZE_IN_BYTES;
private static final int TTL_OFFSET
= FLAGS_AND_FRAGMENT_OFFSET_OFFSET + FLAGS_AND_FRAGMENT_OFFSET_SIZE;
private static final int TTL_SIZE
= BYTE_SIZE_IN_BYTES;
private static final int PROTOCOL_OFFSET
= TTL_OFFSET + TTL_SIZE;
private static final int PROTOCOL_SIZE
= BYTE_SIZE_IN_BYTES;
private static final int HEADER_CHECKSUM_OFFSET
= PROTOCOL_OFFSET + PROTOCOL_SIZE;
private static final int HEADER_CHECKSUM_SIZE
= SHORT_SIZE_IN_BYTES;
private static final int SRC_ADDR_OFFSET
= HEADER_CHECKSUM_OFFSET + HEADER_CHECKSUM_SIZE;
private static final int SRC_ADDR_SIZE
= INET4_ADDRESS_SIZE_IN_BYTES;
private static final int DST_ADDR_OFFSET
= SRC_ADDR_OFFSET + SRC_ADDR_SIZE;
private static final int DST_ADDR_SIZE
= INET4_ADDRESS_SIZE_IN_BYTES;
private static final int OPTIONS_OFFSET
= DST_ADDR_OFFSET + DST_ADDR_SIZE;
private static final int MIN_IPV4_HEADER_SIZE
= DST_ADDR_OFFSET + DST_ADDR_SIZE;
private final IpVersion version;
private final byte ihl;
private final IpV4Tos tos;
private final short totalLength;
private final short identification;
private final boolean reservedFlag;
private final boolean dontFragmentFlag;
private final boolean moreFragmentFlag;
private final short fragmentOffset;
private final byte ttl;
private final IpNumber protocol;
private final short headerChecksum;
private final Inet4Address srcAddr;
private final Inet4Address dstAddr;
private final List options;
private final byte[] padding;
private IpV4Header(byte[] rawData, int offset, int length) throws IllegalRawDataException {
if (length < MIN_IPV4_HEADER_SIZE) {
StringBuilder sb = new StringBuilder(110);
sb.append("The data is too short to build an IPv4 header. ")
.append("It must be at least ")
.append(MIN_IPV4_HEADER_SIZE)
.append(" bytes. data: ")
.append(ByteArrays.toHexString(rawData, " "))
.append(", offset: ")
.append(offset)
.append(", length: ")
.append(length);
throw new IllegalRawDataException(sb.toString());
}
byte versionAndIhl
= ByteArrays.getByte(rawData, VERSION_AND_IHL_OFFSET + offset);
this.version = IpVersion.getInstance(
(byte)((versionAndIhl & 0xF0) >> 4)
);
this.ihl = (byte)(versionAndIhl & 0x0F);
this.tos
= PacketFactories.getFactory(
IpV4Tos.class, NotApplicable.class
).newInstance(rawData, TOS_OFFSET + offset, BYTE_SIZE_IN_BYTES);
this.totalLength
= ByteArrays.getShort(rawData, TOTAL_LENGTH_OFFSET + offset);
this.identification
= ByteArrays.getShort(rawData, IDENTIFICATION_OFFSET + offset);
short flagsAndFragmentOffset
= ByteArrays.getShort(rawData, FLAGS_AND_FRAGMENT_OFFSET_OFFSET + offset);
this.reservedFlag = (flagsAndFragmentOffset & 0x8000) != 0;
this.dontFragmentFlag = (flagsAndFragmentOffset & 0x4000) != 0;
this.moreFragmentFlag = (flagsAndFragmentOffset & 0x2000) != 0;
this.fragmentOffset = (short)(flagsAndFragmentOffset & 0x1FFF);
this.ttl
= ByteArrays.getByte(rawData, TTL_OFFSET + offset);
this.protocol
= IpNumber
.getInstance(ByteArrays.getByte(rawData, PROTOCOL_OFFSET + offset));
this.headerChecksum
= ByteArrays.getShort(rawData, HEADER_CHECKSUM_OFFSET + offset);
this.srcAddr
= ByteArrays.getInet4Address(rawData, SRC_ADDR_OFFSET + offset);
this.dstAddr
= ByteArrays.getInet4Address(rawData, DST_ADDR_OFFSET + offset);
int headerLength = getIhlAsInt() * 4;
if (length < headerLength) {
StringBuilder sb = new StringBuilder(110);
sb.append("The data is too short to build an IPv4 header(")
.append(headerLength)
.append(" bytes). data: ")
.append(ByteArrays.toHexString(rawData, " "))
.append(", offset: ")
.append(offset)
.append(", length: ")
.append(length);
throw new IllegalRawDataException(sb.toString());
}
if (headerLength < OPTIONS_OFFSET) {
StringBuilder sb = new StringBuilder(100);
sb.append("The ihl must be equal or more than")
.append(OPTIONS_OFFSET / 4)
.append("but it is: ")
.append(getIhlAsInt());
throw new IllegalRawDataException(sb.toString());
}
this.options = new ArrayList();
int currentOffsetInHeader = OPTIONS_OFFSET;
while (currentOffsetInHeader < headerLength) {
IpV4OptionType type
= IpV4OptionType.getInstance(rawData[currentOffsetInHeader + offset]);
IpV4Option newOne;
try {
newOne = PacketFactories
.getFactory(IpV4Option.class, IpV4OptionType.class)
.newInstance(
rawData,
currentOffsetInHeader + offset,
headerLength - currentOffsetInHeader,
type
);
} catch (Exception e) {
break;
}
options.add(newOne);
currentOffsetInHeader += newOne.length();
if (newOne.getType().equals(IpV4OptionType.END_OF_OPTION_LIST)) {
break;
}
}
int paddingLength = headerLength - currentOffsetInHeader;
if (paddingLength != 0) {
this.padding
= ByteArrays.getSubArray(rawData, currentOffsetInHeader + offset, paddingLength);
}
else {
this.padding = new byte[0];
}
}
private IpV4Header(Builder builder, Packet payload) {
if ((builder.fragmentOffset & 0xE000) != 0) {
throw new IllegalArgumentException(
"Invalid fragmentOffset: " + builder.fragmentOffset
);
}
this.version = builder.version;
this.tos = builder.tos;
this.identification = builder.identification;
this.reservedFlag = builder.reservedFlag;
this.dontFragmentFlag = builder.dontFragmentFlag;
this.moreFragmentFlag = builder.moreFragmentFlag;
this.fragmentOffset = builder.fragmentOffset;
this.ttl = builder.ttl;
this.protocol = builder.protocol;
this.srcAddr = builder.srcAddr;
this.dstAddr = builder.dstAddr;
if (builder.options != null) {
this.options = new ArrayList(builder.options);
}
else {
this.options = new ArrayList(0);
}
if (builder.paddingAtBuild) {
int mod = measureLengthWithoutPadding() % 4;
if (mod != 0) {
this.padding = new byte[4 - mod];
}
else {
this.padding = new byte[0];
}
}
else {
if (builder.padding != null) {
this.padding = new byte[builder.padding.length];
System.arraycopy(builder.padding, 0, padding, 0, padding.length);
}
else {
this.padding = new byte[0];
}
}
if (builder.correctLengthAtBuild) {
this.ihl = (byte)(length() / 4);
if (payload != null) {
this.totalLength = (short)(payload.length() + length());
}
else {
this.totalLength = (short)length();
}
}
else {
if ((builder.ihl & 0xF0) != 0) {
throw new IllegalArgumentException("Invalid ihl: " + builder.ihl);
}
this.ihl = builder.ihl;
this.totalLength = builder.totalLength;
}
if (builder.correctChecksumAtBuild) {
if (PacketPropertiesLoader.getInstance().ipV4CalcChecksum()) {
headerChecksum = calcHeaderChecksum();
}
else {
headerChecksum = (short)0;
}
}
else {
this.headerChecksum = builder.headerChecksum;
}
}
private short calcHeaderChecksum() {
// If call getRawData() here, rawData will be cached with
// an invalid checksum in some cases.
// To avoid it, use buildRawData() instead.
byte[] data = buildRawData();
for (int i = 0; i < HEADER_CHECKSUM_SIZE; i++) {
data[HEADER_CHECKSUM_OFFSET + i] = (byte)0;
}
return ByteArrays.calcChecksum(data);
}
/**
*
* @return version
*/
public IpVersion getVersion() {
return version;
}
/**
*
* @return ihl
*/
public byte getIhl() {
return ihl;
}
/**
*
* @return ihl
*/
public int getIhlAsInt() {
return 0xFF & ihl;
}
/**
*
* @return tos
*/
public IpV4Tos getTos() {
return tos;
}
/**
*
* @return totalLength
*/
public short getTotalLength() {
return totalLength;
}
/**
*
* @return totalLength
*/
public int getTotalLengthAsInt() {
return 0xFFFF & totalLength;
}
/**
*
* @return identification
*/
public short getIdentification() {
return identification;
}
/**
*
* @return identification
*/
public int getIdentificationAsInt() {
return 0xFFFF & identification;
}
/**
*
* @return reservedFlag
*/
public boolean getReservedFlag() {
return reservedFlag;
}
/**
*
* @return dontFragmentFlag
*/
public boolean getDontFragmentFlag() {
return dontFragmentFlag;
}
/**
*
* @return moreFragmentFlag
*/
public boolean getMoreFragmentFlag() {
return moreFragmentFlag;
}
/**
*
* @return fragmentOffset
*/
public short getFragmentOffset() {
return fragmentOffset;
}
/**
*
* @return ttl
*/
public byte getTtl() {
return ttl;
}
/**
*
* @return ttl
*/
public int getTtlAsInt() {
return 0xFF & ttl;
}
/**
*
* @return protocol
*/
public IpNumber getProtocol() {
return protocol;
}
/**
*
* @return headerChecksum
*/
public short getHeaderChecksum() {
return headerChecksum;
}
/**
*
* @return srcAddr
*/
public Inet4Address getSrcAddr() {
return srcAddr;
}
/**
*
* @return dstAddr
*/
public Inet4Address getDstAddr() {
return dstAddr;
}
/**
*
* @return options
*/
public List getOptions() {
return new ArrayList(options);
}
/**
*
* @return padding
*/
public byte[] getPadding() {
byte[] copy = new byte[padding.length];
System.arraycopy(padding, 0, copy, 0, padding.length);
return copy;
}
/**
*
* @param acceptZero acceptZero
* @return true if the packet represented by this object has a valid checksum;
* false otherwise.
*/
public boolean hasValidChecksum(boolean acceptZero) {
if (headerChecksum == 0) {
if (acceptZero) { return true; }
else { return false; }
}
return calcHeaderChecksum() == headerChecksum;
}
@Override
protected List getRawFields() {
byte flags = 0;
if (moreFragmentFlag) { flags = (byte)1; }
if (dontFragmentFlag) { flags = (byte)(flags | 2); }
if (reservedFlag) { flags = (byte)(flags | 4); }
List rawFields = new ArrayList();
rawFields.add(ByteArrays.toByteArray((byte)((version.value() << 4) | ihl)));
rawFields.add(new byte[] {tos.value()});
rawFields.add(ByteArrays.toByteArray(totalLength));
rawFields.add(ByteArrays.toByteArray(identification));
rawFields.add(ByteArrays.toByteArray((short)((flags << 13) | fragmentOffset)));
rawFields.add(ByteArrays.toByteArray(ttl));
rawFields.add(ByteArrays.toByteArray(protocol.value()));
rawFields.add(ByteArrays.toByteArray(headerChecksum));
rawFields.add(ByteArrays.toByteArray(srcAddr));
rawFields.add(ByteArrays.toByteArray(dstAddr));
for (IpV4Option o: options) {
rawFields.add(o.getRawData());
}
rawFields.add(padding);
return rawFields;
}
private int measureLengthWithoutPadding() {
int len = 0;
for (IpV4Option o: options) {
len += o.length();
}
return len + MIN_IPV4_HEADER_SIZE;
}
@Override
protected int calcLength() {
return measureLengthWithoutPadding() + padding.length;
}
@Override
protected String buildString() {
StringBuilder sb = new StringBuilder();
String ls = System.getProperty("line.separator");
sb.append("[IPv4 Header (")
.append(length())
.append(" bytes)]")
.append(ls);
sb.append(" Version: ")
.append(version)
.append(ls);
sb.append(" IHL: ")
.append(ihl)
.append(" (")
.append(ihl * 4)
.append(" [bytes])")
.append(ls);
sb.append(" TOS: ")
.append(tos)
.append(ls);
sb.append(" Total length: ")
.append(getTotalLengthAsInt())
.append(" [bytes]")
.append(ls);
sb.append(" Identification: ")
.append(getIdentificationAsInt())
.append(ls);
sb.append(" Flags: (Reserved, Don't Fragment, More Fragment) = (")
.append(getReservedFlag())
.append(", ")
.append(getDontFragmentFlag())
.append(", ")
.append(getMoreFragmentFlag())
.append(")")
.append(ls);
sb.append(" Fragment offset: ")
.append(fragmentOffset)
.append(" (")
.append(fragmentOffset * 8)
.append(" [bytes])")
.append(ls);
sb.append(" TTL: ")
.append(getTtlAsInt())
.append(ls);
sb.append(" Protocol: ")
.append(protocol)
.append(ls);
sb.append(" Header checksum: 0x")
.append(ByteArrays.toHexString(headerChecksum, ""))
.append(ls);
sb.append(" Source address: ")
.append(srcAddr)
.append(ls);
sb.append(" Destination address: ")
.append(dstAddr)
.append(ls);
for (IpV4Option opt: options) {
sb.append(" Option: ")
.append(opt)
.append(ls);
}
if (padding.length != 0) {
sb.append(" Padding: 0x")
.append(ByteArrays.toHexString(padding, " "))
.append(ls);
}
return sb.toString();
}
@Override
public boolean equals(Object obj) {
if (obj == this) { return true; }
if (!this.getClass().isInstance(obj)) { return false; }
IpV4Header other = (IpV4Header)obj;
return
identification == other.identification
&& headerChecksum == other.headerChecksum
&& srcAddr.equals(other.srcAddr)
&& dstAddr.equals(other.dstAddr)
&& totalLength == other.totalLength
&& protocol.equals(other.protocol)
&& ttl == other.ttl
&& fragmentOffset == other.fragmentOffset
&& reservedFlag == other.reservedFlag
&& dontFragmentFlag == other.dontFragmentFlag
&& moreFragmentFlag == other.moreFragmentFlag
&& tos.equals(other.tos)
&& ihl == other.ihl
&& version.equals(other.version)
&& options.equals(other.options)
&& Arrays.equals(padding, other.padding);
}
@Override
protected int calcHashCode() {
int result = 17;
result = 31 * result + version.hashCode();
result = 31 * result + ihl;
result = 31 * result + tos.hashCode();
result = 31 * result + totalLength;
result = 31 * result + identification;
result = 31 * result + (reservedFlag ? 1231 : 1237);
result = 31 * result + (dontFragmentFlag ? 1231 : 1237);
result = 31 * result + (moreFragmentFlag ? 1231 : 1237);
result = 31 * result + fragmentOffset;
result = 31 * result + ttl;
result = 31 * result + protocol.hashCode();
result = 31 * result + headerChecksum;
result = 31 * result + srcAddr.hashCode();
result = 31 * result + dstAddr.hashCode();
result = 31 * result + Arrays.hashCode(padding);
result = 31 * result + options.hashCode();
return result;
}
}
/**
* The interface representing an IPv4 option.
* If you use {@link org.pcap4j.packet.factory.PropertiesBasedPacketFactory PropertiesBasedPacketFactory},
* Classes which imprement this interface must implement the following method:
* {@code public static IpV4Option newInstance(byte[] rawData, int offset, int length)
* throws IllegalRawDataException}
*
* @author Kaito Yamada
* @since pcap4j 0.9.11
*/
public interface IpV4Option extends Serializable {
/**
*
* @return type
*/
public IpV4OptionType getType();
/**
*
* @return length
*/
public int length();
/**
*
* @return raw data
*/
public byte[] getRawData();
}
/**
* The interface representing an IPv4 TOS.
* If you use {@link org.pcap4j.packet.factory.PropertiesBasedPacketFactory PropertiesBasedPacketFactory},
* Classes which imprement this interface must implement the following method:
* {@code public static IpV4Tos newInstance(byte value)}
*
* @author Kaito Yamada
* @since pcap4j 0.9.11
*/
public interface IpV4Tos extends Serializable {
/**
*
* @return value
*/
public byte value();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy