@Ignore @Test public void benchComputeChecksum() { ByteBuffer buffer = createLongPacket(); buffer.flip(); IPv4Packet packet = new IPv4Packet(buffer); TCPHeader tcpHeader = (TCPHeader) packet.getTransportHeader(); long start = System.currentTimeMillis(); for (int i = 0; i < 5000000; ++i) { tcpHeader.computeChecksum(packet.getIpv4Header(), packet.getPayload()); } long duration = System.currentTimeMillis() - start; System.out.println("5000000 TCP checksums: " + duration + "ms"); }
@Override public void computeChecksum(IPv4Header ipv4Header, ByteBuffer payload) { byte[] rawArray = raw.array(); int rawOffset = raw.arrayOffset(); byte[] payloadArray = payload.array(); int payloadOffset = payload.arrayOffset(); int source = ipv4Header.getSource(); int destination = ipv4Header.getDestination(); int length = ipv4Header.getTotalLength() - ipv4Header.getHeaderLength(); assert (length & ~0xffff) == 0 : "Length cannot take more than 16 bits"; int sum = source >>> 16; sum += source & 0xffff; sum += destination >>> 16; sum += destination & 0xffff; sum += IPv4Header.Protocol.TCP.getNumber(); sum += length; setChecksum((short) 0); for (int i = 0; i < headerLength / 2; ++i) { sum += ((rawArray[rawOffset + 2 * i] & 0xff) << 8) | (rawArray[rawOffset + 2 * i + 1] & 0xff); } int payloadLength = length - headerLength; assert payloadLength == payload.limit() : "Payload length does not match"; for (int i = 0; i < payloadLength / 2; ++i) { sum += ((payloadArray[payloadOffset + 2 * i] & 0xff) << 8) | (payloadArray[payloadOffset + 2 * i + 1] & 0xff); } if (payloadLength % 2 != 0) { sum += (payloadArray[payloadOffset + payloadLength - 1] & 0xff) << 8; } while ((sum & ~0xffff) != 0) { sum = (sum & 0xffff) + (sum >> 16); } setChecksum((short) ~sum); }
TCPHeader implements TransportHeader { @Override public void computeChecksum(IPv4Header ipv4Header, ByteBuffer payload) { byte[] rawArray = raw.array(); int rawOffset = raw.arrayOffset(); byte[] payloadArray = payload.array(); int payloadOffset = payload.arrayOffset(); int source = ipv4Header.getSource(); int destination = ipv4Header.getDestination(); int length = ipv4Header.getTotalLength() - ipv4Header.getHeaderLength(); assert (length & ~0xffff) == 0 : "Length cannot take more than 16 bits"; int sum = source >>> 16; sum += source & 0xffff; sum += destination >>> 16; sum += destination & 0xffff; sum += IPv4Header.Protocol.TCP.getNumber(); sum += length; setChecksum((short) 0); for (int i = 0; i < headerLength / 2; ++i) { sum += ((rawArray[rawOffset + 2 * i] & 0xff) << 8) | (rawArray[rawOffset + 2 * i + 1] & 0xff); } int payloadLength = length - headerLength; assert payloadLength == payload.limit() : "Payload length does not match"; for (int i = 0; i < payloadLength / 2; ++i) { sum += ((payloadArray[payloadOffset + 2 * i] & 0xff) << 8) | (payloadArray[payloadOffset + 2 * i + 1] & 0xff); } if (payloadLength % 2 != 0) { sum += (payloadArray[payloadOffset + payloadLength - 1] & 0xff) << 8; } while ((sum & ~0xffff) != 0) { sum = (sum & 0xffff) + (sum >> 16); } setChecksum((short) ~sum); } }
TCPHeader implements TransportHeader { @Override public void computeChecksum(IPv4Header ipv4Header, ByteBuffer payload) { byte[] rawArray = raw.array(); int rawOffset = raw.arrayOffset(); byte[] payloadArray = payload.array(); int payloadOffset = payload.arrayOffset(); int source = ipv4Header.getSource(); int destination = ipv4Header.getDestination(); int length = ipv4Header.getTotalLength() - ipv4Header.getHeaderLength(); assert (length & ~0xffff) == 0 : "Length cannot take more than 16 bits"; int sum = source >>> 16; sum += source & 0xffff; sum += destination >>> 16; sum += destination & 0xffff; sum += IPv4Header.Protocol.TCP.getNumber(); sum += length; setChecksum((short) 0); for (int i = 0; i < headerLength / 2; ++i) { sum += ((rawArray[rawOffset + 2 * i] & 0xff) << 8) | (rawArray[rawOffset + 2 * i + 1] & 0xff); } int payloadLength = length - headerLength; assert payloadLength == payload.limit() : "Payload length does not match"; for (int i = 0; i < payloadLength / 2; ++i) { sum += ((payloadArray[payloadOffset + 2 * i] & 0xff) << 8) | (payloadArray[payloadOffset + 2 * i + 1] & 0xff); } if (payloadLength % 2 != 0) { sum += (payloadArray[payloadOffset + payloadLength - 1] & 0xff) << 8; } while ((sum & ~0xffff) != 0) { sum = (sum & 0xffff) + (sum >> 16); } setChecksum((short) ~sum); } TCPHeader(ByteBuffer raw); }
TCPHeader implements TransportHeader { @Override public void computeChecksum(IPv4Header ipv4Header, ByteBuffer payload) { byte[] rawArray = raw.array(); int rawOffset = raw.arrayOffset(); byte[] payloadArray = payload.array(); int payloadOffset = payload.arrayOffset(); int source = ipv4Header.getSource(); int destination = ipv4Header.getDestination(); int length = ipv4Header.getTotalLength() - ipv4Header.getHeaderLength(); assert (length & ~0xffff) == 0 : "Length cannot take more than 16 bits"; int sum = source >>> 16; sum += source & 0xffff; sum += destination >>> 16; sum += destination & 0xffff; sum += IPv4Header.Protocol.TCP.getNumber(); sum += length; setChecksum((short) 0); for (int i = 0; i < headerLength / 2; ++i) { sum += ((rawArray[rawOffset + 2 * i] & 0xff) << 8) | (rawArray[rawOffset + 2 * i + 1] & 0xff); } int payloadLength = length - headerLength; assert payloadLength == payload.limit() : "Payload length does not match"; for (int i = 0; i < payloadLength / 2; ++i) { sum += ((payloadArray[payloadOffset + 2 * i] & 0xff) << 8) | (payloadArray[payloadOffset + 2 * i + 1] & 0xff); } if (payloadLength % 2 != 0) { sum += (payloadArray[payloadOffset + payloadLength - 1] & 0xff) << 8; } while ((sum & ~0xffff) != 0) { sum = (sum & 0xffff) + (sum >> 16); } setChecksum((short) ~sum); } TCPHeader(ByteBuffer raw); int getWindow(); @Override int getSourcePort(); @Override int getDestinationPort(); @Override void setSourcePort(int sourcePort); @Override void setDestinationPort(int destinationPort); int getSequenceNumber(); void setSequenceNumber(int sequenceNumber); int getAcknowledgementNumber(); void setAcknowledgementNumber(int acknowledgementNumber); @Override int getHeaderLength(); @Override void setPayloadLength(int payloadLength); int getFlags(); void setFlags(int flags); void shrinkOptions(); boolean isFin(); boolean isSyn(); boolean isRst(); boolean isPsh(); boolean isAck(); boolean isUrg(); @Override ByteBuffer getRaw(); @Override TCPHeader copyTo(ByteBuffer target); TCPHeader copy(); @Override void computeChecksum(IPv4Header ipv4Header, ByteBuffer payload); short getChecksum(); }
TCPHeader implements TransportHeader { @Override public void computeChecksum(IPv4Header ipv4Header, ByteBuffer payload) { byte[] rawArray = raw.array(); int rawOffset = raw.arrayOffset(); byte[] payloadArray = payload.array(); int payloadOffset = payload.arrayOffset(); int source = ipv4Header.getSource(); int destination = ipv4Header.getDestination(); int length = ipv4Header.getTotalLength() - ipv4Header.getHeaderLength(); assert (length & ~0xffff) == 0 : "Length cannot take more than 16 bits"; int sum = source >>> 16; sum += source & 0xffff; sum += destination >>> 16; sum += destination & 0xffff; sum += IPv4Header.Protocol.TCP.getNumber(); sum += length; setChecksum((short) 0); for (int i = 0; i < headerLength / 2; ++i) { sum += ((rawArray[rawOffset + 2 * i] & 0xff) << 8) | (rawArray[rawOffset + 2 * i + 1] & 0xff); } int payloadLength = length - headerLength; assert payloadLength == payload.limit() : "Payload length does not match"; for (int i = 0; i < payloadLength / 2; ++i) { sum += ((payloadArray[payloadOffset + 2 * i] & 0xff) << 8) | (payloadArray[payloadOffset + 2 * i + 1] & 0xff); } if (payloadLength % 2 != 0) { sum += (payloadArray[payloadOffset + payloadLength - 1] & 0xff) << 8; } while ((sum & ~0xffff) != 0) { sum = (sum & 0xffff) + (sum >> 16); } setChecksum((short) ~sum); } TCPHeader(ByteBuffer raw); int getWindow(); @Override int getSourcePort(); @Override int getDestinationPort(); @Override void setSourcePort(int sourcePort); @Override void setDestinationPort(int destinationPort); int getSequenceNumber(); void setSequenceNumber(int sequenceNumber); int getAcknowledgementNumber(); void setAcknowledgementNumber(int acknowledgementNumber); @Override int getHeaderLength(); @Override void setPayloadLength(int payloadLength); int getFlags(); void setFlags(int flags); void shrinkOptions(); boolean isFin(); boolean isSyn(); boolean isRst(); boolean isPsh(); boolean isAck(); boolean isUrg(); @Override ByteBuffer getRaw(); @Override TCPHeader copyTo(ByteBuffer target); TCPHeader copy(); @Override void computeChecksum(IPv4Header ipv4Header, ByteBuffer payload); short getChecksum(); static final int FLAG_FIN; static final int FLAG_SYN; static final int FLAG_RST; static final int FLAG_PSH; static final int FLAG_ACK; static final int FLAG_URG; }