/******************************************************************************* * Copyright (c) 2014 Ericsson * * All rights reserved. This program and the accompanying materials are * made available under the terms of the Eclipse Public License v1.0 which * accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Vincent Perot - Initial API and implementation *******************************************************************************/ package org.eclipse.tracecompass.pcap.core.tests.protocol.ipv4; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; import java.io.IOException; import java.net.InetAddress; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.tracecompass.internal.pcap.core.packet.BadPacketException; import org.eclipse.tracecompass.internal.pcap.core.protocol.PcapProtocol; import org.eclipse.tracecompass.internal.pcap.core.protocol.ipv4.IPv4Endpoint; import org.eclipse.tracecompass.internal.pcap.core.protocol.ipv4.IPv4Packet; import org.eclipse.tracecompass.internal.pcap.core.trace.BadPcapFileException; import org.eclipse.tracecompass.internal.pcap.core.trace.PcapFile; import org.eclipse.tracecompass.pcap.core.tests.shared.PcapTestTrace; import org.junit.Before; import org.junit.Test; /** * JUnit Class that tests the IPv4Packet class and its method. * * @author Vincent Perot */ public class IPv4PacketTest { private static final Map<String, String> EXPECTED_FIELDS; static { EXPECTED_FIELDS = new LinkedHashMap<>(); EXPECTED_FIELDS.put("Version", "4"); EXPECTED_FIELDS.put("Header Length", "24 bytes"); EXPECTED_FIELDS.put("Differentiated Services Field", "0x26"); EXPECTED_FIELDS.put("Explicit Congestion Notification", "0x02"); EXPECTED_FIELDS.put("Total Length", "255 bytes"); EXPECTED_FIELDS.put("Identification", "0x0ff0"); EXPECTED_FIELDS.put("Don't Fragment Flag", "false"); EXPECTED_FIELDS.put("More Fragment Flag", "false"); EXPECTED_FIELDS.put("Fragment Offset", "7905"); EXPECTED_FIELDS.put("Time to live", "160"); EXPECTED_FIELDS.put("Protocol", "Unknown (254)"); EXPECTED_FIELDS.put("Checksum", "0x3344"); EXPECTED_FIELDS.put("Source IP Address", "192.168.1.0"); EXPECTED_FIELDS.put("Destination IP Address", "193.169.2.1"); EXPECTED_FIELDS.put("Options", "a2 56 a2 56"); } private static final String EXPECTED_TOSTRING; static { StringBuilder sb = new StringBuilder(); sb.append("Internet Protocol Version 4, Source: 192.168.1.0, Destination: 193.169.2.1\n"); sb.append("Version: 4, Identification: 0x0ff0, Header Length: 24 bytes, Total Length: 255 bytes\n"); sb.append("Differentiated Services Code Point: 0x26; Explicit Congestion Notification: 0x02\n"); sb.append("Flags: 0x00 (Don't have more fragments), Fragment Offset: 7905\n"); sb.append("Time to live: 160\n"); sb.append("Protocol: 254\n"); sb.append("Header Checksum: 0x3344\n"); sb.append("Payload: a6"); EXPECTED_TOSTRING = sb.toString(); } private ByteBuffer fPacket; /** * Initialize the packet. */ @Before public void initialize() { fPacket = ByteBuffer.allocate(25); fPacket.order(ByteOrder.BIG_ENDIAN); // Version + IHL fPacket.put((byte) 0x46); // DSCP + ECN fPacket.put((byte) 0x9A); // Total length - this is randomly chosen so that we verify that the // packet handles wrong total length. fPacket.put((byte) 0x00); fPacket.put((byte) 0xFF); // Identification fPacket.put((byte) 0x0F); fPacket.put((byte) 0xF0); // Flags + Fragment Offset fPacket.put((byte) 0x1E); fPacket.put((byte) 0xE1); // Time to live fPacket.put((byte) 0xA0); // Protocol - Unknown fPacket.put((byte) 0xFE); // Header checksum - chosen randomly fPacket.put((byte) 0x33); fPacket.put((byte) 0x44); // Source IP - 4 bytes fPacket.put((byte) 192); fPacket.put((byte) 168); fPacket.put((byte) 1); fPacket.put((byte) 0); // Destination IP - 4 bytes fPacket.put((byte) 193); fPacket.put((byte) 169); fPacket.put((byte) 2); fPacket.put((byte) 1); // Options - 4 bytes fPacket.put((byte) 0xA2); fPacket.put((byte) 0x56); fPacket.put((byte) 0xA2); fPacket.put((byte) 0x56); // Payload - 1 byte fPacket.put((byte) 0xA6); fPacket.flip(); } /** * Test that verify the correctness of the IPv4Packet's methods. * * @throws BadPcapFileException * Thrown when the file is erroneous. Fails the test. * @throws IOException * Thrown when an IO error occurs. Fails the test. * @throws BadPacketException * Thrown when a packet is erroneous. Fails the test. */ @Test public void CompleteIPv4PacketTest() throws IOException, BadPcapFileException, BadPacketException { PcapTestTrace trace = PcapTestTrace.MOSTLY_TCP; assumeTrue(trace.exists()); try (PcapFile dummy = new PcapFile(trace.getPath())) { ByteBuffer byteBuffer = fPacket; if (byteBuffer == null) { fail("CompleteIPv4PacketTest has failed!"); return; } IPv4Packet packet = new IPv4Packet(dummy, null, byteBuffer); // Protocol Testing assertEquals(PcapProtocol.IPV4, packet.getProtocol()); assertTrue(packet.hasProtocol(PcapProtocol.IPV4)); assertTrue(packet.hasProtocol(PcapProtocol.UNKNOWN)); assertFalse(packet.hasProtocol(PcapProtocol.TCP)); // Abstract methods Testing assertTrue(packet.validate()); assertEquals(-222021887, packet.hashCode()); assertFalse(packet.equals(null)); assertEquals(new IPv4Packet(dummy, null, byteBuffer), packet); assertEquals(EXPECTED_FIELDS, packet.getFields()); assertEquals(EXPECTED_TOSTRING, packet.toString()); assertEquals("Src: 192.168.1.0 , Dst: 193.169.2.1", packet.getLocalSummaryString()); assertEquals("192.168.1.0 > 193.169.2.1 Id=4080 Len=1", packet.getGlobalSummaryString()); assertEquals(new IPv4Endpoint(packet, true), packet.getSourceEndpoint()); assertEquals(new IPv4Endpoint(packet, false), packet.getDestinationEndpoint()); fPacket.position(24); byte[] payload = new byte[1]; fPacket.get(payload); assertEquals(ByteBuffer.wrap(payload), packet.getPayload()); // Packet-specific methods Testing assertEquals(InetAddress.getByAddress(Arrays.copyOfRange(fPacket.array(), 12, 16)), packet.getSourceIpAddress()); assertEquals(InetAddress.getByAddress(Arrays.copyOfRange(fPacket.array(), 16, 20)), packet.getDestinationIpAddress()); assertTrue(Arrays.equals(packet.getOptions(), Arrays.copyOfRange(fPacket.array(), 20, 24))); assertEquals(4, packet.getVersion()); assertEquals(24, packet.getHeaderLength()); assertEquals(0x26, packet.getDSCP()); assertEquals(0x02, packet.getExplicitCongestionNotification()); assertEquals(255, packet.getTotalLength()); assertEquals(0x0FF0, packet.getIdentification()); assertFalse(packet.getReservedFlag()); assertFalse(packet.getDontFragmentFlag()); assertFalse(packet.getHasMoreFragment()); assertEquals(7905, packet.getFragmentOffset()); assertEquals(160, packet.getTimeToLive()); assertEquals(0xFE, packet.getIpDatagramProtocol()); assertEquals(0x3344, packet.getHeaderChecksum()); } } }