Commit | Line | Data |
---|---|---|
5255c030 VP |
1 | /******************************************************************************* |
2 | * Copyright (c) 2014 Ericsson | |
3 | * | |
4 | * All rights reserved. This program and the accompanying materials are | |
5 | * made available under the terms of the Eclipse Public License v1.0 which | |
6 | * accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | * | |
9 | * Contributors: | |
10 | * Vincent Perot - Initial API and implementation | |
11 | *******************************************************************************/ | |
12 | ||
13 | package org.eclipse.linuxtools.pcap.core.stream; | |
14 | ||
15 | import java.io.IOException; | |
16 | import java.util.HashMap; | |
17 | import java.util.LinkedList; | |
18 | import java.util.Map; | |
19 | ||
20 | import org.eclipse.jdt.annotation.Nullable; | |
21 | import org.eclipse.linuxtools.pcap.core.endpoint.ProtocolEndpoint; | |
22 | import org.eclipse.linuxtools.pcap.core.endpoint.ProtocolEndpointPair; | |
23 | import org.eclipse.linuxtools.pcap.core.filter.IPacketFilter; | |
24 | import org.eclipse.linuxtools.pcap.core.filter.PacketFilterByProtocol; | |
25 | import org.eclipse.linuxtools.pcap.core.packet.BadPacketException; | |
26 | import org.eclipse.linuxtools.pcap.core.packet.Packet; | |
27 | import org.eclipse.linuxtools.pcap.core.protocol.Protocol; | |
28 | import org.eclipse.linuxtools.pcap.core.protocol.pcap.PcapPacket; | |
29 | import org.eclipse.linuxtools.pcap.core.trace.BadPcapFileException; | |
30 | import org.eclipse.linuxtools.pcap.core.trace.PcapFile; | |
31 | ||
32 | /** | |
33 | * Class that parse an entire pcap file to build the different streams. | |
34 | * | |
35 | * @author Vincent Perot | |
36 | */ | |
37 | public class PacketStreamBuilder { | |
38 | ||
39 | private final IPacketFilter fPacketFilter; | |
40 | private final Protocol fProtocol; | |
41 | ||
42 | private final Map<Integer, PacketStream> fStreams; | |
43 | private final Map<ProtocolEndpointPair, Integer> fIDs; | |
44 | private int fCurrentId; | |
45 | ||
46 | /** | |
47 | * Main constructor. | |
48 | * | |
49 | * @param protocol | |
50 | * The protocol of the builder. | |
51 | */ | |
52 | public PacketStreamBuilder(Protocol protocol) { | |
53 | fCurrentId = 0; | |
54 | fProtocol = protocol; | |
55 | fPacketFilter = new PacketFilterByProtocol(protocol); | |
56 | fStreams = new HashMap<>(); | |
57 | fIDs = new HashMap<>(); | |
58 | } | |
59 | ||
60 | /** | |
61 | * Method that returns a particular stream based on its ID. | |
62 | * | |
63 | * @param id | |
64 | * The ID of the stream. | |
65 | * @return The stream that has the specified ID. | |
66 | */ | |
67 | public synchronized @Nullable PacketStream getStream(int id) { | |
68 | return fStreams.get(id); | |
69 | } | |
70 | ||
71 | /** | |
72 | * Method that returns a particular stream based on its endpoints. It | |
73 | * returns null if no corresponding stream is found. | |
74 | * | |
75 | * @param endpointA | |
76 | * The first endpoint of the stream. | |
77 | * @param endpointB | |
78 | * The second endpoint of the stream. | |
79 | * | |
80 | * @return The stream that has the specified endpoints. Return Null if no | |
81 | * stream is found between the two endpoints. | |
82 | */ | |
83 | public synchronized @Nullable PacketStream getStream(ProtocolEndpoint endpointA, ProtocolEndpoint endpointB) { | |
84 | ProtocolEndpointPair set = new ProtocolEndpointPair(endpointA, endpointB); | |
85 | int id = fIDs.get(set); | |
86 | return fStreams.get(id); | |
87 | } | |
88 | ||
89 | /** | |
90 | * Method that returns all the streams at the specified protocol level. | |
91 | * | |
92 | * @return The streams as a list. | |
93 | */ | |
94 | public synchronized Iterable<PacketStream> getStreams() { | |
95 | Iterable<PacketStream> iterable = new LinkedList<>(fStreams.values()); | |
96 | return iterable; | |
97 | } | |
98 | ||
99 | /** | |
100 | * Method that is called when the filter accepts a packet. This methods add | |
101 | * the packet to a stream based on its characteristics. | |
102 | * | |
103 | * @param packet | |
104 | * The packet to be added. | |
105 | */ | |
106 | public synchronized void addPacketToStream(PcapPacket packet) { | |
107 | if (fPacketFilter.accepts(packet)) { | |
108 | @Nullable Packet newPacket = packet.getPacket(fProtocol); | |
109 | if (newPacket == null) { | |
110 | return; | |
111 | } | |
112 | ProtocolEndpointPair endpointSet = new ProtocolEndpointPair(newPacket); | |
113 | if (!fIDs.containsKey(endpointSet)) { | |
114 | fIDs.put(endpointSet, fCurrentId); | |
115 | fStreams.put(fCurrentId, new PacketStream(fProtocol, fCurrentId, endpointSet)); | |
116 | fStreams.get(fCurrentId).add(packet); | |
117 | fCurrentId++; | |
118 | } else { | |
119 | Integer id = fIDs.get(endpointSet); | |
120 | fStreams.get(id).add(packet); | |
121 | } | |
122 | } | |
123 | return; | |
124 | } | |
125 | ||
126 | /** | |
127 | * Getter method for the protocol of the stream builder. | |
128 | * | |
129 | * @return The protocol. | |
130 | */ | |
131 | public Protocol getProtocol() { | |
132 | return fProtocol; | |
133 | } | |
134 | ||
135 | /** | |
136 | * Method that clears the builder. | |
137 | */ | |
138 | public void clear() { | |
139 | fStreams.clear(); | |
140 | fIDs.clear(); | |
141 | fCurrentId = 0; | |
142 | } | |
143 | ||
144 | /** | |
145 | * Method that returns the number of streams built. | |
146 | * | |
147 | * @return The number of streams built. | |
148 | */ | |
149 | public synchronized int getNbStreams() { | |
150 | return fStreams.size(); | |
151 | } | |
152 | ||
153 | /** | |
154 | * Method that parse an entire file and build the streams contained in the | |
155 | * file. | |
156 | * | |
157 | * @param file | |
158 | * The file path. | |
159 | * @throws IOException | |
160 | * When an IO error occurs. | |
161 | * @throws BadPcapFileException | |
162 | * When the PcapFile is not valid. | |
163 | */ | |
d6fca387 | 164 | public synchronized void parsePcapFile(String file) throws IOException, BadPcapFileException { |
5255c030 VP |
165 | try (PcapFile pcapFile = new PcapFile(file);) { |
166 | while (pcapFile.hasNextPacket()) { // not eof | |
167 | PcapPacket packet; | |
168 | try { | |
169 | packet = pcapFile.parseNextPacket(); | |
170 | if (packet == null) { | |
171 | return; | |
172 | } | |
173 | addPacketToStream(packet); | |
174 | } catch (BadPacketException e) { | |
175 | // Ignore packet. Do nothing. | |
176 | } | |
177 | } | |
178 | } | |
179 | ||
180 | } | |
181 | } |