1 /*******************************************************************************
2 * Copyright (c) 2014 Ericsson
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
10 * Vincent Perot - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.tracecompass
.internal
.pcap
.core
.protocol
.ethernet2
;
15 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
17 import java
.nio
.ByteBuffer
;
18 import java
.nio
.ByteOrder
;
19 import java
.util
.Arrays
;
22 import org
.eclipse
.jdt
.annotation
.Nullable
;
23 import org
.eclipse
.tracecompass
.internal
.pcap
.core
.packet
.BadPacketException
;
24 import org
.eclipse
.tracecompass
.internal
.pcap
.core
.packet
.Packet
;
25 import org
.eclipse
.tracecompass
.internal
.pcap
.core
.protocol
.PcapProtocol
;
26 import org
.eclipse
.tracecompass
.internal
.pcap
.core
.protocol
.ipv4
.IPv4Packet
;
27 import org
.eclipse
.tracecompass
.internal
.pcap
.core
.protocol
.unknown
.UnknownPacket
;
28 import org
.eclipse
.tracecompass
.internal
.pcap
.core
.trace
.PcapFile
;
29 import org
.eclipse
.tracecompass
.internal
.pcap
.core
.util
.ConversionHelper
;
30 import org
.eclipse
.tracecompass
.internal
.pcap
.core
.util
.EthertypeHelper
;
32 import com
.google
.common
.collect
.ImmutableMap
;
35 * Class that represents an Ethernet II packet. This should be called an
36 * Ethernet frame, but in order to keep the nomenclature consistent, this is
39 * @author Vincent Perot
41 public class EthernetIIPacket
extends Packet
{
43 private final @Nullable Packet fChildPacket
;
44 private final @Nullable ByteBuffer fPayload
;
46 /* We store MAC addresses as byte arrays since
47 * there is no standard java class to store them. */
48 private final byte[] fSourceMacAddress
;
49 private final byte[] fDestinationMacAddress
;
51 private final int fType
;
53 private @Nullable EthernetIIEndpoint fSourceEndpoint
;
54 private @Nullable EthernetIIEndpoint fDestinationEndpoint
;
56 private @Nullable Map
<String
, String
> fFields
;
59 * Constructor of the Ethernet Packet class.
62 * The file that contains this packet.
64 * The parent packet of this packet (the encapsulating packet).
66 * The entire packet (header and payload).
67 * @throws BadPacketException
68 * Thrown when the packet is erroneous.
70 public EthernetIIPacket(PcapFile file
, @Nullable Packet parent
, ByteBuffer packet
) throws BadPacketException
{
71 super(file
, parent
, PcapProtocol
.ETHERNET_II
);
73 if (packet
.array().length
<= EthernetIIValues
.ETHERNET_II_MIN_SIZE
) {
74 throw new BadPacketException("An Ethernet II packet can't be smaller than 14 bytes."); //$NON-NLS-1$
77 // The endpoints are lazy loaded. They are defined in the get*Endpoint()
79 fSourceEndpoint
= null;
80 fDestinationEndpoint
= null;
84 fDestinationMacAddress
= new byte[EthernetIIValues
.MAC_ADDRESS_SIZE
];
85 fSourceMacAddress
= new byte[EthernetIIValues
.MAC_ADDRESS_SIZE
];
86 packet
.order(ByteOrder
.BIG_ENDIAN
);
88 packet
.get(fDestinationMacAddress
);
89 packet
.get(fSourceMacAddress
);
90 fType
= ConversionHelper
.unsignedShortToInt(packet
.getShort());
92 // Get payload if it exists.
93 if (packet
.array().length
- packet
.position() > 0) {
94 byte[] array
= new byte[packet
.array().length
- packet
.position()];
96 ByteBuffer payload
= ByteBuffer
.wrap(array
);
97 if (payload
!= null) {
98 payload
.order(ByteOrder
.BIG_ENDIAN
);
108 fChildPacket
= findChildPacket();
113 public @Nullable Packet
getChildPacket() {
118 public @Nullable ByteBuffer
getPayload() {
123 * Getter method for the source MAC Address.
125 * @return The source MAC address.
127 public byte[] getSourceMacAddress() {
128 return checkNotNull(Arrays
.copyOf(fSourceMacAddress
, fSourceMacAddress
.length
));
132 * Getter method for the destination MAC Address.
134 * @return The destination MAC address.
136 public byte[] getDestinationMacAddress() {
137 return checkNotNull(Arrays
.copyOf(fDestinationMacAddress
, fDestinationMacAddress
.length
));
141 * Getter method for Ethertype. See
142 * http://standards.ieee.org/develop/regauth/ethertype/eth.txt
144 * @return The Ethertype. This is used to determine the child packet..
146 public int getEthertype() {
151 protected @Nullable Packet
findChildPacket() throws BadPacketException
{
152 // TODO Add more protocols.
153 ByteBuffer payload
= fPayload
;
154 if (payload
== null) {
158 case EthertypeHelper
.ETHERTYPE_IPV4
:
159 return new IPv4Packet(getPcapFile(), this, payload
);
161 return new UnknownPacket(getPcapFile(), this, payload
);
166 public String
toString() {
167 String string
= getProtocol().getName() + ", Source: " + ConversionHelper
.toMacAddress(fSourceMacAddress
) + //$NON-NLS-1$
168 ", Destination: " + ConversionHelper
.toMacAddress(fDestinationMacAddress
) + ", Type: " + //$NON-NLS-1$ //$NON-NLS-2$
169 EthertypeHelper
.toEtherType(fType
) + "\n"; //$NON-NLS-1$
170 final Packet child
= fChildPacket
;
172 return string
+ child
.toString();
178 public boolean validate() {
179 // Not yet implemented. ATM, we consider that all packets are valid.
180 // This is the case for all packets.
181 // TODO Implement it.
186 public EthernetIIEndpoint
getSourceEndpoint() {
187 @Nullable EthernetIIEndpoint endpoint
= fSourceEndpoint
;
188 if (endpoint
== null) {
189 endpoint
= new EthernetIIEndpoint(this, true);
191 fSourceEndpoint
= endpoint
;
192 return fSourceEndpoint
;
196 public EthernetIIEndpoint
getDestinationEndpoint() {
197 @Nullable EthernetIIEndpoint endpoint
= fDestinationEndpoint
;
199 if (endpoint
== null) {
200 endpoint
= new EthernetIIEndpoint(this, false);
202 fDestinationEndpoint
= endpoint
;
203 return fDestinationEndpoint
;
207 public Map
<String
, String
> getFields() {
208 Map
<String
, String
> map
= fFields
;
210 ImmutableMap
.Builder
<String
, String
> builder
= ImmutableMap
.<String
, String
> builder();
211 builder
.put("Source MAC Address", ConversionHelper
.toMacAddress(fSourceMacAddress
)); //$NON-NLS-1$
212 builder
.put("Destination MAC Address", ConversionHelper
.toMacAddress(fDestinationMacAddress
)); //$NON-NLS-1$
213 builder
.put("Ethertype", String
.valueOf(EthertypeHelper
.toEtherType(fType
))); //$NON-NLS-1$
215 fFields
= checkNotNull(builder
.build());
222 public String
getLocalSummaryString() {
223 return "Src: " + ConversionHelper
.toMacAddress(fSourceMacAddress
) + " , Dst: " + ConversionHelper
.toMacAddress(fDestinationMacAddress
); //$NON-NLS-1$ //$NON-NLS-2$
227 protected String
getSignificationString() {
228 return "Source MAC: " + ConversionHelper
.toMacAddress(fSourceMacAddress
) + " , Destination MAC: " + ConversionHelper
.toMacAddress(fDestinationMacAddress
); //$NON-NLS-1$ //$NON-NLS-2$
232 public int hashCode() {
233 final int prime
= 31;
235 final Packet child
= fChildPacket
;
237 result
= prime
* result
+ child
.hashCode();
239 result
= prime
* result
;
241 result
= prime
* result
+ Arrays
.hashCode(fDestinationMacAddress
);
242 final ByteBuffer payload
= fPayload
;
243 if (payload
!= null) {
244 result
= prime
* result
+ payload
.hashCode();
246 result
= prime
* result
;
248 result
= prime
* result
+ Arrays
.hashCode(fSourceMacAddress
);
249 result
= prime
* result
+ fType
;
254 public boolean equals(@Nullable Object obj
) {
261 if (getClass() != obj
.getClass()) {
264 EthernetIIPacket other
= (EthernetIIPacket
) obj
;
265 if (fChildPacket
== null) {
266 if (other
.fChildPacket
!= null) {
270 final Packet child
= fChildPacket
;
272 if (!child
.equals(other
.fChildPacket
)) {
276 if (other
.fChildPacket
!= null) {
281 if (!Arrays
.equals(fDestinationMacAddress
, other
.fDestinationMacAddress
)) {
284 if (fPayload
== null) {
285 if (other
.fPayload
!= null) {
289 final ByteBuffer payload
= fPayload
;
290 if (payload
!= null) {
291 if (!payload
.equals(other
.fPayload
)) {
295 if (other
.fPayload
!= null) {
300 if (!Arrays
.equals(fSourceMacAddress
, other
.fSourceMacAddress
)) {
303 if (fType
!= other
.fType
) {