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 | ||
71f2817f | 13 | package org.eclipse.tracecompass.internal.pcap.core.stream; |
5255c030 | 14 | |
71f2817f AM |
15 | import org.eclipse.tracecompass.internal.pcap.core.endpoint.ProtocolEndpointPair; |
16 | import org.eclipse.tracecompass.internal.pcap.core.packet.Packet; | |
17 | import org.eclipse.tracecompass.internal.pcap.core.protocol.PcapProtocol; | |
18 | import org.eclipse.tracecompass.internal.pcap.core.protocol.pcap.PcapPacket; | |
5255c030 | 19 | |
f2fb631e VP |
20 | import com.google.common.math.DoubleMath; |
21 | ||
5255c030 VP |
22 | // TODO decide if default modifier a good idea. This allows only the |
23 | // stream builder to call that method (and any class that is added to this | |
24 | // package). This effectively makes the stream read-only. | |
25 | ||
26 | /** | |
27 | * Class that represents a packet stream, which is a collection of packets that | |
28 | * share the same endpoints. The endpoints of a packet are protocol-dependent. | |
29 | * For example, a TCP stream is a collection of packets that share the same MAC | |
30 | * address, IP address, and Port couple. | |
31 | * | |
32 | * @author Vincent Perot | |
33 | */ | |
34 | public class PacketStream { | |
35 | ||
f2fb631e VP |
36 | private static final double SECOND_TO_NANOSECOND = 1000000000.0; |
37 | private static final double DELTA = 0.000000001; | |
c88feda9 | 38 | private final PcapProtocol fProtocol; |
5255c030 VP |
39 | private final int fId; |
40 | private final ProtocolEndpointPair fEndpointPair; | |
41 | ||
f2fb631e VP |
42 | private long fNbPacketsAtoB; |
43 | private long fNbPacketsBtoA; | |
44 | private long fNbBytesAtoB; | |
45 | private long fNbBytesBtoA; | |
46 | private long fStartTime; | |
47 | private long fEndTime; | |
48 | ||
5255c030 VP |
49 | /** |
50 | * Constructor of a packet stream. | |
51 | * | |
52 | * @param protocol | |
53 | * The protocol of the packets of the stream. This is needed | |
54 | * because the definition of a stream is protocol-dependent. | |
55 | * @param id | |
56 | * The id of this stream. | |
57 | * @param endpointPair | |
58 | * The common endpoints of the packets in this stream. | |
59 | */ | |
c88feda9 | 60 | PacketStream(PcapProtocol protocol, int id, ProtocolEndpointPair endpointPair) { |
5255c030 | 61 | fProtocol = protocol; |
5255c030 VP |
62 | fId = id; |
63 | fEndpointPair = endpointPair; | |
f2fb631e VP |
64 | fNbPacketsAtoB = 0; |
65 | fNbPacketsBtoA = 0; | |
66 | fNbBytesAtoB = 0; | |
67 | fNbBytesBtoA = 0; | |
68 | fStartTime = Long.MAX_VALUE; | |
69 | fEndTime = Long.MIN_VALUE; | |
5255c030 VP |
70 | } |
71 | ||
72 | /** | |
f2fb631e | 73 | * Add a packet to the stream. |
5255c030 VP |
74 | * |
75 | * @param packet | |
f2fb631e | 76 | * The packet that must be added. |
5255c030 VP |
77 | */ |
78 | synchronized void add(PcapPacket packet) { | |
5255c030 | 79 | |
f2fb631e VP |
80 | Packet newPacket = packet.getPacket(fProtocol); |
81 | if (newPacket == null) { | |
82 | return; | |
83 | } | |
84 | ||
85 | // Update packet and byte number | |
86 | if (fEndpointPair.getFirstEndpoint().equals(newPacket.getSourceEndpoint()) && | |
87 | fEndpointPair.getSecondEndpoint().equals(newPacket.getDestinationEndpoint())) { | |
88 | fNbPacketsAtoB++; | |
89 | fNbBytesAtoB += packet.getOriginalLength(); | |
90 | } else if (fEndpointPair.getFirstEndpoint().equals(newPacket.getDestinationEndpoint()) && | |
91 | fEndpointPair.getSecondEndpoint().equals(newPacket.getSourceEndpoint())) { | |
92 | fNbPacketsBtoA++; | |
93 | fNbBytesBtoA += packet.getOriginalLength(); | |
94 | } else { | |
95 | throw new IllegalStateException(); | |
5255c030 | 96 | } |
f2fb631e VP |
97 | |
98 | // Update start and stop time | |
99 | // Stream timestamp is ALWAYS in nanoseconds. | |
100 | long timestamp; | |
101 | switch (packet.getTimestampScale()) { | |
102 | case MICROSECOND: | |
103 | timestamp = packet.getTimestamp() * 1000; | |
104 | break; | |
105 | case NANOSECOND: | |
106 | timestamp = packet.getTimestamp(); | |
107 | break; | |
108 | default: | |
109 | throw new IllegalArgumentException("The timestamp precision is not valid!"); //$NON-NLS-1$ | |
110 | } | |
111 | fStartTime = Math.min(fStartTime, timestamp); | |
112 | fEndTime = Math.max(fEndTime, timestamp); | |
5255c030 VP |
113 | } |
114 | ||
115 | /** | |
116 | * Get the Protocol of this stream. | |
117 | * | |
118 | * @return The protocol of this stream. | |
119 | */ | |
c88feda9 | 120 | public PcapProtocol getProtocol() { |
5255c030 VP |
121 | return fProtocol; |
122 | } | |
123 | ||
124 | /** | |
125 | * Method that returns the non-unique ID of this stream. | |
126 | * | |
127 | * @return the non-unique ID of this stream. | |
128 | */ | |
129 | public int getID() { | |
130 | return fId; | |
131 | } | |
132 | ||
133 | /** | |
134 | * Method that returns the unique ID of this stream. | |
135 | * | |
136 | * @return the unique ID of this stream. | |
137 | */ | |
138 | public String getUniqueID() { | |
139 | return fProtocol.getShortName() + '.' + fId; | |
140 | } | |
141 | ||
142 | /** | |
143 | * Method that returns the endpoint pair of the stream. | |
144 | * | |
145 | * @return The endpoint pair of the stream. | |
146 | */ | |
147 | public ProtocolEndpointPair getEndpointPair() { | |
148 | return fEndpointPair; | |
149 | } | |
150 | ||
151 | // TODO return also the endpoint set. | |
152 | @Override | |
153 | public synchronized String toString() { | |
154 | StringBuilder sb = new StringBuilder(); | |
f2fb631e | 155 | sb.append("Stream " + getUniqueID() + ", Number of Packets: " + getNbPackets() + "\n"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ |
5255c030 | 156 | |
0e4f957e | 157 | return sb.toString(); |
5255c030 VP |
158 | |
159 | } | |
160 | ||
161 | /** | |
f2fb631e VP |
162 | * Get the number of packets going from the first endpoint to the second. |
163 | * | |
164 | * @return The number of packets from A to B. | |
165 | */ | |
166 | public synchronized long getNbPacketsAtoB() { | |
167 | return fNbPacketsAtoB; | |
168 | } | |
169 | ||
170 | /** | |
171 | * Get the number of packets going from the second endpoint to the first. | |
172 | * | |
173 | * @return The number of packets from B to A. | |
174 | */ | |
175 | public synchronized long getNbPacketsBtoA() { | |
176 | return fNbPacketsBtoA; | |
177 | } | |
178 | ||
179 | /** | |
180 | * Get the total number of packets in this stream. | |
181 | * | |
182 | * @return The total number of packets. | |
183 | */ | |
184 | public synchronized long getNbPackets() { | |
185 | return fNbPacketsAtoB + fNbPacketsBtoA; | |
186 | } | |
187 | ||
188 | /** | |
189 | * Get the number of bytes going from the first endpoint to the second. | |
190 | * | |
191 | * @return The number of bytes from A to B. | |
192 | */ | |
193 | public synchronized long getNbBytesAtoB() { | |
194 | return fNbBytesAtoB; | |
195 | } | |
196 | ||
197 | /** | |
198 | * Get the number of bytes going from the second endpoint to the first. | |
199 | * | |
200 | * @return The number of bytes from B to A. | |
201 | */ | |
202 | public synchronized long getNbBytesBtoA() { | |
203 | return fNbBytesBtoA; | |
204 | } | |
205 | ||
206 | /** | |
207 | * Get the total number of bytes in this stream. | |
5255c030 | 208 | * |
f2fb631e | 209 | * @return The total number of bytes. |
5255c030 | 210 | */ |
f2fb631e VP |
211 | public synchronized long getNbBytes() { |
212 | return fNbBytesAtoB + fNbBytesBtoA; | |
213 | } | |
214 | ||
215 | /** | |
216 | * Get the start time of this stream, in nanoseconds relative to epoch. | |
217 | * | |
218 | * @return The start time. | |
219 | */ | |
220 | public synchronized long getStartTime() { | |
221 | return fStartTime; | |
222 | } | |
223 | ||
224 | /** | |
225 | * Get the stop time of this stream, in nanoseconds relative to epoch. | |
226 | * | |
227 | * @return The stop time. | |
228 | */ | |
229 | public synchronized long getStopTime() { | |
230 | return fEndTime; | |
231 | } | |
232 | ||
233 | /** | |
234 | * Get the duration of this stream, in seconds | |
235 | * | |
236 | * @return The duration of this stream. | |
237 | */ | |
238 | public synchronized double getDuration() { | |
239 | return (fEndTime - fStartTime) / SECOND_TO_NANOSECOND; | |
240 | } | |
241 | ||
242 | /** | |
243 | * Get the the average byte per second from A to B. | |
244 | * | |
245 | * @return the average byte per second from A to B. | |
246 | */ | |
247 | public synchronized double getBPSAtoB() { | |
248 | if (DoubleMath.fuzzyEquals(getDuration(), 0, DELTA)) { | |
249 | return 0; | |
250 | } | |
251 | return fNbBytesAtoB / getDuration(); | |
252 | } | |
253 | ||
254 | /** | |
255 | * Get the the average byte per second from B to A. | |
256 | * | |
257 | * @return the average byte per second from B to A. | |
258 | */ | |
259 | public synchronized double getBPSBtoA() { | |
260 | if (DoubleMath.fuzzyEquals(getDuration(), 0, DELTA)) { | |
261 | return 0; | |
262 | } | |
263 | return fNbBytesBtoA / getDuration(); | |
5255c030 VP |
264 | } |
265 | ||
266 | } |