ipv4header.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 377 行
JAVA
377 行
/*
* $Id: IPv4Header.java,v 1.1 2003/11/25 11:52:24 epr Exp $
*/
package org.jnode.net.ipv4;
import org.jnode.net.NetworkLayerHeader;
import org.jnode.net.ProtocolAddress;
import org.jnode.net.SocketBuffer;
/**
* @author epr
*/
public class IPv4Header implements NetworkLayerHeader, IPv4Constants {
/** IP version */
private int version;
/** Length of header in bytes */
private int hdrlength;
/** Type of service */
private int tos;
/** Length of message data in bytes (without this IP header) */
private int dataLength;
/** Identification */
private int identification;
/** Fragment offset */
private int fragmentOffset;
/** Time to live */
private int ttl;
/** Protocol ID */
private int protocol;
/** Source address */
private IPv4Address srcAddress;
/** Destination address */
private IPv4Address dstAddress;
/** Checksum is ok */
private final boolean checksumOk;
/**
* Create a new instance
* @param tos
* @param ttl
* @param protocol
* @param dstAddress
*/
public IPv4Header(int tos, int ttl, int protocol, IPv4Address dstAddress, int dataLength) {
if (dstAddress == null) {
throw new IllegalArgumentException("dstAddress cannot be null");
}
this.version = 4;
this.tos = tos;
this.ttl = ttl;
this.protocol = protocol;
this.dstAddress = dstAddress;
this.hdrlength = 20;
this.dataLength = dataLength;
this.checksumOk = true; // For this constructor not relevant
}
/**
* Create a new instance, read the header from the given buffer
* @param skbuf
*/
public IPv4Header(SocketBuffer skbuf) {
final int b0 = skbuf.get(0);
this.version = (b0 >> 4) & 0x0f;
this.hdrlength = (b0 & 0x0f) * 4;
this.tos = skbuf.get(1);
this.dataLength = skbuf.get16(2) - hdrlength;
this.identification = skbuf.get16(4);
this.fragmentOffset = skbuf.get16(6);
this.ttl = skbuf.get(8);
this.protocol = skbuf.get(9);
//final int checksum = skbuf.get16(10);
this.srcAddress = new IPv4Address(skbuf, 12);
this.dstAddress = new IPv4Address(skbuf, 16);
final int ccs = IPv4Utils.calcChecksum(skbuf, 0, hdrlength);
checksumOk = (ccs == 0/*0xFFFF*/);
//Syslog.debug("TEST: ccs=0x" + NumberUtils.hex(ccs, 4));
}
/**
* Create a clone of the given header
* @param src
*/
public IPv4Header(IPv4Header src) {
this.version = src.version;
this.hdrlength = src.hdrlength;
this.tos = src.tos;
this.dataLength = src.dataLength;
this.identification = src.identification;
this.fragmentOffset = src.fragmentOffset;
this.ttl = src.ttl;
this.protocol = src.protocol;
this.srcAddress = src.srcAddress;
this.dstAddress = src.dstAddress;
this.checksumOk = src.checksumOk;
}
/**
* Prefix this header to the front of the given buffer
* @param skbuf
*/
public void prefixTo(SocketBuffer skbuf) {
skbuf.insert(hdrlength);
skbuf.set(0, ((version << 4) & 0xf0) | ((hdrlength / 4) & 0xf));
skbuf.set(1, tos);
skbuf.set16(2, dataLength + hdrlength);
skbuf.set16(4, identification);
skbuf.set16(6, fragmentOffset);
skbuf.set(8, ttl);
skbuf.set(9, protocol);
skbuf.set(10, 0); // checksum, calculate and set later
srcAddress.writeTo(skbuf, 12);
dstAddress.writeTo(skbuf, 16);
// calculate and set checksum
final int ccs = IPv4Utils.calcChecksum(skbuf, 0, hdrlength);
if (ccs == 0) {
skbuf.set(10, 0xffff);
} else {
skbuf.set16(10, ccs);
}
//final int ccs2 = IPv4Utils.calcChecksum(skbuf, 0, hdrlength);
//Syslog.debug("TEST: ccs=0x" + NumberUtils.hex(ccs, 4) + ", ccs2=0x" + NumberUtils.hex(ccs2, 4) + ", hdrlength=" + hdrlength);
}
/**
* Finalize the header in the given buffer.
* This method is called when all layers have set their header data
* and can be used e.g. to update checksum values.
*
* @param skbuf The buffer
* @param offset The offset to the first byte (in the buffer) of this header (since low layer headers are already prefixed)
*/
public void finalizeHeader(SocketBuffer skbuf, int offset) {
// Nothing to do
}
/**
* Gets the source address of the packet described in this header
*/
public ProtocolAddress getSourceAddress() {
return srcAddress;
}
/**
* Gets the source address of the packet described in this header
*/
public ProtocolAddress getDestinationAddress() {
return dstAddress;
}
/**
* Gets the destination
*/
public IPv4Address getDestination() {
return dstAddress;
}
/**
* Is the don't fragment flag set?
*/
public boolean isDontFragment() {
return ((fragmentOffset & IP_DF) != 0);
}
/**
* Is the more fragments flag set?
*/
public boolean hasMoreFragments() {
return ((fragmentOffset & IP_MF) != 0);
}
/**
* Is this a fragment. That is, the MF flag is set, or fragment offset
* is greater then 0.
*/
public boolean isFragment() {
return (((fragmentOffset & IP_MF) != 0) ||
((fragmentOffset & IP_FRAGOFS_MASK) != 0));
}
/**
* Gets the offset of this fragment in the IP packet
*/
public int getFragmentOffset() {
return (fragmentOffset & 0x1FFF) << 3;
}
/**
* Gets the key used to find the correct fragment list.
* This key contains:
* identification, protocol, srcAddress, dstAddress
*/
public Object getFragmentListKey() {
final StringBuffer b = new StringBuffer();
b.append(identification);
b.append('-');
b.append(protocol);
b.append('-');
b.append(srcAddress);
b.append('-');
b.append(dstAddress);
return b.toString();
}
/**
* Set the fragment offset (not the DF & MF bits)
* @param i
*/
public void setFragmentOffset(int i) {
fragmentOffset &= ~IP_FRAGOFS_MASK;
fragmentOffset |= ((i >> 3) & IP_FRAGOFS_MASK);
}
/**
* Sets the don't fragment flag
*/
public void setDontFragment(boolean on) {
if (on) {
fragmentOffset |= IP_DF;
} else {
fragmentOffset &= ~IP_DF;
}
}
/**
* Sets the more fragments flag
*/
public void setMoreFragments(boolean on) {
if (on) {
fragmentOffset |= IP_MF;
} else {
fragmentOffset &= ~IP_MF;
}
}
/**
* Get the header length
*/
public int getLength() {
return hdrlength;
}
/**
* Gets the identification number
*/
public int getIdentification() {
return identification;
}
/**
* Gets the length of the header and data
*/
public int getTotalLength() {
return dataLength + hdrlength;
}
/**
* Gets the length of the data (without the IP header)
*/
public int getDataLength() {
return dataLength;
}
/**
* Gets the protocol
*/
public int getProtocol() {
return protocol;
}
/**
* Gets the source address
*/
public IPv4Address getSource() {
return srcAddress;
}
/**
* Gets the type of service attribute
*/
public int getTos() {
return tos;
}
/**
* Gets the time to live attribute
*/
public int getTtl() {
return ttl;
}
/**
* Gets the IP version
*/
public int getVersion() {
return version;
}
/**
* Sets the destination address
* @param address
*/
public void setDestination(IPv4Address address) {
dstAddress = address;
}
/**
* Sets the identification number
* @param i
*/
public void setIdentification(int i) {
identification = i;
}
/**
* Sets the length of the data in bytes
* @param i
*/
public void setDataLength(int i) {
dataLength = i;
}
/**
* Sets the protocol
* @param i
*/
public void setProtocol(int i) {
protocol = i;
}
/**
* Sets the source address
* @param address
*/
public void setSource(IPv4Address address) {
srcAddress = address;
}
/**
* Sets the type of service
* @param i
*/
public void setTos(int i) {
tos = i;
}
/**
* Sets the time to live
* @param i
*/
public void setTtl(int i) {
ttl = i;
}
/**
* Is the checksum valid
*/
public boolean isChecksumOk() {
return checksumOk;
}
/**
* Swap the source and destination address
*/
public void swapAddresses() {
final IPv4Address tmp = dstAddress;
this.dstAddress = this.srcAddress;
this.srcAddress = tmp;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?