Package com.slytechs.file.pcap

Source Code of com.slytechs.file.pcap.PcapInputCapture

/**
* Copyright (C) 2007 Sly Technologies, Inc. This library is free software; you
* can redistribute it and/or modify it under the terms of the GNU Lesser
* General Public License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version. This
* library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details. You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package com.slytechs.file.pcap;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.ReadableByteChannel;

import org.jnetstream.capture.FormatType;
import org.jnetstream.capture.InputIterator;
import org.jnetstream.capture.file.HeaderReader;
import org.jnetstream.capture.file.RecordFilterTarget;
import org.jnetstream.capture.file.RecordType;
import org.jnetstream.capture.file.pcap.PcapBlockRecord;
import org.jnetstream.capture.file.pcap.PcapDLT;
import org.jnetstream.capture.file.pcap.PcapFile;
import org.jnetstream.capture.file.pcap.PcapInput;
import org.jnetstream.capture.file.pcap.PcapPacket;
import org.jnetstream.capture.file.pcap.PcapPacketRecord;
import org.jnetstream.capture.file.pcap.PcapRecord;
import org.jnetstream.filter.Filter;
import org.jnetstream.packet.ProtocolFilterTarget;
import org.jnetstream.protocol.Protocol;

import com.slytechs.capture.DefaultCaptureDevice;
import com.slytechs.capture.file.AbstractStream;
import com.slytechs.utils.memory.BitBuffer;
import com.slytechs.utils.memory.BufferUtils;

/**
* @author Mark Bednarczyk
* @author Sly Technologies, Inc.
*/
public class PcapInputCapture
    extends AbstractStream<PcapPacket, PcapBlockRecord> implements PcapInput {

  public static final HeaderReader headerReader = PcapFile.headerReader;

  /**
   * Checks the format of the stream. First few bytes are compared for valid
   * MAGIC pattern and then appropriate check is made to determine the byte
   * order of the headers. The method consumes 4 bytes from the channel.
   *
   * @param in
   *          input channel to check
   * @return either the byte order of the format of the header or null if this
   *         is an invalid format and magic pattern did not match
   * @throws IOException
   */
  public static ByteOrder checkFormat(ReadableByteChannel in)
      throws IOException {
    ByteBuffer b = ByteBuffer.allocate(4);
    in.read(b);
    b.flip();

    if (PcapFile.headerReader.readType(b) != RecordType.BlockRecord) {
      return null;
    }

    return (b.get(0) == PcapFile.MAGIC_PATTERN_BE[0] ? ByteOrder.BIG_ENDIAN
        : ByteOrder.LITTLE_ENDIAN);
  }

  /**
   * @param in
   * @param order
   *          TODO
   * @param filter
   *          TODO
   * @throws IOException
   */
  public PcapInputCapture(final ReadableByteChannel in, ByteOrder order,
      Filter<ProtocolFilterTarget> filter) throws IOException {
    super(in, order, headerReader, filter);

    Protocol protocol =
        PcapDLT.asConst(((PcapBlockRecord) block).getLinktype());

    setCaptureDevice(new DefaultCaptureDevice(protocol));

  }

  /*
   * (non-Javadoc)
   *
   * @see org.jnetstream.capture.InputCapture#getFormatType()
   */
  public FormatType getFormatType() {
    return FormatType.Pcap;
  }

  public InputIterator<PcapPacket> getPacketIterator() throws IOException {
    return getPacketIterator(filter);
  }

  /*
   * (non-Javadoc)
   *
   * @see org.jnetstream.capture.InputCapture#getPacketIterator(org.jnetstream.filter.Filter)
   */
  public InputIterator<PcapPacket> getPacketIterator(
      Filter<ProtocolFilterTarget> filter) throws IOException {

    /*
     * Now convert the protocol filter into a record filter and apply it to raw
     * iterator
     */
    final Filter<RecordFilterTarget> rf =
        (filter == null ? PcapPacketRecord.FILTER : headerReader
            .asRecordFilter(filter, getCaptureDevice().getLinkType()));

    final InputIterator<ByteBuffer> raw = getRawIterator(rf);

    return new InputIterator<PcapPacket>() {


      public void close() throws IOException {
        raw.close();
      }

      public long getPosition() {
        return raw.getPosition();
      }

      public boolean hasNext() throws IOException {
        return raw.hasNext();
      }

      public PcapPacket next() throws IOException {
        final ByteBuffer buffer = raw.next();
        final long position = 0;

        final PcapPacket packet =
            new PcapPacketImpl(BitBuffer.wrap(BufferUtils.slice(buffer)),
                position, dlt);

        return packet;
      }

      public void remove() throws IOException {
        throw new UnsupportedOperationException(
            "Inputstream is readonly. Operation not supported");
      }

      public void skip() throws IOException {
        raw.skip();
      }

    };
  }

  public InputIterator<PcapRecord> getRecordIterator() throws IOException {
    return getRecordIterator(null);

  }

  /*
   * (non-Javadoc)
   *
   * @see org.jnetstream.capture.InputCapture#getRecordIterator(org.jnetstream.filter.Filter)
   */
  public InputIterator<PcapRecord> getRecordIterator(
      Filter<RecordFilterTarget> filter) throws IOException {

    final InputIterator<ByteBuffer> raw = getRawIterator(filter);

    return new InputIterator<PcapRecord>() {

      public void close() throws IOException {
        raw.close();
      }

      public long getPosition() {
        return raw.getPosition();
      }

      public boolean hasNext() throws IOException {
        return raw.hasNext();
      }

      public PcapRecord next() throws IOException {
        final long position = raw.getPosition();
        final ByteBuffer buffer = raw.next();

        final RecordType type = headerReader.readType(buffer);

        switch (type) {
          case BlockRecord:
            return new PcapBlockRecordImpl(buffer, position);

          case PacketRecord:
            return new PcapPacketRecordImpl(buffer, position, block);

          default:
            throw new IllegalStateException("Unknow record type encountered ["
                + type + "]");
        }
      }

      public void remove() throws IOException {
        raw.remove();
      }

      public void skip() throws IOException {
        raw.skip();
      }

    };
  }

  /*
   * (non-Javadoc)
   *
   * @see com.slytechs.capture.file.AbstractStream#createBlockRecord(java.nio.ByteBuffer)
   */
  @Override
  protected PcapBlockRecord createBlockRecord(ByteBuffer b) {
    return new PcapBlockRecordImpl(b, 0);
  }

}
TOP

Related Classes of com.slytechs.file.pcap.PcapInputCapture

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.