/* * Copyright 2010 NCHOVY * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.krakenapps.pcap.file; import java.io.DataInputStream; import java.io.EOFException; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import org.krakenapps.pcap.PcapInputStream; import org.krakenapps.pcap.packet.PacketHeader; import org.krakenapps.pcap.packet.PcapPacket; import org.krakenapps.pcap.util.Buffer; import org.krakenapps.pcap.util.ByteOrderConverter; import org.krakenapps.pcap.util.ChainBuffer; /** * PcapFileInputStream reads pcap packet stream from pcap dump file. At this * point of time, commonly used format is 2.4 version. It can read file * regardless of byte order because of the magic number of global header. * * @author mindori * @see http://wiki.wireshark.org/Development/LibpcapFileFormat */ public class PcapFileInputStream implements PcapInputStream { private DataInputStream is; private GlobalHeader globalHeader; /** * Opens pcap file input stream. * * @param file * the file to be opened for reading * @throws FileNotFoundException * if the file does not exist, is a directory rather than a * regular file, or for some other reason cannot be opened for * reading. */ public PcapFileInputStream(InputStream stream) throws IOException { is = new DataInputStream(stream); readGlobalHeader(); } /** * Opens pcap file input stream. * * @param file * the file to be opened for reading * @throws FileNotFoundException * if the file does not exist, is a directory rather than a * regular file, or for some other reason cannot be opened for * reading. */ public PcapFileInputStream(File file) throws IOException { is = new DataInputStream(new FileInputStream(file)); readGlobalHeader(); } /** * Reads a packet from pcap file. * * @exception EOFException * if this input stream reaches the end before reading four * bytes. * @exception IOException * the stream has been closed and the contained input stream * does not support reading after close, or another I/O error * occurs. */ @Override public PcapPacket getPacket() throws IOException { return readPacket(globalHeader.getMagicNumber()); } public GlobalHeader getGlobalHeader() { return globalHeader; } private void readGlobalHeader() throws IOException { int magic = is.readInt(); short major = is.readShort(); short minor = is.readShort(); int tz = is.readInt(); int sigfigs = is.readInt(); int snaplen = is.readInt(); int network = is.readInt(); globalHeader = new GlobalHeader(magic, major, minor, tz, sigfigs, snaplen, network); if (globalHeader.getMagicNumber() == 0xD4C3B2A1) globalHeader.swapByteOrder(); } private PcapPacket readPacket(int magicNumber) throws IOException, EOFException { PacketHeader packetHeader = readPacketHeader(magicNumber); Buffer packetData = readPacketData(packetHeader.getInclLen()); return new PcapPacket(packetHeader, packetData); } private PacketHeader readPacketHeader(int magicNumber) throws IOException, EOFException { int tsSec = is.readInt(); int tsUsec = is.readInt(); int inclLen = is.readInt(); int origLen = is.readInt(); if (magicNumber == 0xD4C3B2A1) { tsSec = ByteOrderConverter.swap(tsSec); tsUsec = ByteOrderConverter.swap(tsUsec); inclLen = ByteOrderConverter.swap(inclLen); origLen = ByteOrderConverter.swap(origLen); } return new PacketHeader(tsSec, tsUsec, inclLen, origLen); } private Buffer readPacketData(int packetLength) throws IOException { byte[] packets = new byte[packetLength]; is.read(packets); Buffer payload = new ChainBuffer(); payload.addLast(packets); return payload; // return new PacketPayload(packets); } /** * Closes pcap file handle. */ public void close() throws IOException { is.close(); } }