/*******************************************************************************
* gMix open source project - https://svs.informatik.uni-hamburg.de/gmix/
* Copyright (C) 2014 SVS
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
package staticContent.evaluation.traceParser.engine.protocolHeaderParser;
import java.io.IOException;
import java.io.InputStream;
import staticContent.evaluation.traceParser.engine.Protocol;
import staticContent.framework.util.Util;
// see http://wiki.wireshark.org/Development/LibpcapFileFormat
public class PCAPfileHeader {
private final static long MAGIC_NUMBER = 0xA1B2C3D4l;
private final static long MAGIC_NUMBER_SWAPPED = 0xD4C3B2A1l;
private boolean isSwapped;
private int majorVersionNr;
private int minorVersionNr;
private int timeZoneOffest; // not used in practice (always 0)
private int timestampAccurycy; // not used in practice (always 0)
private int snaplen;
private LinkLayerHeaderType linkLayerHeaderType;
public enum LinkLayerHeaderType {
LINKTYPE_NULL, // 0
LINKTYPE_ETHERNET,
RESERVED2,
LINKTYPE_AX25,
RESERVED4,
RESERVED5,
LINKTYPE_IEEE802_5,
LINKTYPE_ARCNET_BSD,
LINKTYPE_SLIP,
LINKTYPE_PPP,
LINKTYPE_FDDI,
RESERVED11,
RESERVED12,
RESERVED13,
RESERVED14,
RESERVED15,
RESERVED16,
RESERVED17,
RESERVED18,
RESERVED19,
RESERVED20,
RESERVED21,
RESERVED22,
RESERVED23,
RESERVED24,
RESERVED25,
RESERVED26,
RESERVED27,
RESERVED28,
RESERVED29,
RESERVED30,
RESERVED31,
RESERVED32,
RESERVED33,
RESERVED34,
RESERVED35,
RESERVED36,
RESERVED37,
RESERVED38,
RESERVED39,
RESERVED40,
RESERVED41,
RESERVED42,
RESERVED43,
RESERVED44,
RESERVED45,
RESERVED46,
RESERVED47,
RESERVED48,
RESERVED49,
LINKTYPE_PPP_HDLC,
LINKTYPE_PPP_ETHER,
RESERVED52,
RESERVED53,
RESERVED54,
RESERVED55,
RESERVED56,
RESERVED57,
RESERVED58,
RESERVED59,
RESERVED60,
RESERVED61,
RESERVED62,
RESERVED63,
RESERVED64,
RESERVED65,
RESERVED66,
RESERVED67,
RESERVED68,
RESERVED69,
RESERVED70,
RESERVED71,
RESERVED72,
RESERVED73,
RESERVED74,
RESERVED75,
RESERVED76,
RESERVED77,
RESERVED78,
RESERVED79,
RESERVED80,
RESERVED81,
RESERVED82,
RESERVED83,
RESERVED84,
RESERVED85,
RESERVED86,
RESERVED87,
RESERVED88,
RESERVED89,
RESERVED90,
RESERVED91,
RESERVED92,
RESERVED93,
RESERVED94,
RESERVED95,
RESERVED96,
RESERVED97,
RESERVED98,
RESERVED99,
LINKTYPE_ATM_RFC1483,
LINKTYPE_RAW,
RESERVED102,
RESERVED103,
LINKTYPE_C_HDLC,
LINKTYPE_IEEE802_11,
RESERVED106,
LINKTYPE_FRELAY,
LINKTYPE_LOOP,
RESERVED109,
RESERVED110,
RESERVED111,
RESERVED112,
LINKTYPE_LINUX_SLL,
LINKTYPE_LTALK,
RESERVED115,
RESERVED116,
LINKTYPE_PFLOG,
RESERVED118,
LINKTYPE_IEEE802_11_PRISM,
RESERVED120,
RESERVED121,
LINKTYPE_IP_OVER_FC,
LINKTYPE_SUNATM,
RESERVED124,
RESERVED125,
RESERVED126,
LINKTYPE_IEEE802_11_RADIOTAP,
RESERVED128,
LINKTYPE_ARCNET_LINUX,
RESERVED130,
RESERVED131,
RESERVED132,
RESERVED133,
RESERVED134,
RESERVED135,
RESERVED136,
RESERVED137,
LINKTYPE_APPLE_IP_OVER_IEEE1394,
LINKTYPE_MTP2_WITH_PHDR,
LINKTYPE_MTP2,
LINKTYPE_MTP3,
LINKTYPE_SCCP,
LINKTYPE_DOCSIS,
LINKTYPE_LINUX_IRDA,
RESERVED145,
RESERVED146,
LINKTYPE_USER0_LINKTYPE_USER15_147,
LINKTYPE_USER0_LINKTYPE_USER15_148,
LINKTYPE_USER0_LINKTYPE_USER15_149,
LINKTYPE_USER0_LINKTYPE_USER15_150,
LINKTYPE_USER0_LINKTYPE_USER15_151,
LINKTYPE_USER0_LINKTYPE_USER15_152,
LINKTYPE_USER0_LINKTYPE_USER15_153,
LINKTYPE_USER0_LINKTYPE_USER15_154,
LINKTYPE_USER0_LINKTYPE_USER15_155,
LINKTYPE_USER0_LINKTYPE_USER15_156,
LINKTYPE_USER0_LINKTYPE_USER15_157,
LINKTYPE_USER0_LINKTYPE_USER15_158,
LINKTYPE_USER0_LINKTYPE_USER15_159,
LINKTYPE_USER0_LINKTYPE_USER15_160,
LINKTYPE_USER0_LINKTYPE_USER15_161,
LINKTYPE_USER0_LINKTYPE_USER15_162,
LINKTYPE_IEEE802_11_AVS,
RESERVED164,
LINKTYPE_BACNET_MS_TP,
LINKTYPE_PPP_PPPD,
RESERVED167,
RESERVED168,
LINKTYPE_GPRS_LLC,
RESERVED170,
RESERVED171,
RESERVED172,
RESERVED173,
RESERVED174,
RESERVED175,
RESERVED176,
LINKTYPE_LINUX_LAPD,
RESERVED178,
RESERVED179,
RESERVED180,
RESERVED181,
RESERVED182,
RESERVED183,
RESERVED184,
RESERVED185,
RESERVED186,
LINKTYPE_BLUETOOTH_HCI_H4,
RESERVED188,
LINKTYPE_USB_LINUX,
RESERVED190,
RESERVED191,
LINKTYPE_PPI,
RESERVED193,
RESERVED194,
LINKTYPE_IEEE802_15_4,
LINKTYPE_SITA,
LINKTYPE_ERF,
RESERVED198,
RESERVED199,
RESERVED200,
LINKTYPE_BLUETOOTH_HCI_H4_WITH_PHDR,
LINKTYPE_AX25_KISS,
LINKTYPE_LAPD,
LINKTYPE_PPP_WITH_DIR,
LINKTYPE_C_HDLC_WITH_DIR,
LINKTYPE_FRELAY_WITH_DIR,
RESERVED207,
RESERVED208,
LINKTYPE_IPMB_LINUX,
RESERVED210,
RESERVED211,
RESERVED212,
RESERVED213,
RESERVED214,
LINKTYPE_IEEE802_15_4_NONASK_PHY,
RESERVED216,
RESERVED217,
RESERVED218,
RESERVED219,
LINKTYPE_USB_LINUX_MMAPPED,
RESERVED221,
RESERVED222,
RESERVED223,
LINKTYPE_FC_2,
LINKTYPE_FC_2_WITH_FRAME_DELIMS,
LINKTYPE_IPNET,
LINKTYPE_CAN_SOCKETCAN,
LINKTYPE_IPV4,
LINKTYPE_IPV6,
LINKTYPE_IEEE802_15_4_NOFCS,
LINKTYPE_DBUS,
RESERVED232,
RESERVED233,
RESERVED234,
LINKTYPE_DVB_CI,
LINKTYPE_MUX27010,
LINKTYPE_STANAG_5066_D_PDU,
RESERVED238,
LINKTYPE_NFLOG,
LINKTYPE_NETANALYZER,
LINKTYPE_NETANALYZER_TRANSPARENT,
LINKTYPE_IPOIB,
LINKTYPE_MPEG_2_TS,
LINKTYPE_NG40,
LINKTYPE_NFC_LLCP,
RESERVED246,
RESERVED247,
RESERVED248,
RESERVED249,
RESERVED250,
RESERVED251,
RESERVED252,
RESERVED253,
RESERVED254,
RESERVED255
};
private PCAPfileHeader() {
}
public static Protocol linkLayerHeaderTypeToProtocol(LinkLayerHeaderType type) {
if (type == LinkLayerHeaderType.LINKTYPE_ETHERNET) {
return Protocol.Ethernet;
} else if (type == LinkLayerHeaderType.LINKTYPE_IPV4) {
return Protocol.IPv4;
} else if (type == LinkLayerHeaderType.LINKTYPE_IPV6) {
return Protocol.IPv6;
} else
return Protocol.UNKNOWN;
}
public static PCAPfileHeader readHeader(InputStream inputStream) throws IOException {
PCAPfileHeader pcapHeader = new PCAPfileHeader();
long magicNumber = Util.unsignedIntToLong(Util.forceRead(inputStream, 4));
if (magicNumber == MAGIC_NUMBER) {
pcapHeader.isSwapped = false;
} else if (magicNumber == MAGIC_NUMBER_SWAPPED) {
pcapHeader.isSwapped = true;
} else
throw new RuntimeException("no PCAP header found. doesn't seem to be a PCAP file");
pcapHeader.majorVersionNr = Util.unsignedShortToInt(pcapHeader.forceRead(inputStream, 2));
pcapHeader.minorVersionNr = Util.unsignedShortToInt(pcapHeader.forceRead(inputStream, 2));
pcapHeader.timeZoneOffest = (int) Util.unsignedIntToLong(pcapHeader.forceRead(inputStream, 4));
if (pcapHeader.timeZoneOffest != 0)
System.err.println("warning: timeZoneOffest in pcap header not set to 0"); // should always be 0 according to http://wiki.wireshark.org/Development/LibpcapFileFormat
pcapHeader.timestampAccurycy = (int) Util.unsignedIntToLong(pcapHeader.forceRead(inputStream, 4));
if (pcapHeader.timestampAccurycy != 0)
System.err.println("warning: timestampAccurycy in pcap header not set to 0"); // should always be 0 according to http://wiki.wireshark.org/Development/LibpcapFileFormat
pcapHeader.snaplen = (int) Util.unsignedIntToLong(pcapHeader.forceRead(inputStream, 4));
pcapHeader.linkLayerHeaderType = LinkLayerHeaderType.values()[(int) Util.unsignedIntToLong(pcapHeader.forceRead(inputStream, 4))];
return pcapHeader;
}
public byte[] forceRead(InputStream inputStream, int length) throws IOException {
byte[] data = Util.forceRead(inputStream, length);
if (data == null) // EOF
return null;
if (isSwapped)
return Util.reverse(data);
else
return data;
}
public boolean isSwapped() {
return isSwapped;
}
public int getMajorVersionNr() {
return majorVersionNr;
}
public int getMinorVersionNr() {
return minorVersionNr;
}
public long getTimeZoneOffest() {
return timeZoneOffest;
}
public long getTimestampAccurycy() {
return timestampAccurycy;
}
public long getSnaplen() {
return snaplen;
}
public LinkLayerHeaderType getLinkLayerHeaderType() {
return linkLayerHeaderType;
}
public Protocol getLinkLayerHeaderTypeAsProtocol() {
return linkLayerHeaderTypeToProtocol(linkLayerHeaderType);
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(" pcap header: \n");
sb.append(" is swapped: " +isSwapped +"\n");
sb.append(" version: " +majorVersionNr +"." +minorVersionNr +"\n");
sb.append(" timeZoneOffest: " +timeZoneOffest +"\n");
sb.append(" timestampAccurycy: " +timestampAccurycy +"\n");
sb.append(" snaplen: " +snaplen +"\n");
sb.append(" linkLayerHeaderType: " +linkLayerHeaderType +"\n");
return sb.toString();
}
}