private Packet nextPacket() {
pcapPacketHeader = new byte[PACKET_HEADER_SIZE];
if (!readBytes(pcapPacketHeader))
return null;
Packet packet = createPacket();
long packetTimestamp = PcapReaderUtil.convertInt(pcapPacketHeader, TIMESTAMP_OFFSET, reverseHeaderByteOrder);
packet.put(Packet.TIMESTAMP, packetTimestamp);
long packetTimestampMicros = PcapReaderUtil.convertInt(pcapPacketHeader, TIMESTAMP_MICROS_OFFSET, reverseHeaderByteOrder);
packet.put(Packet.TIMESTAMP_MICROS, packetTimestampMicros);
// Prepare the timestamp with a BigDecimal to include microseconds
BigDecimal packetTimestampUsec = new BigDecimal(packetTimestamp
+ (double) packetTimestampMicros/1000000, ts_mc);
packet.put(Packet.TS_USEC, packetTimestampUsec);
long packetSize = PcapReaderUtil.convertInt(pcapPacketHeader, CAP_LEN_OFFSET, reverseHeaderByteOrder);
packetData = new byte[(int)packetSize];
if (!readBytes(packetData))
return packet;
int ipStart = findIPStart(packetData);
if (ipStart == -1)
return packet;
int ipProtocolHeaderVersion = getInternetProtocolHeaderVersion(packetData, ipStart);
packet.put(Packet.IP_VERSION, ipProtocolHeaderVersion);
if (ipProtocolHeaderVersion == 4 || ipProtocolHeaderVersion == 6) {
int ipHeaderLen = getInternetProtocolHeaderLength(packetData, ipProtocolHeaderVersion, ipStart);
packet.put(Packet.IP_HEADER_LENGTH, ipHeaderLen);
int totalLength = 0;
if (ipProtocolHeaderVersion == 4) {
buildInternetProtocolV4Packet(packet, packetData, ipStart);
totalLength = PcapReaderUtil.convertShort(packetData, ipStart + IP_TOTAL_LEN_OFFSET);
} else if (ipProtocolHeaderVersion == 6) {
buildInternetProtocolV6Packet(packet, packetData, ipStart);
int payloadLength = PcapReaderUtil.convertShort(packetData, ipStart + IPV6_PAYLOAD_LEN_OFFSET);
totalLength = payloadLength + IPV6_HEADER_SIZE;
}
String protocol = (String)packet.get(Packet.PROTOCOL);
if (PROTOCOL_UDP == protocol ||
PROTOCOL_TCP == protocol) {
byte[] packetPayload = buildTcpAndUdpPacket(packet, packetData, ipProtocolHeaderVersion, ipStart, ipHeaderLen, totalLength);
if (isReassemble() && PROTOCOL_TCP == protocol) {
Flow flow = packet.getFlow();
if (packetPayload.length > 0) {
Long seq = (Long)packet.get(Packet.TCP_SEQ);
SequencePayload sequencePayload = new SequencePayload(seq, packetPayload);
flows.put(flow, sequencePayload);
}
if ((Boolean)packet.get(Packet.TCP_FLAG_FIN) || (isPush() && (Boolean)packet.get(Packet.TCP_FLAG_PSH))) {
Collection<SequencePayload> fragments = flows.removeAll(flow);
if (fragments != null && fragments.size() > 0) {
packet.put(Packet.REASSEMBLED_FRAGMENTS, fragments.size());
packetPayload = new byte[0];
SequencePayload prev = null;
for (SequencePayload seqPayload : fragments) {
if (prev != null && !seqPayload.linked(prev)) {
LOG.warn("Broken sequence chain between " + seqPayload + " and " + prev + ". Returning empty payload.");