btf: Move the plugins to their own sub-directory
[deliverable/tracecompass.git] / org.eclipse.tracecompass.pcap.core / src / org / eclipse / tracecompass / internal / pcap / core / packet / Packet.java
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.tracecompass.internal.pcap.core.packet;
14
15 import java.nio.ByteBuffer;
16 import java.util.Map;
17
18 import org.eclipse.jdt.annotation.NonNull;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.eclipse.tracecompass.internal.pcap.core.endpoint.ProtocolEndpoint;
21 import org.eclipse.tracecompass.internal.pcap.core.protocol.PcapProtocol;
22 import org.eclipse.tracecompass.internal.pcap.core.protocol.ipv4.IPv4Packet;
23 import org.eclipse.tracecompass.internal.pcap.core.protocol.unknown.UnknownPacket;
24 import org.eclipse.tracecompass.internal.pcap.core.trace.PcapFile;
25
26 // TODO For all packets, make checks on dimension.
27 // TODO maybe add a invalid packet type?
28
29 /**
30 * Abstract class that implements the methods that are common to every packets.
31 *
32 * @author Vincent Perot
33 */
34 public abstract class Packet {
35
36 /** Empty string */
37 protected static final String EMPTY_STRING = ""; //$NON-NLS-1$
38
39 /** The Pcap File to which this packet belong */
40 private final PcapFile fPcapFile;
41
42 /** The parent packet of this packet */
43 private final @Nullable Packet fParentPacket;
44
45 /** The protocol that this packet uses */
46 private final PcapProtocol fProtocol;
47
48 /**
49 * Constructor of the Packet Class.
50 *
51 * @param file
52 * The file to which this packet belongs.
53 * @param parent
54 * The parent packet of this packet.
55 * @param protocol
56 * The protocol of the packet.
57 */
58 public Packet(PcapFile file, @Nullable Packet parent, PcapProtocol protocol) {
59 fPcapFile = file;
60 fParentPacket = parent;
61 fProtocol = protocol;
62 }
63
64 /**
65 * Getter method for the Pcap File that contains this packet.
66 *
67 * @return The Pcap File.
68 */
69 public PcapFile getPcapFile() {
70 return fPcapFile;
71 }
72
73 /**
74 * Method that returns the parent (encapsulating) packet of this packet.
75 * This method returns null if the packet is a Pcap Packet (highest level of
76 * encapsulation).
77 *
78 * @return The parent packet.
79 */
80 public @Nullable Packet getParentPacket() {
81 return fParentPacket;
82 }
83
84 /**
85 * Method that returns the child (encapsulated) packet of this packet. This
86 * method returns null if the packet is at the lowest level of
87 * encapsulation.
88 *
89 * @return The child packet.
90 */
91 public abstract @Nullable Packet getChildPacket();
92
93 /**
94 * Getter method for the protocol of the packet.
95 *
96 * @return The protocol of the packet.
97 */
98 public PcapProtocol getProtocol() {
99 return fProtocol;
100 }
101
102 /**
103 * Getter method for the payload of the packet. Returns null if there is no
104 * payload.
105 *
106 * @return the payload of the packet.
107 */
108 public abstract @Nullable ByteBuffer getPayload();
109
110 /**
111 * Method that looks for the packet that respects the specified protocol. It
112 * will go through all the layers of encapsulation and return the wanted
113 * packet, or null if the protocol is not present.
114 *
115 * @param protocol
116 * The specified protocol.
117 * @return The packet that respects the protocol.
118 */
119 public final @Nullable Packet getPacket(PcapProtocol protocol) {
120
121 Packet wantedPacket = this;
122
123 while (wantedPacket != null) {
124 if (wantedPacket.getProtocol() == protocol) {
125 return wantedPacket;
126 }
127 wantedPacket = wantedPacket.getParentPacket();
128 }
129 wantedPacket = this.getChildPacket();
130
131 while (wantedPacket != null) {
132 if (wantedPacket.getProtocol() == protocol) {
133 return wantedPacket;
134 }
135 wantedPacket = wantedPacket.getChildPacket();
136 }
137
138 return null;
139 }
140
141 /**
142 * Method that looks if the protocol is contained in the packet, or in one
143 * of the encapsulating/encapsulated packet. It will go through all the
144 * layers of encapsulation and return true if it finds the specified
145 * protocol, and false otherwise. *
146 *
147 * @param protocol
148 * The specified protocol.
149 * @return The presence of the protocol.
150 */
151 public final boolean hasProtocol(PcapProtocol protocol) {
152
153 // TODO Verify inputs
154 Packet wantedPacket = this;
155
156 while (wantedPacket != null) {
157 if (wantedPacket.getProtocol() == protocol) {
158 return true;
159 }
160 wantedPacket = wantedPacket.getParentPacket();
161 }
162 wantedPacket = this.getChildPacket();
163
164 while (wantedPacket != null) {
165 if (wantedPacket.getProtocol() == protocol) {
166 return true;
167 }
168 wantedPacket = wantedPacket.getChildPacket();
169 }
170
171 return false;
172 }
173
174 /**
175 * Method that returns the most encapsulated packet possible. If the global
176 * packet contains the protocol Unknown, it will stop at the packet just
177 * before this protocol. This is because the {@link UnknownPacket} can be
178 * considered as plain payload.
179 *
180 * @return The most encapsulated packet.
181 */
182 public Packet getMostEcapsulatedPacket() {
183 @NonNull Packet packet = this;
184 while (packet.getProtocol() != PcapProtocol.UNKNOWN) {
185 Packet childPacket = packet.getChildPacket();
186 if (childPacket == null || childPacket.getProtocol() == PcapProtocol.UNKNOWN) {
187 break;
188 }
189 packet = childPacket;
190 }
191 return packet;
192 }
193
194 /**
195 * Method that look at the validity of the different fields (such as
196 * checksum). This is protocol dependent and is used to identify bad
197 * packets.
198 *
199 * @return The validity of the packet.
200 */
201 public abstract boolean validate();
202
203 /**
204 * Internal method that is used to find the child packet. This is protocol
205 * dependent and must be implemented by each packet class.
206 *
207 * @return The child packet.
208 * @throws BadPacketException
209 * Thrown when the packet is erroneous.
210 */
211 protected abstract @Nullable Packet findChildPacket() throws BadPacketException;
212
213 /**
214 * This method returns the source endpoint of this packet. The endpoint is
215 * equivalent to the address of this packet, and is protocol dependent. For
216 * instance, a UDP endpoint is the combination of the MAC address, the IP
217 * address and the port number.
218 *
219 * @return The source endpoint of this packet.
220 */
221 public abstract ProtocolEndpoint getSourceEndpoint();
222
223 /**
224 * This method returns the destination endpoint of this packet. The endpoint
225 * is equivalent to the address of this packet, and is protocol dependent.
226 * For instance, a UDP endpoint is the combination of the MAC address, the
227 * IP address and the port number.
228 *
229 * @return The destination endpoint of this packet.
230 */
231 public abstract ProtocolEndpoint getDestinationEndpoint();
232
233 /**
234 * Method that returns all the fields of the packet as a Map<Field ID, Field
235 * Value>. All child classes of {@link Packet} must implement this method.
236 *
237 * @return All the packet fields as a map.
238 */
239 public abstract Map<String, String> getFields();
240
241 /**
242 * Method that returns a short summary of the local packet, such as the most
243 * useful information.
244 *
245 * For instance, a possible summary string of an {@link IPv4Packet} can be:
246 * "Src: 192.168.0.1, Dst: 192.168.1.12".
247 *
248 * @return A short summary of the local packet, as a string.
249 */
250 public abstract String getLocalSummaryString();
251
252 /**
253 * Method that returns the local meaning of a packet, based on its fields.
254 *
255 * For instance, a possible signification of an ARP packet can be:
256 * "Who has 192.168.1.12? Tell 192.168.0.1".
257 *
258 * @return The local meaning of the packet, as a string.
259 */
260 protected abstract String getSignificationString();
261
262 /**
263 * Method that returns the global meaning of the packet. As such, it will
264 * look for the most relevant packet and display its signification.
265 *
266 * For instance, a possible signification of an ARP packet can be:
267 * "Who has 192.168.1.12? Tell 192.168.0.1".
268 *
269 * @return The meaning of the global packet, as a string.
270 */
271 public final String getGlobalSummaryString() {
272 Packet packet = this.getMostEcapsulatedPacket();
273 return packet.getSignificationString();
274 }
275
276 @Override
277 public abstract boolean equals(@Nullable Object obj);
278
279 @Override
280 public abstract int hashCode();
281
282 /**
283 * Method that is used by child packet classes to verify if a bit is set.
284 *
285 * @param value
286 * the byte containing the flags.
287 * @param bit
288 * the bit index.
289 * @return Whether the bit is set or not.
290 */
291 protected static final boolean isBitSet(byte value, int bit) {
292 if (bit < 0 || bit > 7) {
293 throw new IllegalArgumentException("The byte index is not valid!"); //$NON-NLS-1$
294 }
295 return ((value >>> bit & 0b1) == 0b1);
296 }
297 }
This page took 0.036722 seconds and 5 git commands to generate.