/*
* Sun Public License
*
* The contents of this file are subject to the Sun Public License Version
* 1.0 (the "License"). You may not use this file except in compliance with
* the License. A copy of the License is available at http://www.sun.com/
*
* The Original Code is the SLAMD Distributed Load Generation Engine.
* The Initial Developer of the Original Code is Neil A. Wilson.
* Portions created by Neil A. Wilson are Copyright (C) 2004-2010.
* Some preexisting portions Copyright (C) 2002-2006 Sun Microsystems, Inc.
* All Rights Reserved.
*
* Contributor(s): Neil A. Wilson
*/
package com.slamd.tools.ldapdecoder.snoop;
import java.io.IOException;
import java.io.InputStream;
/**
* This class defines a generic snoop packet record, which holds information
* about a packet that has been captured.
*
*
* @author Neil A. Wilson
*/
public class TCPDumpPacketRecord
{
// The actual data associated with this packet record.
private byte[] packetData;
// The original length of the packet that was captured.
private int originalLength;
// The time this packet was captured, measured in seconds since January 1,
// 1970.
private long timestampSeconds;
// The number of microseconds after the indicated timestamp in seconds that
// the packet was captured.
private long timestampMicroseconds;
/**
* Creates a new TCPDump packet record with the provided information.
*
* @param originalLength The original length of the data that was
* captured.
* @param timestampSeconds The time this packet was captured, measured
* in seconds since January 1, 1970.
* @param timestampMicroseconds The number of microseconds after the
* indicated timestamp in seconds that the
* packet was captured.
* @param packetData The actual data of the packet that was
* captured.
*/
public TCPDumpPacketRecord(int originalLength, long timestampSeconds,
long timestampMicroseconds, byte[] packetData)
{
this.originalLength = originalLength;
this.timestampSeconds = timestampSeconds;
this.timestampMicroseconds = timestampMicroseconds;
this.packetData = packetData;
}
/**
* Reads a TCPDump packet record from the provided input stream.
*
* @param inputStream The input stream from which to read the packet record.
* @param bigEndian Indicates whether the data in the capture file uses
* big endian or little endian encoding.
*
* @return The TCPDump packet record that was captured.
*
* @throws IOException If a problem occurs while reading data from the
* provided input stream.
* @throws SnoopException If a problem occurs while attempting to decode the
* TCPDump data.
*/
public static TCPDumpPacketRecord readPacketRecord(InputStream inputStream,
boolean bigEndian)
throws IOException, SnoopException
{
// Read and decode the TCPDump packet record header, which will always be
// 16 bytes.
byte[] headerBytes = SnoopDecoder.readBytes(inputStream, 16);
if (headerBytes == null)
{
return null;
}
long timestampSeconds = TCPDumpDecoder.byteArrayToLong(headerBytes, 0, 4,
bigEndian);
long timestampMicros = TCPDumpDecoder.byteArrayToLong(headerBytes, 4, 8,
bigEndian);
int includedLength = TCPDumpDecoder.byteArrayToInt(headerBytes, 8, 4,
bigEndian);
int originalLength = TCPDumpDecoder.byteArrayToInt(headerBytes, 12, 4,
bigEndian);
// Read the actual packet data.
byte[] packetData = SnoopDecoder.readBytes(inputStream, includedLength);
if (packetData == null)
{
throw new SnoopException("End of input stream reached before packet " +
"data could be read");
}
// Create and return the packet record.
return new TCPDumpPacketRecord(originalLength, timestampSeconds,
timestampMicros, packetData);
}
/**
* Retrieves the number of bytes in the original data packet.
*
* @return The number of bytes in the original data packet.
*/
public int getOriginalLength()
{
return originalLength;
}
/**
* Retrieves the number of bytes actually captured from the data packet.
*
* @return The number of bytes actually captured from the data packet.
*/
public int getIncludedLength()
{
return packetData.length;
}
/**
* Indicates whether this packet is truncated (i.e., the amount of data
* captured is less than the amount of data in the original packet).
*
* @return <CODE>true</CODE> if this packet is truncated, or
* <CODE>false</CODE> if not.
*/
public boolean isTruncated()
{
return (originalLength != packetData.length);
}
/**
* Retrieves the time this packet was captured, measured in number of seconds
* since January 1, 1970.
*
* @return The time this packet was captured, measured in number of seconds
* since January 1, 1970.
*/
public long getTimestampSeconds()
{
return timestampSeconds;
}
/**
* Retrieves the number of microseconds after the specified number of seconds
* that this packet was captured.
*
* @return The number of microseconds after the specified number of seconds
* that this packet was captured.
*/
public long getTimestampMicroseconds()
{
return timestampMicroseconds;
}
/**
* Retrieves the actual data contained in the packet.
*
* @return The actual data contained in the packet.
*/
public byte[] getPacketData()
{
return packetData;
}
}