1 /*******************************************************************************
2 * Copyright (c) 2014 Ericsson
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
10 * Vincent Perot - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.internal
.pcap
.core
.stream
;
15 import org
.eclipse
.jdt
.annotation
.NonNull
;
16 import org
.eclipse
.linuxtools
.internal
.pcap
.core
.endpoint
.ProtocolEndpointPair
;
17 import org
.eclipse
.linuxtools
.internal
.pcap
.core
.packet
.Packet
;
18 import org
.eclipse
.linuxtools
.internal
.pcap
.core
.protocol
.PcapProtocol
;
19 import org
.eclipse
.linuxtools
.internal
.pcap
.core
.protocol
.pcap
.PcapPacket
;
21 import com
.google
.common
.math
.DoubleMath
;
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.
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.
33 * @author Vincent Perot
35 public class PacketStream
{
37 private static final double SECOND_TO_NANOSECOND
= 1000000000.0;
38 private static final double DELTA
= 0.000000001;
39 private final PcapProtocol fProtocol
;
40 private final int fId
;
41 private final ProtocolEndpointPair fEndpointPair
;
43 private long fNbPacketsAtoB
;
44 private long fNbPacketsBtoA
;
45 private long fNbBytesAtoB
;
46 private long fNbBytesBtoA
;
47 private long fStartTime
;
48 private long fEndTime
;
51 * Constructor of a packet stream.
54 * The protocol of the packets of the stream. This is needed
55 * because the definition of a stream is protocol-dependent.
57 * The id of this stream.
59 * The common endpoints of the packets in this stream.
61 PacketStream(PcapProtocol protocol
, int id
, ProtocolEndpointPair endpointPair
) {
64 fEndpointPair
= endpointPair
;
69 fStartTime
= Long
.MAX_VALUE
;
70 fEndTime
= Long
.MIN_VALUE
;
74 * Add a packet to the stream.
77 * The packet that must be added.
79 synchronized void add(PcapPacket packet
) {
81 Packet newPacket
= packet
.getPacket(fProtocol
);
82 if (newPacket
== null) {
86 // Update packet and byte number
87 if (fEndpointPair
.getFirstEndpoint().equals(newPacket
.getSourceEndpoint()) &&
88 fEndpointPair
.getSecondEndpoint().equals(newPacket
.getDestinationEndpoint())) {
90 fNbBytesAtoB
+= packet
.getOriginalLength();
91 } else if (fEndpointPair
.getFirstEndpoint().equals(newPacket
.getDestinationEndpoint()) &&
92 fEndpointPair
.getSecondEndpoint().equals(newPacket
.getSourceEndpoint())) {
94 fNbBytesBtoA
+= packet
.getOriginalLength();
96 throw new IllegalStateException();
99 // Update start and stop time
100 // Stream timestamp is ALWAYS in nanoseconds.
102 switch (packet
.getTimestampScale()) {
104 timestamp
= packet
.getTimestamp() * 1000;
107 timestamp
= packet
.getTimestamp();
110 throw new IllegalArgumentException("The timestamp precision is not valid!"); //$NON-NLS-1$
112 fStartTime
= Math
.min(fStartTime
, timestamp
);
113 fEndTime
= Math
.max(fEndTime
, timestamp
);
117 * Get the Protocol of this stream.
119 * @return The protocol of this stream.
121 public PcapProtocol
getProtocol() {
126 * Method that returns the non-unique ID of this stream.
128 * @return the non-unique ID of this stream.
135 * Method that returns the unique ID of this stream.
137 * @return the unique ID of this stream.
139 public String
getUniqueID() {
140 return fProtocol
.getShortName() + '.' + fId
;
144 * Method that returns the endpoint pair of the stream.
146 * @return The endpoint pair of the stream.
148 public ProtocolEndpointPair
getEndpointPair() {
149 return fEndpointPair
;
152 // TODO return also the endpoint set.
154 public synchronized String
toString() {
155 StringBuilder sb
= new StringBuilder();
156 sb
.append("Stream " + getUniqueID() + ", Number of Packets: " + getNbPackets() + "\n"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
158 @SuppressWarnings("null")
159 @NonNull String string
= sb
.toString();
165 * Get the number of packets going from the first endpoint to the second.
167 * @return The number of packets from A to B.
169 public synchronized long getNbPacketsAtoB() {
170 return fNbPacketsAtoB
;
174 * Get the number of packets going from the second endpoint to the first.
176 * @return The number of packets from B to A.
178 public synchronized long getNbPacketsBtoA() {
179 return fNbPacketsBtoA
;
183 * Get the total number of packets in this stream.
185 * @return The total number of packets.
187 public synchronized long getNbPackets() {
188 return fNbPacketsAtoB
+ fNbPacketsBtoA
;
192 * Get the number of bytes going from the first endpoint to the second.
194 * @return The number of bytes from A to B.
196 public synchronized long getNbBytesAtoB() {
201 * Get the number of bytes going from the second endpoint to the first.
203 * @return The number of bytes from B to A.
205 public synchronized long getNbBytesBtoA() {
210 * Get the total number of bytes in this stream.
212 * @return The total number of bytes.
214 public synchronized long getNbBytes() {
215 return fNbBytesAtoB
+ fNbBytesBtoA
;
219 * Get the start time of this stream, in nanoseconds relative to epoch.
221 * @return The start time.
223 public synchronized long getStartTime() {
228 * Get the stop time of this stream, in nanoseconds relative to epoch.
230 * @return The stop time.
232 public synchronized long getStopTime() {
237 * Get the duration of this stream, in seconds
239 * @return The duration of this stream.
241 public synchronized double getDuration() {
242 return (fEndTime
- fStartTime
) / SECOND_TO_NANOSECOND
;
246 * Get the the average byte per second from A to B.
248 * @return the average byte per second from A to B.
250 public synchronized double getBPSAtoB() {
251 if (DoubleMath
.fuzzyEquals(getDuration(), 0, DELTA
)) {
254 return fNbBytesAtoB
/ getDuration();
258 * Get the the average byte per second from B to A.
260 * @return the average byte per second from B to A.
262 public synchronized double getBPSBtoA() {
263 if (DoubleMath
.fuzzyEquals(getDuration(), 0, DELTA
)) {
266 return fNbBytesBtoA
/ getDuration();