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