/******************************************************************************* * 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.fileReader; import java.io.IOException; import java.io.InputStream; import staticContent.evaluation.traceParser.engine.Protocol; import staticContent.evaluation.traceParser.engine.TraceInfo; import staticContent.evaluation.traceParser.engine.dataStructure.Packet; import staticContent.evaluation.traceParser.engine.dataStructure.Flow.FlowDirection; import staticContent.evaluation.traceParser.engine.dataStructure.Packet.TCPflags; import staticContent.evaluation.traceParser.engine.protocolHandler.ProtocolHandler; import staticContent.evaluation.traceParser.engine.protocolHandler.ProtocolHandler.LengthAccuracy; import staticContent.evaluation.traceParser.engine.protocolHeaderParser.TCPpacket; public class DynamicPacketReader extends PacketReader { private TraceInfo traceInfo; private final String WAN_ADDRESS; // mac private final String LAN_ADDRESS; // mac private long seqNumber = 0; private long read = 0; /** * Packet reader that create Packets from any packet format with a * handler available (see enum Protocol.java). * * @param sourceTraceFile * @param traceInfo */ public DynamicPacketReader(InputStream sourceTraceFile, TraceInfo traceInfo) { super(sourceTraceFile); this.traceInfo = traceInfo; this.WAN_ADDRESS = traceInfo.getWanAddress(); this.LAN_ADDRESS = traceInfo.getLanAddress(); } @Override public Packet readPacket() throws IOException { return readPack(new Packet()); } @Override public Packet readPacket(Packet reusePacket) throws IOException { reusePacket.reuse(); return readPack(reusePacket); } // TODO: support direct layer 2 records (layer 0 contains layer 2 packets... e.g. ERFtype = TYPE_IPV4) private Packet readPack(Packet packet) throws IOException { // layer 0: byte[] layer0payload; byte[] layer0packet; ProtocolHandler layer0handler = traceInfo.getTraceFormat().getProtocolHandler(); assert layer0handler != null; layer0packet = layer0handler.readPacket(sourceTraceFile); if (layer0packet == null) return null; read += layer0packet.length; //packet.setRaw(layer0packet); layer0payload = layer0handler.getPayload(layer0packet); //packet.setPayload(layer0payload); packet.setSequenceNumber(++seqNumber); packet.setTimestamp(layer0handler.getTimestamp(layer0packet)); assert packet.getTimestamp() != null; packet.setLayer0protocol(traceInfo.getTraceFormat()); packet.setLayer1length(layer0handler.getPayloadLength(layer0packet)); Protocol layer1protocol = layer0handler.getPayloadProtocol(layer0packet); packet.setLayer1protocol(layer1protocol); ProtocolHandler layer1handler = layer1protocol.getProtocolHandler(); if (layer1protocol == Protocol.UNKNOWN || layer1handler == null) return packet; // layer 1: byte[] layer1packet = layer0payload; byte[] layer1payload; packet.setLayer2length(layer1handler.getPayloadLength(layer1packet)); packet.setLayer1srcAddress(layer1handler.getSourceAddress(layer1packet)); packet.setLayer1dstAddress(layer1handler.getDestinationAddress(layer1packet)); if (WAN_ADDRESS != null) { // determine and store flow direction if possible if (packet.getLayer1srcAddress().equalsIgnoreCase(WAN_ADDRESS)) packet.setFlowDirection(FlowDirection.FROM_WAN); else if (packet.getLayer1dstAddress().equalsIgnoreCase(WAN_ADDRESS)) packet.setFlowDirection(FlowDirection.TO_WAN); else packet.setFlowDirection(FlowDirection.UNKNOWN); } if ((packet.getFlowDirection() == null || packet.getFlowDirection() == FlowDirection.UNKNOWN) && LAN_ADDRESS != null) { if (packet.getLayer1srcAddress().equalsIgnoreCase(LAN_ADDRESS)) packet.setFlowDirection(FlowDirection.TO_WAN); else if (packet.getLayer1dstAddress().equalsIgnoreCase(LAN_ADDRESS)) packet.setFlowDirection(FlowDirection.FROM_WAN); else packet.setFlowDirection(FlowDirection.UNKNOWN); } Protocol layer2protocol = layer1handler.getPayloadProtocol(layer1packet); packet.setLayer2protocol(layer2protocol); layer1payload = layer1handler.getPayload(layer1packet); //packet.setPayload(layer1payload); ProtocolHandler layer2handler = layer2protocol.getProtocolHandler(); if (layer2protocol == Protocol.UNKNOWN || layer2handler == null) return packet; // layer 2: byte[] layer2packet = layer1payload; byte[] layer2payload; if ( layer1handler.getPayloadLengthAccuracy(layer1packet) != LengthAccuracy.EXACT // the layer below is not sure about the size && layer2handler.getLengthAccuracy(layer2packet) == LengthAccuracy.EXACT // this layer knows the exact value ) packet.setLayer2length(layer2handler.getLength(layer2packet)); if (layer1handler.getPayloadLengthAccuracy(layer1packet) == LengthAccuracy.EXACT && layer2handler.getLengthAccuracy(layer2packet) == LengthAccuracy.EXACT ) { if (layer1handler.getPayloadLength(layer1packet) != layer2handler.getLength(layer2packet)) { // malformed packet return readPacket(packet); } } packet.setLayer3length(layer2handler.getPayloadLength(layer2packet)); packet.setLayer2srcAddress(layer2handler.getSourceAddress(layer2packet)); packet.setLayer2dstAddress(layer2handler.getDestinationAddress(layer2packet)); Protocol layer3protocol = layer2handler.getPayloadProtocol(layer2packet); packet.setLayer3protocol(layer3protocol); layer2payload = layer2handler.getPayload(layer2packet); //packet.setPayload(layer2payload); ProtocolHandler layer3handler = layer3protocol.getProtocolHandler(); if (layer3protocol == Protocol.UNKNOWN || layer3handler == null || layer2payload == null) { // try to find out about the actual size if (layer1handler.getPayloadLengthAccuracy(layer1packet) == LengthAccuracy.EXACT // the layer below is sure about the payload size && layer2handler.getHeaderLengthAccuracy(layer2packet) == LengthAccuracy.EXACT // this layer is sure about the header size ) packet.setLayer3length(layer1handler.getPayloadLength(layer1packet) - layer2handler.getHeaderLength(layer2packet)); return packet; } // layer 3: byte[] layer3packet = layer2payload; byte[] layer3payload; if ( layer2handler.getPayloadLengthAccuracy(layer2packet) != LengthAccuracy.EXACT // the layer below is not sure about the size && layer3handler.getLengthAccuracy(layer3packet) == LengthAccuracy.EXACT // this layer knows the exact value ) packet.setLayer3length(layer3handler.getLength(layer3packet)); if (layer2handler.getPayloadLengthAccuracy(layer2packet) == LengthAccuracy.EXACT && layer3handler.getLengthAccuracy(layer3packet) == LengthAccuracy.EXACT ) { if (layer2handler.getPayloadLength(layer2packet) != layer3handler.getLength(layer3packet)) { // malformed packet return readPacket(packet); } } packet.setLayer4length(layer3handler.getPayloadLength(layer3packet)); packet.setLayer3srcAddress(layer3handler.getSourceAddress(layer3packet)); packet.setLayer3dstAddress(layer3handler.getDestinationAddress(layer3packet)); if (layer3protocol == Protocol.TCP) { // store handshake status if possible boolean syn = TCPpacket.getFlag_SYN(layer3packet); boolean ack = TCPpacket.getFlag_ACK(layer3packet); boolean fin = TCPpacket.getFlag_FIN(layer3packet); if (syn && ack) packet.setTCPflags(TCPflags.SYN_ACK); else if (fin && ack) packet.setTCPflags(TCPflags.FIN_ACK); else if (syn) packet.setTCPflags(TCPflags.SYN); else if (ack) packet.setTCPflags(TCPflags.ACK); else packet.setTCPflags(TCPflags.NONE); } Protocol layer4protocol = layer3handler.getPayloadProtocol(layer3packet); packet.setLayer4protocol(layer4protocol); layer3payload = layer3handler.getPayload(layer3packet); //packet.setPayload(layer3payload); ProtocolHandler layer4handler = layer4protocol.getProtocolHandler(); if (layer4protocol == Protocol.UNKNOWN || layer4handler == null) { // try to find out about the actual size if (layer2handler.getPayloadLengthAccuracy(layer2packet) == LengthAccuracy.EXACT // the layer below is sure about the payload size && layer3handler.getHeaderLengthAccuracy(layer3packet) == LengthAccuracy.EXACT // this layer is sure about the header size ) packet.setLayer4length(layer2handler.getPayloadLength(layer2packet) - layer3handler.getHeaderLength(layer3packet)); return packet; } // layer 4: byte[] layer4packet = layer3payload; //byte[] layer4payload; if ( layer3handler.getPayloadLengthAccuracy(layer3packet) != LengthAccuracy.EXACT // the layer below is not sure about the size && layer4handler.getLengthAccuracy(layer4packet) == LengthAccuracy.EXACT // this layer knows the exact value ) packet.setLayer4length(layer4handler.getLength(layer4packet)); if (layer3handler.getPayloadLengthAccuracy(layer3packet) == LengthAccuracy.EXACT && layer4handler.getLengthAccuracy(layer4packet) == LengthAccuracy.EXACT ) { if (layer3handler.getPayloadLength(layer3packet) != layer4handler.getLength(layer4packet)) { // malformed packet return readPacket(packet); } } //layer4payload = layer4handler.getPayload(layer4packet); //packet.setPayload(layer4payload); return packet; } @Override public long getTotalBytesRead() { return read; } }