| /******************************************************************************* |
| * Copyright (c) 2018, 2019 Ericsson |
| * |
| * All rights reserved. This program and the accompanying materials are |
| * made available under the terms of the Eclipse Public License 2.0 which |
| * accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Viet-Hung Phan - Initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.tracecompass.internal.pcap.core.protocol.pcap; |
| |
| import java.nio.ByteBuffer; |
| import java.nio.ByteOrder; |
| |
| import org.eclipse.jdt.annotation.Nullable; |
| import org.eclipse.tracecompass.internal.pcap.core.packet.BadPacketException; |
| import org.eclipse.tracecompass.internal.pcap.core.trace.PcapFileValues; |
| import org.eclipse.tracecompass.internal.pcap.core.trace.PcapOldFile; |
| import org.eclipse.tracecompass.internal.pcap.core.util.ConversionHelper; |
| |
| /** |
| * Class that represents a Pcap packet. This is the highest level of |
| * encapsulation. |
| * This class will serve pcap packet |
| */ |
| public class PcapOldPacket extends PcapPacket { |
| |
| private static final long TIMESTAMP_MICROSECOND_MAX = 1000000L; |
| private static final long TIMESTAMP_NANOSECOND_MAX = 1000000000L; |
| |
| /** |
| * Constructor of the Pcap Packet class. |
| * |
| * @param file |
| * The file that contains this packet. |
| * @param header |
| * The header of the packet. |
| * @param payload |
| * The payload of this packet. |
| * @param index |
| * The index of the packet in the file. |
| * @throws BadPacketException |
| * Thrown when the Packet is erroneous. |
| */ |
| public PcapOldPacket(PcapOldFile file, ByteBuffer header, @Nullable ByteBuffer payload, long index) throws BadPacketException { |
| |
| super(file); |
| |
| long timestampMostSignificant; |
| long timestampLeastSignificant; |
| |
| if (header.limit() < PcapFileValues.PACKET_HEADER_SIZE) { |
| throw new BadPacketException("The Pcap packet header is too small."); //$NON-NLS-1$ |
| } |
| |
| setIndex(index); |
| |
| // PcapPacket header in File endian |
| header.order(getPcapFile().getByteOrder()); |
| header.position(0); |
| |
| // Get Timestamp MSB |
| timestampMostSignificant = ConversionHelper.unsignedIntToLong(header.getInt()); |
| // Get Timestamp LSB |
| timestampLeastSignificant = ConversionHelper.unsignedIntToLong(header.getInt()); |
| switch (getTimestampScale()) { |
| case MICROSECOND: |
| if (timestampLeastSignificant > TIMESTAMP_MICROSECOND_MAX) { |
| throw new BadPacketException("The timestamp is erroneous."); //$NON-NLS-1$ |
| } |
| setTimeStamp(TIMESTAMP_MICROSECOND_MAX * timestampMostSignificant + timestampLeastSignificant); |
| break; |
| case NANOSECOND: |
| if (timestampMostSignificant > TIMESTAMP_NANOSECOND_MAX) { |
| throw new BadPacketException("The timestamp is erroneous."); //$NON-NLS-1$ |
| } |
| setTimeStamp(TIMESTAMP_NANOSECOND_MAX * timestampMostSignificant + timestampLeastSignificant); |
| break; |
| default: |
| throw new IllegalArgumentException("The timestamp precision is not valid!"); //$NON-NLS-1$ |
| } |
| |
| // Get captured length from the packet |
| setIncludedLength(ConversionHelper.unsignedIntToLong(header.getInt())); |
| // Get packet data length (payload) |
| setOriginalLength(ConversionHelper.unsignedIntToLong(header.getInt())); |
| |
| // Set up payload |
| final ByteBuffer pcapPacket = payload; |
| if (pcapPacket == null) { |
| return; |
| } |
| |
| pcapPacket.order(ByteOrder.BIG_ENDIAN); |
| pcapPacket.position(0); |
| setPayload(pcapPacket); |
| |
| // Find Child Packet |
| setChildPacket(findChildPacket()); |
| |
| } |
| |
| @Override |
| public PcapOldFile getPcapFile() { |
| return (PcapOldFile) super.getPcapFile(); |
| } |
| |
| @Override |
| public long getDataLinkType() { |
| return getPcapFile().getDataLinkType(); |
| } |
| } |