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