lttng: Move plugins to the Trace Compass namespace
[deliverable/tracecompass.git] / org.eclipse.linuxtools.pcap.core / src / org / eclipse / linuxtools / internal / pcap / core / protocol / ethernet2 / EthernetIIPacket.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.internal.pcap.core.protocol.ethernet2;
14
15 import java.nio.ByteBuffer;
16 import java.nio.ByteOrder;
17 import java.util.Arrays;
18 import java.util.Map;
19
20 import org.eclipse.jdt.annotation.NonNull;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.eclipse.linuxtools.internal.pcap.core.packet.BadPacketException;
23 import org.eclipse.linuxtools.internal.pcap.core.packet.Packet;
24 import org.eclipse.linuxtools.internal.pcap.core.protocol.PcapProtocol;
25 import org.eclipse.linuxtools.internal.pcap.core.protocol.ipv4.IPv4Packet;
26 import org.eclipse.linuxtools.internal.pcap.core.protocol.unknown.UnknownPacket;
27 import org.eclipse.linuxtools.internal.pcap.core.trace.PcapFile;
28 import org.eclipse.linuxtools.internal.pcap.core.util.ConversionHelper;
29 import org.eclipse.linuxtools.internal.pcap.core.util.EthertypeHelper;
30
31 import com.google.common.collect.ImmutableMap;
32
33 /**
34 * Class that represents an Ethernet II packet. This should be called an
35 * Ethernet frame, but in order to keep the nomenclature consistent, this is
36 * called a packet.
37 *
38 * @author Vincent Perot
39 */
40 public class EthernetIIPacket extends Packet {
41
42 private final @Nullable Packet fChildPacket;
43 private final @Nullable ByteBuffer fPayload;
44
45 /* We store MAC addresses as byte arrays since
46 * there is no standard java class to store them. */
47 private final byte[] fSourceMacAddress;
48 private final byte[] fDestinationMacAddress;
49
50 private final int fType;
51
52 private @Nullable EthernetIIEndpoint fSourceEndpoint;
53 private @Nullable EthernetIIEndpoint fDestinationEndpoint;
54
55 private @Nullable ImmutableMap<String, String> fFields;
56
57 /**
58 * Constructor of the Ethernet Packet class.
59 *
60 * @param file
61 * The file that contains this packet.
62 * @param parent
63 * The parent packet of this packet (the encapsulating packet).
64 * @param packet
65 * The entire packet (header and payload).
66 * @throws BadPacketException
67 * Thrown when the packet is erroneous.
68 */
69 public EthernetIIPacket(PcapFile file, @Nullable Packet parent, ByteBuffer packet) throws BadPacketException {
70 super(file, parent, PcapProtocol.ETHERNET_II);
71
72 if (packet.array().length <= EthernetIIValues.ETHERNET_II_MIN_SIZE) {
73 throw new BadPacketException("An Ethernet II packet can't be smaller than 14 bytes."); //$NON-NLS-1$
74 }
75
76 // The endpoints are lazy loaded. They are defined in the get*Endpoint()
77 // methods.
78 fSourceEndpoint = null;
79 fDestinationEndpoint = null;
80
81 fFields = null;
82
83 fDestinationMacAddress = new byte[EthernetIIValues.MAC_ADDRESS_SIZE];
84 fSourceMacAddress = new byte[EthernetIIValues.MAC_ADDRESS_SIZE];
85 packet.order(ByteOrder.BIG_ENDIAN);
86 packet.position(0);
87 packet.get(fDestinationMacAddress);
88 packet.get(fSourceMacAddress);
89 fType = ConversionHelper.unsignedShortToInt(packet.getShort());
90
91 // Get payload if it exists.
92 if (packet.array().length - packet.position() > 0) {
93 byte[] array = new byte[packet.array().length - packet.position()];
94 packet.get(array);
95 ByteBuffer payload = ByteBuffer.wrap(array);
96 if (payload != null) {
97 payload.order(ByteOrder.BIG_ENDIAN);
98 payload.position(0);
99 }
100 fPayload = payload;
101
102 } else {
103 fPayload = null;
104 }
105
106 // Find child
107 fChildPacket = findChildPacket();
108
109 }
110
111 @Override
112 public @Nullable Packet getChildPacket() {
113 return fChildPacket;
114 }
115
116 @Override
117 public @Nullable ByteBuffer getPayload() {
118 return fPayload;
119 }
120
121 /**
122 * Getter method for the source MAC Address.
123 *
124 * @return The source MAC address.
125 */
126 public byte[] getSourceMacAddress() {
127 @SuppressWarnings("null")
128 @NonNull byte[] mac = Arrays.copyOf(fSourceMacAddress, fSourceMacAddress.length);
129 return mac;
130 }
131
132 /**
133 * Getter method for the destination MAC Address.
134 *
135 * @return The destination MAC address.
136 */
137 public byte[] getDestinationMacAddress() {
138 @SuppressWarnings("null")
139 @NonNull byte[] mac = Arrays.copyOf(fDestinationMacAddress, fDestinationMacAddress.length);
140 return mac;
141 }
142
143 /**
144 * Getter method for Ethertype. See
145 * http://standards.ieee.org/develop/regauth/ethertype/eth.txt
146 *
147 * @return The Ethertype. This is used to determine the child packet..
148 */
149 public int getEthertype() {
150 return fType;
151 }
152
153 @Override
154 protected @Nullable Packet findChildPacket() throws BadPacketException {
155 // TODO Add more protocols.
156 ByteBuffer payload = fPayload;
157 if (payload == null) {
158 return null;
159 }
160 switch (fType) {
161 case EthertypeHelper.ETHERTYPE_IPV4:
162 return new IPv4Packet(getPcapFile(), this, payload);
163 default:
164 return new UnknownPacket(getPcapFile(), this, payload);
165 }
166 }
167
168 @Override
169 public String toString() {
170 String string = getProtocol().getName() + ", Source: " + ConversionHelper.toMacAddress(fSourceMacAddress) + //$NON-NLS-1$
171 ", Destination: " + ConversionHelper.toMacAddress(fDestinationMacAddress) + ", Type: " + //$NON-NLS-1$ //$NON-NLS-2$
172 EthertypeHelper.toEtherType(fType) + "\n"; //$NON-NLS-1$
173 final Packet child = fChildPacket;
174 if (child != null) {
175 return string + child.toString();
176 }
177 return string;
178 }
179
180 @Override
181 public boolean validate() {
182 // Not yet implemented. ATM, we consider that all packets are valid.
183 // This is the case for all packets.
184 // TODO Implement it.
185 return true;
186 }
187
188 @Override
189 public EthernetIIEndpoint getSourceEndpoint() {
190 @Nullable EthernetIIEndpoint endpoint = fSourceEndpoint;
191 if (endpoint == null) {
192 endpoint = new EthernetIIEndpoint(this, true);
193 }
194 fSourceEndpoint = endpoint;
195 return fSourceEndpoint;
196 }
197
198 @Override
199 public EthernetIIEndpoint getDestinationEndpoint() {
200 @Nullable EthernetIIEndpoint endpoint = fDestinationEndpoint;
201
202 if (endpoint == null) {
203 endpoint = new EthernetIIEndpoint(this, false);
204 }
205 fDestinationEndpoint = endpoint;
206 return fDestinationEndpoint;
207 }
208
209 @Override
210 public Map<String, String> getFields() {
211 ImmutableMap<String, String> map = fFields;
212 if (map == null) {
213 @SuppressWarnings("null")
214 @NonNull ImmutableMap<String, String> newMap = ImmutableMap.<String, String> builder()
215 .put("Source MAC Address", ConversionHelper.toMacAddress(fSourceMacAddress)) //$NON-NLS-1$
216 .put("Destination MAC Address", ConversionHelper.toMacAddress(fDestinationMacAddress)) //$NON-NLS-1$
217 .put("Ethertype", String.valueOf(EthertypeHelper.toEtherType(fType))) //$NON-NLS-1$
218 .build();
219 fFields = newMap;
220 return newMap;
221 }
222 return map;
223 }
224
225 @Override
226 public String getLocalSummaryString() {
227 return "Src: " + ConversionHelper.toMacAddress(fSourceMacAddress) + " , Dst: " + ConversionHelper.toMacAddress(fDestinationMacAddress); //$NON-NLS-1$ //$NON-NLS-2$
228 }
229
230 @Override
231 protected String getSignificationString() {
232 return "Source MAC: " + ConversionHelper.toMacAddress(fSourceMacAddress) + " , Destination MAC: " + ConversionHelper.toMacAddress(fDestinationMacAddress); //$NON-NLS-1$ //$NON-NLS-2$
233 }
234
235 @Override
236 public int hashCode() {
237 final int prime = 31;
238 int result = 1;
239 final Packet child = fChildPacket;
240 if (child != null) {
241 result = prime * result + child.hashCode();
242 } else {
243 result = prime * result;
244 }
245 result = prime * result + Arrays.hashCode(fDestinationMacAddress);
246 final ByteBuffer payload = fPayload;
247 if (payload != null) {
248 result = prime * result + payload.hashCode();
249 } else {
250 result = prime * result;
251 }
252 result = prime * result + Arrays.hashCode(fSourceMacAddress);
253 result = prime * result + fType;
254 return result;
255 }
256
257 @Override
258 public boolean equals(@Nullable Object obj) {
259 if (this == obj) {
260 return true;
261 }
262 if (obj == null) {
263 return false;
264 }
265 if (getClass() != obj.getClass()) {
266 return false;
267 }
268 EthernetIIPacket other = (EthernetIIPacket) obj;
269 if (fChildPacket == null) {
270 if (other.fChildPacket != null) {
271 return false;
272 }
273 } else {
274 final Packet child = fChildPacket;
275 if (child != null) {
276 if (!child.equals(other.fChildPacket)) {
277 return false;
278 }
279 } else {
280 if (other.fChildPacket != null) {
281 return false;
282 }
283 }
284 }
285 if (!Arrays.equals(fDestinationMacAddress, other.fDestinationMacAddress)) {
286 return false;
287 }
288 if (fPayload == null) {
289 if (other.fPayload != null) {
290 return false;
291 }
292 } else {
293 final ByteBuffer payload = fPayload;
294 if (payload != null) {
295 if (!payload.equals(other.fPayload)) {
296 return false;
297 }
298 } else {
299 if (other.fPayload != null) {
300 return false;
301 }
302 }
303 }
304 if (!Arrays.equals(fSourceMacAddress, other.fSourceMacAddress)) {
305 return false;
306 }
307 if (fType != other.fType) {
308 return false;
309 }
310 return true;
311 }
312
313 }
This page took 0.042985 seconds and 5 git commands to generate.