tmf: Initial commit of Pcap Parser
[deliverable/tracecompass.git] / org.eclipse.linuxtools.pcap.core / src / org / eclipse / linuxtools / 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.linuxtools.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.linuxtools.pcap.core.endpoint.ProtocolEndpoint;
21 import org.eclipse.linuxtools.pcap.core.protocol.Protocol;
22 import org.eclipse.linuxtools.pcap.core.protocol.ipv4.IPv4Packet;
23 import org.eclipse.linuxtools.pcap.core.protocol.unknown.UnknownPacket;
24 import org.eclipse.linuxtools.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 Protocol 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, Protocol 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 Protocol 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(Protocol 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(Protocol 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
184 Packet packet = this;
185 while (packet.getProtocol() != Protocol.UNKNOWN) {
186 Packet childPacket = packet.getChildPacket();
187 if (childPacket == null || childPacket.getProtocol() == Protocol.UNKNOWN) {
188 break;
189 }
190 packet = childPacket;
191 }
192 return packet;
193 }
194
195 /**
196 * Method that look at the validity of the different fields (such as
197 * checksum). This is protocol dependent and is used to identify bad
198 * packets.
199 *
200 * @return The validity of the packet.
201 */
202 public abstract boolean validate();
203
204 /**
205 * Internal method that is used to find the child packet. This is protocol
206 * dependent and must be implemented by each packet class.
207 *
208 * @return The child packet.
209 * @throws BadPacketException
210 * Thrown when the packet is erroneous.
211 */
212 protected abstract @Nullable Packet findChildPacket() throws BadPacketException;
213
214 /**
215 * This method returns the source endpoint of this packet. The endpoint is
216 * equivalent to the address of this packet, and is protocol dependent. For
217 * instance, a UDP endpoint is the combination of the MAC address, the IP
218 * address and the port number.
219 *
220 * @return The source endpoint of this packet.
221 */
222 public abstract ProtocolEndpoint getSourceEndpoint();
223
224 /**
225 * This method returns the destination endpoint of this packet. The endpoint
226 * is equivalent to the address of this packet, and is protocol dependent.
227 * For instance, a UDP endpoint is the combination of the MAC address, the
228 * IP address and the port number.
229 *
230 * @return The destination endpoint of this packet.
231 */
232 public abstract ProtocolEndpoint getDestinationEndpoint();
233
234 /**
235 * Method that returns all the fields of the packet as a Map<Field ID, Field
236 * Value>. All child classes of {@link Packet} must implement this method.
237 *
238 * @return All the packet fields as a map.
239 */
240 public abstract Map<String, String> getFields();
241
242 /**
243 * Method that returns a short summary of the local packet, such as the most
244 * useful information.
245 *
246 * For instance, a possible summary string of an {@link IPv4Packet} can be:
247 * "Src: 192.168.0.1, Dst: 192.168.1.12".
248 *
249 * @return A short summary of the local packet, as a string.
250 */
251 public abstract String getLocalSummaryString();
252
253 /**
254 * Method that returns the local meaning of a packet, based on its fields.
255 *
256 * For instance, a possible signification of an ARP packet can be:
257 * "Who has 192.168.1.12? Tell 192.168.0.1".
258 *
259 * @return The local meaning of the packet, as a string.
260 */
261 protected abstract String getSignificationString();
262
263 /**
264 * Method that returns the global meaning of the packet. As such, it will
265 * look for the most relevant packet and display its signification.
266 *
267 * For instance, a possible signification of an ARP packet can be:
268 * "Who has 192.168.1.12? Tell 192.168.0.1".
269 *
270 * @return The meaning of the global packet, as a string.
271 */
272 public final String getGlobalSummaryString() {
273 Packet packet = this.getMostEcapsulatedPacket();
274 return packet.getSignificationString();
275 }
276
277 @Override
278 public abstract boolean equals(@Nullable Object obj);
279
280 @Override
281 public abstract int hashCode();
282
283 /**
284 * Method that is used by child packet classes to verify if a bit is set.
285 *
286 * @param value
287 * the byte containing the flags.
288 * @param bit
289 * the bit index.
290 * @return Whether the bit is set or not.
291 */
292 protected static final boolean isBitSet(byte value, int bit) {
293 if (bit < 0 || bit > 7) {
294 throw new IllegalArgumentException("The byte index is not valid!"); //$NON-NLS-1$
295 }
296 return ((value >>> bit & 0b1) == 0b1);
297 }
298 }
This page took 0.038117 seconds and 5 git commands to generate.