All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.pkts.packet.impl.PCapPacketImpl Maven / Gradle / Ivy

There is a newer version: 3.0.10
Show newest version
/**
 * 
 */
package io.pkts.packet.impl;

import io.pkts.buffer.Buffer;
import io.pkts.frame.PcapGlobalHeader;
import io.pkts.frame.PcapRecordHeader;
import io.pkts.framer.EthernetFramer;
import io.pkts.framer.FramingException;
import io.pkts.framer.IPv4Framer;
import io.pkts.framer.SllFramer;
import io.pkts.packet.PCapPacket;
import io.pkts.packet.PacketParseException;
import io.pkts.packet.Packet;
import io.pkts.protocol.Protocol;

import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * TODO: may rename this to a frame instead since this is a little different
 * than a "real" protocol packet.
 * 
 * @author [email protected]
 */
public final class PCapPacketImpl extends AbstractPacket implements PCapPacket {

    private final PcapRecordHeader pcapHeader;

    private static final SllFramer sllFramer = new SllFramer();
    private static final EthernetFramer ethernetFramer = new EthernetFramer();
    private static final IPv4Framer ipFramer = new IPv4Framer();
    private final PcapGlobalHeader pcapGlobalHeader;

    /**
     * Constructor which assumes an Ethernet link layer.
     */
    public PCapPacketImpl(final PcapRecordHeader header, final Buffer payload) {
        super(Protocol.PCAP, null, payload);
        this.pcapGlobalHeader = PcapGlobalHeader.createDefaultHeader();
        this.pcapHeader = header;
    }

    /**
     * Constructor which uses the PCAP file's global header to support more than just Ethernet link layers
     */
    public PCapPacketImpl(PcapGlobalHeader pcapGlobalHeader, final PcapRecordHeader header, final Buffer payload) {
        super(Protocol.PCAP, null, payload);
        this.pcapGlobalHeader = pcapGlobalHeader;
        this.pcapHeader = header;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public long getArrivalTime() {
        final long multiplier = pcapGlobalHeader.timestampsInNs() ? 1000000000 : 1000000;

        return this.pcapHeader.getTimeStampSeconds() * multiplier + this.pcapHeader.getTimeStampMicroOrNanoSeconds();
    }

    @Override
    public long getTotalLength() {
        return this.pcapHeader.getTotalLength();
    }

    @Override
    public long getCapturedLength() {
        return this.pcapHeader.getCapturedLength();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void verify() {
        // nothing to verify for the pcap packet since that would
        // have been detected when we framed the pcap packet.
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();
        final SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss.SSS");
        final Date date = new Date(getArrivalTime() / 1000);
        sb.append("Arrival Time: ").append(formatter.format(date))
          .append(" Epoch Time: ").append(this.pcapHeader.getTimeStampSeconds()).append(".")
          .append(String.format("%09d", this.pcapHeader.getTimeStampMicroOrNanoSeconds()))
          .append(" Frame Length: ").append(getTotalLength())
          .append(" Capture Length: ").append(getCapturedLength());

        return sb.toString();
    }

    @Override
    public void write(final OutputStream out, final Buffer payload) throws IOException {
        final int size = payload.getReadableBytes();
        this.pcapHeader.setCapturedLength(size);
        this.pcapHeader.setTotalLength(size);
        this.pcapHeader.write(out);
        out.write(payload.getArray());
    }

    @Override
    public PCapPacket clone() {
        throw new RuntimeException("not implemented yet");
    }

    @Override
    public Packet getNextPacket() throws IOException, PacketParseException {
        final Buffer payload = getPayload();
        if (payload == null) {
            return null;
        }

        switch(pcapGlobalHeader.getDataLinkType())
        {
            case 1:
            default:
                try {
                    return ethernetFramer.frame(this, payload);
                } catch (FramingException e) {
                    throw new PacketParseException(16, "Ethernet parsing failed", e);
                }
            case 113:
                return sllFramer.frame(this, payload);
            case 101:
                return ipFramer.frame(this, payload);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy