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