diff --git a/tools/pcapdump/.classpath b/tools/pcapdump/.classpath
new file mode 100644
index 0000000000000000000000000000000000000000..205625cc4c22bb1a948a5a60fabc50af99ef925d
--- /dev/null
+++ b/tools/pcapdump/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/tools/pcapdump/.project b/tools/pcapdump/.project
new file mode 100644
index 0000000000000000000000000000000000000000..cee79a6d9c0dcfbb44141706cd2913f009a472e7
--- /dev/null
+++ b/tools/pcapdump/.project
@@ -0,0 +1,17 @@
+
+
+ pcapdump
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/tools/pcapdump/.settings/org.eclipse.jdt.core.prefs b/tools/pcapdump/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..bb35fa0a87b032ee9d0b128004c1edbd464f07bf
--- /dev/null
+++ b/tools/pcapdump/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/tools/pcapdump/PcapDump.bat b/tools/pcapdump/PcapDump.bat
new file mode 100644
index 0000000000000000000000000000000000000000..1fd507d799a3473d026cf0952a6b6a43b6595a0e
--- /dev/null
+++ b/tools/pcapdump/PcapDump.bat
@@ -0,0 +1,19 @@
+@echo "Starting PcapDump..."
+@title PcapDump
+
+@set JAVA_PATH=C:\Program Files\Java\jre1.8.0_101\bin
+@rem set BASE_PATH=C:\Users\garciay\Documents\ETSI\ITS
+
+@rem Home laptop
+@rem set JAVA_PATH=C:\Program Files\Java\jre1.8.0_101\bin
+@rem set JAVA_PATH=C:\Program Files (x86)\Java\jre8\bin
+@set BASE_PATH=F:\FSCOM\ETSI\ITS
+
+@set LOG_PATH=%BASE_PATH%\STF517_ITS_Valid_Conform_Frmwk.2016\workspace_eclipse\pcapdump\lib
+@set CODEC_PATH=%LOG_PATH%\PcapDump.jar
+@set JNETPCAP_PATH=%BASE_PATH%\STF517_ITS_Valid_Conform_Frmwk.2016\workspace_ttwb\STF517\tt3plugins\EtsiItsAdapter\jnetpcap-1.4.r1425\jnetpcap.jar
+
+@"%JAVA_PATH%\java.exe" -cp "%CODEC_PATH%;%JNETPCAP_PATH%" org.etsi.its.pcapdump.pcapdump
+@rem --FileName yann.pcap --NicAddr 00FF6BADBFC2 --FrameType=8947
+@rem pause
+
diff --git a/tools/pcapdump/PcapDump.jardesc b/tools/pcapdump/PcapDump.jardesc
new file mode 100644
index 0000000000000000000000000000000000000000..dcec9a4d075c2853c57aad6cccf41837e3b531c7
--- /dev/null
+++ b/tools/pcapdump/PcapDump.jardesc
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tools/pcapdump/bin/org/etsi/common/ByteHelper.class b/tools/pcapdump/bin/org/etsi/common/ByteHelper.class
new file mode 100644
index 0000000000000000000000000000000000000000..fef8374559dfe286e98db182ae2f3117f222e892
Binary files /dev/null and b/tools/pcapdump/bin/org/etsi/common/ByteHelper.class differ
diff --git a/tools/pcapdump/bin/org/etsi/common/ITuple.class b/tools/pcapdump/bin/org/etsi/common/ITuple.class
new file mode 100644
index 0000000000000000000000000000000000000000..0ad0044427480d216ab7a29379c49c28692c07e2
Binary files /dev/null and b/tools/pcapdump/bin/org/etsi/common/ITuple.class differ
diff --git a/tools/pcapdump/bin/org/etsi/common/KPM.class b/tools/pcapdump/bin/org/etsi/common/KPM.class
new file mode 100644
index 0000000000000000000000000000000000000000..f8a5f2fe8af3c9e3b8e7ab6982bea5fd1fd3f69b
Binary files /dev/null and b/tools/pcapdump/bin/org/etsi/common/KPM.class differ
diff --git a/tools/pcapdump/bin/org/etsi/common/Tuple.class b/tools/pcapdump/bin/org/etsi/common/Tuple.class
new file mode 100644
index 0000000000000000000000000000000000000000..9a69048106381cab04fa969e3451b7c2dc6df91e
Binary files /dev/null and b/tools/pcapdump/bin/org/etsi/common/Tuple.class differ
diff --git a/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$IllegalOptionValueException.class b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$IllegalOptionValueException.class
new file mode 100644
index 0000000000000000000000000000000000000000..4fd582c600d42de7fe809746a62070492ef8c82b
Binary files /dev/null and b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$IllegalOptionValueException.class differ
diff --git a/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$NotFlagException.class b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$NotFlagException.class
new file mode 100644
index 0000000000000000000000000000000000000000..01199f0bf0d1c2a9c64246711cdb9ba3034f83b3
Binary files /dev/null and b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$NotFlagException.class differ
diff --git a/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$Option$BooleanOption.class b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$Option$BooleanOption.class
new file mode 100644
index 0000000000000000000000000000000000000000..45250e5c4cf65ca7691d2415bd65e9956d30e7c7
Binary files /dev/null and b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$Option$BooleanOption.class differ
diff --git a/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$Option$DoubleOption.class b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$Option$DoubleOption.class
new file mode 100644
index 0000000000000000000000000000000000000000..547ad8ffc02d91d806857b7f42c5b57de14c7c72
Binary files /dev/null and b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$Option$DoubleOption.class differ
diff --git a/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$Option$IntegerOption.class b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$Option$IntegerOption.class
new file mode 100644
index 0000000000000000000000000000000000000000..62f6dc1d307306d8609a2096ff402ba970eed515
Binary files /dev/null and b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$Option$IntegerOption.class differ
diff --git a/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$Option$LongOption.class b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$Option$LongOption.class
new file mode 100644
index 0000000000000000000000000000000000000000..4e108eeec310b1925111d37ca8dba7e0ff743352
Binary files /dev/null and b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$Option$LongOption.class differ
diff --git a/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$Option$StringOption.class b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$Option$StringOption.class
new file mode 100644
index 0000000000000000000000000000000000000000..6c91be837cf951d7773b038207c4c237de380dd9
Binary files /dev/null and b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$Option$StringOption.class differ
diff --git a/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$Option.class b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$Option.class
new file mode 100644
index 0000000000000000000000000000000000000000..2442b1a0dc88166f99f4255cbacb6e30046cdacd
Binary files /dev/null and b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$Option.class differ
diff --git a/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$OptionException.class b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$OptionException.class
new file mode 100644
index 0000000000000000000000000000000000000000..b54e43a72f08753b8f1f60b1c29e7220dab80d9b
Binary files /dev/null and b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$OptionException.class differ
diff --git a/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$UnknownOptionException.class b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$UnknownOptionException.class
new file mode 100644
index 0000000000000000000000000000000000000000..921ebf8776f3f9b694f74588290e815a57a7d5bb
Binary files /dev/null and b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$UnknownOptionException.class differ
diff --git a/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$UnknownSuboptionException.class b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$UnknownSuboptionException.class
new file mode 100644
index 0000000000000000000000000000000000000000..e87f730097a852b8baa15e0456ee321ca59e11bd
Binary files /dev/null and b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser$UnknownSuboptionException.class differ
diff --git a/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser.class b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser.class
new file mode 100644
index 0000000000000000000000000000000000000000..f35caca8f7230bb8d6a5df9d9363cb9bd59151a7
Binary files /dev/null and b/tools/pcapdump/bin/org/etsi/its/pcapdump/CmdLineParser.class differ
diff --git a/tools/pcapdump/bin/org/etsi/its/pcapdump/ILayer.class b/tools/pcapdump/bin/org/etsi/its/pcapdump/ILayer.class
new file mode 100644
index 0000000000000000000000000000000000000000..80a9aa1245a8b9ad6be0f301b3c2efb715402b30
Binary files /dev/null and b/tools/pcapdump/bin/org/etsi/its/pcapdump/ILayer.class differ
diff --git a/tools/pcapdump/bin/org/etsi/its/pcapdump/PcapMultiplexer$1.class b/tools/pcapdump/bin/org/etsi/its/pcapdump/PcapMultiplexer$1.class
new file mode 100644
index 0000000000000000000000000000000000000000..88f40a53fe1642745fb7c8fce1acb82f9ed98d5e
Binary files /dev/null and b/tools/pcapdump/bin/org/etsi/its/pcapdump/PcapMultiplexer$1.class differ
diff --git a/tools/pcapdump/bin/org/etsi/its/pcapdump/PcapMultiplexer.class b/tools/pcapdump/bin/org/etsi/its/pcapdump/PcapMultiplexer.class
new file mode 100644
index 0000000000000000000000000000000000000000..12e506ff1aa94768e503f932f2e521106cc651db
Binary files /dev/null and b/tools/pcapdump/bin/org/etsi/its/pcapdump/PcapMultiplexer.class differ
diff --git a/tools/pcapdump/bin/org/etsi/its/pcapdump/pcapdump.class b/tools/pcapdump/bin/org/etsi/its/pcapdump/pcapdump.class
new file mode 100644
index 0000000000000000000000000000000000000000..ad4271bcbf88ca4416f511a201729e11b8dd4d99
Binary files /dev/null and b/tools/pcapdump/bin/org/etsi/its/pcapdump/pcapdump.class differ
diff --git a/tools/pcapdump/itsdump.pcapng b/tools/pcapdump/itsdump.pcapng
new file mode 100644
index 0000000000000000000000000000000000000000..07d7efd2ab1a93b3c655401a672df18bb9330a19
Binary files /dev/null and b/tools/pcapdump/itsdump.pcapng differ
diff --git a/tools/pcapdump/itsdump.pcapng_1475823029887 b/tools/pcapdump/itsdump.pcapng_1475823029887
new file mode 100644
index 0000000000000000000000000000000000000000..82d353e51e55027d3ff1eff9dc4de369b7396786
Binary files /dev/null and b/tools/pcapdump/itsdump.pcapng_1475823029887 differ
diff --git a/tools/pcapdump/lib/PcapDump.jar b/tools/pcapdump/lib/PcapDump.jar
new file mode 100644
index 0000000000000000000000000000000000000000..f67ac0813a5ea190f94ccfc6e43c9592f4819365
Binary files /dev/null and b/tools/pcapdump/lib/PcapDump.jar differ
diff --git a/tools/pcapdump/src/org/etsi/common/ByteHelper.java b/tools/pcapdump/src/org/etsi/common/ByteHelper.java
new file mode 100644
index 0000000000000000000000000000000000000000..b595b4c1c26e5265bc55f7bd14d304378f23dd2d
--- /dev/null
+++ b/tools/pcapdump/src/org/etsi/common/ByteHelper.java
@@ -0,0 +1,284 @@
+package org.etsi.common;
+
+import java.nio.ByteOrder;
+
+public class ByteHelper {
+
+ public static byte[] changeEndianness(byte [] in) {
+ byte[] out = new byte[in.length];
+ for(int i=0; i < in.length; i++) {
+ out[in.length - i -1] = in[i];
+ }
+ return out;
+ }
+
+ public static byte[] intToByteArray(int value, int length, ByteOrder byteOrder) {
+ if(byteOrder == ByteOrder.LITTLE_ENDIAN) {
+ return changeEndianness(intToByteArray(value, length));
+ }
+ return intToByteArray(value, length);
+ }
+
+ public static byte[] intToByteArray(int value, int length) {
+ byte[] b = new byte[length];
+ for (int i = length - 1; i >= 0; i--) {
+ int offset = (b.length - 1 - i) * 8;
+ b[i] = (byte) ((value >>> offset) & 0xFF);
+ }
+ return b;
+ }
+
+ public static byte[] longToByteArray(long value, int length, ByteOrder byteOrder) {
+ if(byteOrder == ByteOrder.LITTLE_ENDIAN) {
+ return changeEndianness(longToByteArray(value, length));
+ }
+ return longToByteArray(value, length);
+ }
+
+ public static byte[] longToByteArray(long value, int length) {
+ byte[] b = new byte[length];
+ for (int i = length - 1; i >= 0; i--) {
+ int offset = (b.length - 1 - i) * 8;
+ b[i] = (byte) ((value >>> offset) & 0xFF);
+ }
+ return b;
+ }
+
+ /** Convert a byte array into a boolean
+ *
+ * @param b The byte array to convert
+ * @return The boolean value on success, false otherwise
+ */
+ public static Boolean byteArrayToBoolean(byte[] b) {
+ // Sanity check
+ if ((b == null) || (b.length != 1)) {
+ return null;
+ }
+
+ return new Boolean(b[0] == 0x01);
+ } // End of method byteArrayToBoolean
+
+ public static Short byteArrayToShort(final byte[] b, ByteOrder byteOrder) {
+ if(byteOrder == ByteOrder.LITTLE_ENDIAN) {
+ return byteArrayToShort(changeEndianness(b));
+ }
+ return byteArrayToShort(b);
+ }
+
+ /** Convert a byte array into a short value assuming that the first byte is the most significant
+ *
+ * @param b The byte array to convert
+ * @return The short value on success, 'Integer.MAX_VALUE' otherwise
+ */
+ public static Short byteArrayToShort(final byte[] b) {
+ // Sanity check
+ if ((b == null) || ((b.length * Byte.SIZE) > Short.SIZE)) {
+ return Short.MAX_VALUE;
+ }
+
+ short value = 0;
+ for (Short i = 0; i < b.length; i++) {
+ value = (short)((value << 8) + (b[i] & 0xff));
+ }
+
+ return new Short(value);
+ } // End of method byteArrayToInt
+
+ public static Integer byteArrayToInt(final byte[] b, ByteOrder byteOrder) {
+ if(byteOrder == ByteOrder.LITTLE_ENDIAN) {
+ return byteArrayToInt(changeEndianness(b));
+ }
+ return byteArrayToInt(b);
+ }
+
+ /** Convert a byte array into an integer assuming that the first byte is the most significant
+ *
+ * @param b The byte array to convert
+ * @return The integer value on success, 'Integer.MAX_VALUE' otherwise
+ */
+ public static Integer byteArrayToInt(final byte[] b) {
+ // Sanity check
+ if ((b == null) || ((b.length * Byte.SIZE) > Integer.SIZE)) {
+ return Integer.MAX_VALUE;
+ }
+
+ int value = 0;
+ for (int i = 0; i < b.length; i++) {
+ value = (value << 8) + (b[i] & 0xff);
+ }
+
+ return new Integer(value);
+ } // End of method byteArrayToInt
+
+ public static Long byteArrayToLong(final byte[] b, ByteOrder byteOrder) {
+ if(byteOrder == ByteOrder.LITTLE_ENDIAN) {
+ return byteArrayToLong(changeEndianness(b));
+ }
+ return byteArrayToLong(b);
+ }
+
+ /** Convert a byte array into a Long assuming that the first byte is the most significant
+ *
+ * @param b The byte array to convert
+ * @return The Long value on success, 'Long.MAX_VALUE' otherwise
+ */
+ public static Long byteArrayToLong(final byte[] b) {
+ // Sanity check
+ if ((b == null) || ((b.length * Byte.SIZE) > Long.SIZE)) {
+ return Long.MAX_VALUE;
+ }
+
+ long value = 0;
+ for (int i = 0; i < b.length; i++) {
+ value = (value << 8) + (b[i] & 0xff);
+ }
+
+ return new Long(value);
+ } // End of method byteArrayToLong
+
+ public static byte[] hexStringToByteArray(final String s) {
+ String str = "";
+ for(String ss : s.split("[^0-9A-Fa-f]")) {
+ str = str + ss;
+ }
+ int len = str.length();
+ byte[] data = new byte[len / 2];
+ for (int i = 0; i < len; i += 2) {
+ data[i / 2] = (byte) ((Character.digit(str.charAt(i), 16) << 4)
+ + Character.digit(str.charAt(i+1), 16));
+ }
+ return data;
+ }
+
+ public static byte[] concat(byte[]... arrays) {
+ int length = 0;
+ for (byte[] array : arrays) {
+ if(array != null) {
+ length += array.length;
+ }
+ }
+ byte[] result = new byte[length];
+ int position = 0;
+ for (byte[] array : arrays) {
+ if(array != null) {
+ System.arraycopy(array, 0, result, position, array.length);
+ position += array.length;
+ }
+ }
+ return result;
+ }
+
+
+ /** Extract a sub part of a byte array
+ * @param array The original array
+ * @param offset The offset to start the extract operation
+ * @param length The number of bytes to extract
+ * @return The sub part of a provided byte array
+ */
+ public static byte[] extract(final byte[] array, final int offset, final int length) {
+ // Sanity check
+ if ((array == null) || (array.length == 0) || (offset > array.length)) {
+ return null;
+ }
+
+ byte[] result = new byte[length];
+ System.arraycopy(array, offset, result, 0, length);
+ return result;
+ }
+
+ /**
+ * This method convert a byte array containing the couple (length + string) into a string
+ * @param b The byte array to convert
+ * @return A string value
+ */
+ public static String byteArrayWithLengthToString(final byte[] b) {
+ // Sanity check
+ if (b == null) {
+ return null;
+ } else if (b.length == 0) {
+ return "";
+ }
+
+ // Extract the length of the string
+ int length = byteArrayToInt(extract(b, 0, 4));
+ // Extract the the string
+ String result = "";
+ for (int i = 0; i < length; i++) {
+ result += (char)(b[4 + i]);
+ } // End of 'for' statement
+
+ return result;
+ }
+
+ public static String byteArrayToString(final byte[] buffer) {
+
+ String result = "";
+ if (buffer != null) {
+ for(int i=0; i < buffer.length; ++i) {
+ result += String.format("%02X", (byte)buffer[i]);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Dump a byte array in hex/ascii mode.
+ * @param label The dump label
+ * @param buffer The byte array to dump
+ */
+ public synchronized static void dump(final String label, final byte[] buffer)
+ {
+ if ((buffer != null) && (buffer.length != 0))
+ {
+ System.out.println(label);
+ StringBuilder finalHexLine = new StringBuilder();
+ StringBuilder finalCharLine = new StringBuilder();
+ int nCounter = 0;
+ int nOffset = 0;
+ // Flush header.
+ System.out.println(" HEX | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F : 0 1 2 3 4 5 6 7 8 9 A B C D E F ");
+ System.out.println("-----|+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+-:--+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+");
+ for (int i = 0; i < buffer.length; ++i)
+ {
+ byte c = (byte)buffer[i];
+
+ String fmtHex = String.format("%02x ", c);
+ String fmtChar = String.format("%c ", Character.isISOControl((char)c) || c < 0 ? '.' : (char)c);
+
+ if (nOffset % 16 == 0)
+ {
+ finalHexLine.append(String.format("%05x| ", nOffset));
+ }
+
+ finalHexLine.append(fmtHex);
+ finalCharLine.append(fmtChar);
+ if (nCounter == 15)
+ {
+ // Flush line.
+ System.out.println(String.format("%s : %s", finalHexLine.toString(), finalCharLine.toString()));
+ // Reset buffer.
+ finalHexLine.delete(0, finalHexLine.length());
+ finalCharLine.delete(0, finalCharLine.length());
+
+ nCounter = 0;
+ }
+ else
+ {
+ nCounter++;
+ }
+ nOffset++;
+ }
+ if (nCounter < 16)
+ {
+ // Pad till 15.
+ for (int i = nCounter; i < 16; i++)
+ {
+ finalHexLine.append(" ");
+ finalCharLine.append(" ");
+ }
+ // Flush line.
+ System.out.println(String.format("%s : %s", finalHexLine.toString(), finalCharLine.toString()));
+ }
+ }
+ }
+}
diff --git a/tools/pcapdump/src/org/etsi/common/ITuple.java b/tools/pcapdump/src/org/etsi/common/ITuple.java
new file mode 100644
index 0000000000000000000000000000000000000000..cb44900511a4ad90be6ca006bfda0b4339f23d31
--- /dev/null
+++ b/tools/pcapdump/src/org/etsi/common/ITuple.java
@@ -0,0 +1,25 @@
+/**
+ * @author STF 424_ITS_Test_Platform
+ * @version $URL$
+ * $Id$
+ */
+package org.etsi.common;
+
+/**
+ * This interface provides mandatory method to be implemented by a Tuple {A, B}
+ * @param Type of the first member of the Tuple
+ * @param Type of the second member of the Tuple
+ */
+public interface ITuple {
+
+ /** Retrieve the A element of the tuple
+ * @return the _a
+ */
+ public abstract A getA();
+
+ /** Retrieve the B element of the tuple
+ * @return the _b
+ */
+ public abstract B getB();
+
+}
\ No newline at end of file
diff --git a/tools/pcapdump/src/org/etsi/common/KPM.java b/tools/pcapdump/src/org/etsi/common/KPM.java
new file mode 100644
index 0000000000000000000000000000000000000000..abf88b67a58927cfca78d886ac0049a7301564eb
--- /dev/null
+++ b/tools/pcapdump/src/org/etsi/common/KPM.java
@@ -0,0 +1,61 @@
+/**
+ * Knuth-Morris-Pratt Algorithm implementation
+ * @author ETSI / STF481
+ * @version $URL$
+ * $Id$
+ * Credit http://www.fmi.uni-sofia.bg/
+ */
+package org.etsi.common;
+
+public class KPM {
+
+ /**
+ * Search the data byte array for the first occurrence of the byte array pattern within given boundaries.
+ * @param data
+ * @param start First index in data
+ * @param stop Last index in data so that stop-start = length
+ * @param pattern What is being searched. '*' can be used as wildcard for "ANY character"
+ * @return
+ */
+ public static int indexOf( byte[] data, int start, int stop, byte[] pattern) {
+ if( data == null || pattern == null) return -1;
+
+ int[] failure = computeFailure(pattern);
+
+ int j = 0;
+
+ for( int i = start; i < stop; i++) {
+ while (j > 0 && ( pattern[j] != '*' && pattern[j] != data[i])) {
+ j = failure[j - 1];
+ }
+ if (pattern[j] == '*' || pattern[j] == data[i]) {
+ j++;
+ }
+ if (j == pattern.length) {
+ return i - pattern.length + 1;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Computes the failure function using a boot-strapping process,
+ * where the pattern is matched against itself.
+ */
+ private static int[] computeFailure(byte[] pattern) {
+ int[] failure = new int[pattern.length];
+
+ int j = 0;
+ for (int i = 1; i < pattern.length; i++) {
+ while (j>0 && pattern[j] != pattern[i]) {
+ j = failure[j - 1];
+ }
+ if (pattern[j] == pattern[i]) {
+ j++;
+ }
+ failure[i] = j;
+ }
+
+ return failure;
+ }
+} // End of class KPM
\ No newline at end of file
diff --git a/tools/pcapdump/src/org/etsi/common/Tuple.java b/tools/pcapdump/src/org/etsi/common/Tuple.java
new file mode 100644
index 0000000000000000000000000000000000000000..424a603aa76e222e958f3d5c00a7439d60674b1f
--- /dev/null
+++ b/tools/pcapdump/src/org/etsi/common/Tuple.java
@@ -0,0 +1,52 @@
+/**
+ * @author STF 424_ITS_Test_Platform
+ * @version $URL$
+ * $Id$
+ */
+package org.etsi.common;
+
+/**
+ * This class implements the ITuple interface
+ * @param Type of the first member of the Tuple
+ * @param Type of the second member of the Tuple
+ */
+public class Tuple implements ITuple {
+
+ /**
+ * A element of the tuple
+ */
+ private A _a;
+
+ /**
+ * B element of the tuple
+ */
+ private B _b;
+
+ /**
+ * Constructor
+ * @param a The A element of the new tuple
+ * @param b The B element of the new tuple
+ */
+ public Tuple(A a, B b) {
+ _a = a;
+ _b = b;
+ }
+
+ /**
+ * Retrieve the A element of the tuple
+ * @return the _a
+ */
+ @Override
+ public A getA() {
+ return _a;
+ }
+
+ /**
+ * Retrieve the B element of the tuple
+ * @return the _b
+ */
+ @Override
+ public B getB() {
+ return _b;
+ }
+}
diff --git a/tools/pcapdump/src/org/etsi/its/pcapdump/CmdLineParser.java b/tools/pcapdump/src/org/etsi/its/pcapdump/CmdLineParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..195d5a59f412dc2af5eb13bee314fc947245001b
--- /dev/null
+++ b/tools/pcapdump/src/org/etsi/its/pcapdump/CmdLineParser.java
@@ -0,0 +1,568 @@
+package org.etsi.its.pcapdump;
+
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+
+/**
+ * Largely GNU-compatible command-line options parser. Has short (-v) and
+ * long-form (--verbose) option support, and also allows options with
+ * associated values (-d 2, --debug 2, --debug=2). Option processing
+ * can be explicitly terminated by the argument '--'.
+ *
+ * @author Steve Purcell
+ * @version $Revision$
+ */
+public class CmdLineParser {
+
+ /**
+ * UID
+ */
+ private static final long serialVersionUID = -5690842973330286842L;
+
+ /**
+ * Base class for exceptions that may be thrown when options are parsed
+ */
+ public static abstract class OptionException extends Exception {
+ OptionException(String msg) { super(msg); }
+ }
+
+ /**
+ * Thrown when the parsed command-line contains an option that is not
+ * recognised. getMessage()
returns
+ * an error string suitable for reporting the error to the user (in
+ * English).
+ */
+ public static class UnknownOptionException extends OptionException {
+ /**
+ * UID
+ */
+ private static final long serialVersionUID = -5690842973330286842L;
+
+ /**
+ * Constructor
+ * @param optionName Option identifier
+ */
+ UnknownOptionException( String optionName ) {
+ this(optionName, "Unknown option '" + optionName + "'");
+ }
+
+ /**
+ * Constructor
+ * @param optionName Option identifier
+ * @param msg Error message
+ */
+ UnknownOptionException( String optionName, String msg ) {
+ super(msg);
+ this.optionName = optionName;
+ }
+
+ /**
+ * @return the name of the option that was unknown (e.g. "-u")
+ */
+ public String getOptionName() { return this.optionName; }
+ private String optionName = null;
+ }
+
+ /**
+ * Thrown when the parsed commandline contains multiple concatenated
+ * short options, such as -abcd, where one is unknown.
+ * getMessage()
returns an english human-readable error
+ * string.
+ * @author Vidar Holen
+ */
+ public static class UnknownSuboptionException extends UnknownOptionException {
+
+ /**
+ * UID
+ */
+ private static final long serialVersionUID = -3886188976129160327L;
+
+ private char suboption;
+
+ /**
+ * Constructor
+ * @param option Option value
+ * @param suboption Sub-option value
+ */
+ UnknownSuboptionException( String option, char suboption ) {
+ super(option, "Illegal option: '"+suboption+"' in '"+option+"'");
+ this.suboption=suboption;
+ }
+ /**
+ * @return The sub-option value
+ */
+ public char getSuboption() { return suboption; }
+ }
+
+ /**
+ * Thrown when the parsed commandline contains multiple concatenated
+ * short options, such as -abcd, where one or more requires a value.
+ * getMessage()
returns an english human-readable error
+ * string.
+ * @author Vidar Holen
+ */
+ public static class NotFlagException extends UnknownOptionException {
+ /**
+ * UID
+ */
+ private static final long serialVersionUID = -5862485101945261269L;
+
+ private char notflag;
+
+ NotFlagException( String option, char unflaggish ) {
+ super(option, "Illegal option: '"+option+"', '"+
+ unflaggish+"' requires a value");
+ notflag=unflaggish;
+ }
+
+ /**
+ * @return the first character which wasn't a boolean (e.g 'c')
+ */
+ public char getOptionChar() { return notflag; }
+ }
+
+ /**
+ * Thrown when an illegal or missing value is given by the user for
+ * an option that takes a value. getMessage()
returns
+ * an error string suitable for reporting the error to the user (in
+ * English).
+ */
+ public static class IllegalOptionValueException extends OptionException {
+ /**
+ * UID
+ */
+ private static final long serialVersionUID = -3519380930288555047L;
+
+ public IllegalOptionValueException( Option opt, String value ) {
+ super("Illegal value '" + value + "' for option " +
+ (opt.shortForm() != null ? "-" + opt.shortForm() + "/" : "") +
+ "--" + opt.longForm());
+ this.option = opt;
+ this.value = value;
+ }
+
+ /**
+ * @return the name of the option whose value was illegal (e.g. "-u")
+ */
+ public Option getOption() { return this.option; }
+
+ /**
+ * @return the illegal value
+ */
+ public String getValue() { return this.value; }
+ private Option option;
+ private String value;
+ }
+
+ /**
+ * Representation of a command-line option
+ */
+ public static abstract class Option {
+
+ protected Option( String longForm, boolean wantsValue ) {
+ this(null, longForm, wantsValue);
+ }
+
+ protected Option( char shortForm, String longForm,
+ boolean wantsValue ) {
+ this(new String(new char[]{shortForm}), longForm, wantsValue);
+ }
+
+ private Option( String shortForm, String longForm, boolean wantsValue ) {
+ if ( longForm == null )
+ throw new IllegalArgumentException("Null longForm not allowed");
+ this.shortForm = shortForm;
+ this.longForm = longForm;
+ this.wantsValue = wantsValue;
+ }
+
+ public String shortForm() { return this.shortForm; }
+
+ public String longForm() { return this.longForm; }
+
+ /**
+ * Tells whether or not this option wants a value
+ */
+ public boolean wantsValue() { return this.wantsValue; }
+
+ public final Object getValue( String arg, Locale locale )
+ throws IllegalOptionValueException {
+ if ( this.wantsValue ) {
+ if ( arg == null ) {
+ throw new IllegalOptionValueException(this, "");
+ }
+ return this.parseValue(arg, locale);
+ }
+ else {
+ return Boolean.TRUE;
+ }
+ }
+
+ /**
+ * Override to extract and convert an option value passed on the
+ * command-line
+ */
+ protected Object parseValue( String arg, Locale locale )
+ throws IllegalOptionValueException {
+ return null;
+ }
+
+ private String shortForm = null;
+ private String longForm = null;
+ private boolean wantsValue = false;
+
+ public static class BooleanOption extends Option {
+ public BooleanOption( char shortForm, String longForm ) {
+ super(shortForm, longForm, false);
+ }
+ public BooleanOption( String longForm ) {
+ super(longForm, false);
+ }
+ }
+
+ /**
+ * An option that expects an integer value
+ */
+ public static class IntegerOption extends Option {
+ public IntegerOption( char shortForm, String longForm ) {
+ super(shortForm, longForm, true);
+ }
+ public IntegerOption( String longForm ) {
+ super(longForm, true);
+ }
+ protected Object parseValue( String arg, Locale locale )
+ throws IllegalOptionValueException {
+ try {
+ return new Integer(arg);
+ }
+ catch (NumberFormatException e) {
+ throw new IllegalOptionValueException(this, arg);
+ }
+ }
+ }
+
+ /**
+ * An option that expects a long integer value
+ */
+ public static class LongOption extends Option {
+ public LongOption( char shortForm, String longForm ) {
+ super(shortForm, longForm, true);
+ }
+ public LongOption( String longForm ) {
+ super(longForm, true);
+ }
+ protected Object parseValue( String arg, Locale locale )
+ throws IllegalOptionValueException {
+ try {
+ return new Long(arg);
+ }
+ catch (NumberFormatException e) {
+ throw new IllegalOptionValueException(this, arg);
+ }
+ }
+ }
+
+ /**
+ * An option that expects a floating-point value
+ */
+ public static class DoubleOption extends Option {
+ public DoubleOption( char shortForm, String longForm ) {
+ super(shortForm, longForm, true);
+ }
+ public DoubleOption( String longForm ) {
+ super(longForm, true);
+ }
+ protected Object parseValue( String arg, Locale locale )
+ throws IllegalOptionValueException {
+ try {
+ NumberFormat format = NumberFormat.getNumberInstance(locale);
+ Number num = (Number)format.parse(arg);
+ return new Double(num.doubleValue());
+ }
+ catch (ParseException e) {
+ throw new IllegalOptionValueException(this, arg);
+ }
+ }
+ }
+
+ /**
+ * An option that expects a string value
+ */
+ public static class StringOption extends Option {
+ public StringOption( char shortForm, String longForm ) {
+ super(shortForm, longForm, true);
+ }
+ public StringOption( String longForm ) {
+ super(longForm, true);
+ }
+ protected Object parseValue( String arg, Locale locale ) {
+ return arg;
+ }
+ }
+ }
+
+ /**
+ * Add the specified Option to the list of accepted options
+ */
+ public final Option addOption( Option opt ) {
+ if ( opt.shortForm() != null )
+ this.options.put("-" + opt.shortForm(), opt);
+ this.options.put("--" + opt.longForm(), opt);
+ return opt;
+ }
+
+ /**
+ * Convenience method for adding a string option.
+ * @return the new Option
+ */
+ public final Option addStringOption( char shortForm, String longForm ) {
+ return addOption(new Option.StringOption(shortForm, longForm));
+ }
+
+ /**
+ * Convenience method for adding a string option.
+ * @return the new Option
+ */
+ public final Option addStringOption( String longForm ) {
+ return addOption(new Option.StringOption(longForm));
+ }
+
+ /**
+ * Convenience method for adding an integer option.
+ * @return the new Option
+ */
+ public final Option addIntegerOption( char shortForm, String longForm ) {
+ return addOption(new Option.IntegerOption(shortForm, longForm));
+ }
+
+ /**
+ * Convenience method for adding an integer option.
+ * @return the new Option
+ */
+ public final Option addIntegerOption( String longForm ) {
+ return addOption(new Option.IntegerOption(longForm));
+ }
+
+ /**
+ * Convenience method for adding a long integer option.
+ * @return the new Option
+ */
+ public final Option addLongOption( char shortForm, String longForm ) {
+ return addOption(new Option.LongOption(shortForm, longForm));
+ }
+
+ /**
+ * Convenience method for adding a long integer option.
+ * @return the new Option
+ */
+ public final Option addLongOption( String longForm ) {
+ return addOption(new Option.LongOption(longForm));
+ }
+
+ /**
+ * Convenience method for adding a double option.
+ * @return the new Option
+ */
+ public final Option addDoubleOption( char shortForm, String longForm ) {
+ return addOption(new Option.DoubleOption(shortForm, longForm));
+ }
+
+ /**
+ * Convenience method for adding a double option.
+ * @return the new Option
+ */
+ public final Option addDoubleOption( String longForm ) {
+ return addOption(new Option.DoubleOption(longForm));
+ }
+
+ /**
+ * Convenience method for adding a boolean option.
+ * @return the new Option
+ */
+ public final Option addBooleanOption( char shortForm, String longForm ) {
+ return addOption(new Option.BooleanOption(shortForm, longForm));
+ }
+
+ /**
+ * Convenience method for adding a boolean option.
+ * @return the new Option
+ */
+ public final Option addBooleanOption( String longForm ) {
+ return addOption(new Option.BooleanOption(longForm));
+ }
+
+ /**
+ * Equivalent to {@link #getOptionValue(Option, Object) getOptionValue(o,
+ * null)}.
+ */
+
+ public final Object getOptionValue( Option o ) {
+ return getOptionValue(o, null);
+ }
+
+
+ /**
+ * @return the parsed value of the given Option, or the given default 'def'
+ * if the option was not set
+ */
+ public final Object getOptionValue( Option o, Object def ) {
+ Vector v = (Vector)values.get(o.longForm());
+
+ if (v == null) {
+ return def;
+ }
+ else if (v.isEmpty()) {
+ return null;
+ }
+ else {
+ Object result = v.elementAt(0);
+ v.removeElementAt(0);
+ return result;
+ }
+ }
+
+
+ /**
+ * @return A Vector giving the parsed values of all the occurrences of the
+ * given Option, or an empty Vector if the option was not set.
+ */
+ public final Vector getOptionValues( Option option ) {
+ Vector result = new Vector();
+
+ while (true) {
+ Object o = getOptionValue(option, null);
+
+ if (o == null) {
+ return result;
+ }
+ else {
+ result.addElement(o);
+ }
+ }
+ }
+
+
+ /**
+ * @return the non-option arguments
+ */
+ public final String[] getRemainingArgs() {
+ return this.remainingArgs;
+ }
+
+ /**
+ * Extract the options and non-option arguments from the given
+ * list of command-line arguments. The default locale is used for
+ * parsing options whose values might be locale-specific.
+ */
+ public final void parse( String[] argv )
+ throws IllegalOptionValueException, UnknownOptionException {
+
+ // It would be best if this method only threw OptionException, but for
+ // backwards compatibility with old user code we throw the two
+ // exceptions above instead.
+
+ parse(argv, Locale.getDefault());
+ }
+
+ /**
+ * Extract the options and non-option arguments from the given
+ * list of command-line arguments. The specified locale is used for
+ * parsing options whose values might be locale-specific.
+ */
+ public final void parse( String[] argv, Locale locale )
+ throws IllegalOptionValueException, UnknownOptionException {
+
+ // It would be best if this method only threw OptionException, but for
+ // backwards compatibility with old user code we throw the two
+ // exceptions above instead.
+
+ Vector otherArgs = new Vector();
+ int position = 0;
+ this.values = new Hashtable(10);
+ while ( position < argv.length ) {
+ String curArg = argv[position];
+ if ( curArg.startsWith("-") ) {
+ if ( curArg.equals("--") ) { // end of options
+ position += 1;
+ break;
+ }
+ String valueArg = null;
+ if ( curArg.startsWith("--") ) { // handle --arg=value
+ int equalsPos = curArg.indexOf("=");
+ if ( equalsPos != -1 ) {
+ valueArg = curArg.substring(equalsPos+1);
+ curArg = curArg.substring(0,equalsPos);
+ }
+ } else if(curArg.length() > 2) { // handle -abcd
+ for(int i=1; i alldevs = new ArrayList(); // Will be filled with NICs
+
+
+ int r = Pcap.findAllDevs(alldevs, errbuf);
+ if (r != Pcap.OK || alldevs.isEmpty()) {
+ System.err.printf("Can't read list of devices, error is %s", errbuf.toString());
+ return;
+ }
+
+ // Find the right interface
+ int ifaceIndex = 0;
+ String expectedIface = PcapMultiplexer.ExpectedIface;
+ for( ; ifaceIndex < alldevs.size(); ifaceIndex++) {
+ try {
+ if (expectedIface.equalsIgnoreCase(ByteHelper.byteArrayToString(alldevs.get(ifaceIndex).getHardwareAddress()))) {
+ // Interface found
+ break;
+ }
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ // Check result
+ if (ifaceIndex == alldevs.size()) {
+ throw new RuntimeException(String.format("EthernetLayer.register: Network interface %s not found", expectedIface));
+ }
+
+ device = alldevs.get(ifaceIndex);
+ System.out.println("Listening: " + device.getName());
+ }
+
+ /**
+ * Gets the unique factory instance
+ * @return PcapMultiplexer instance
+ */
+ public static PcapMultiplexer getInstance(final String macAddress){
+ ExpectedIface = macAddress;
+ return (instance = new PcapMultiplexer());
+ }
+
+ /**
+ * Gets the unique factory instance
+ * @return PcapMultiplexer instance
+ */
+ public static PcapMultiplexer getInstance(){
+ return instance;
+ }
+
+ public synchronized void register(ILayer client, short frameType) {
+ // Open interface
+ int snaplen = 64 * 1024; // Capture all packets, no truncation
+ int flags = Pcap.MODE_PROMISCUOUS; // capture all packets
+ int timeout = 10; // 10 millis
+ pcap = Pcap.openLive(device.getName(), snaplen, flags, timeout, errbuf);
+
+ if (pcap == null) {
+ System.err.printf("Error while opening device for capture: " + errbuf.toString());
+ return;
+ }
+ captureThread = new Thread(this);
+ captureThread.start();
+ filter = String.format("ether proto 0x%04x", frameType);
+ System.out.println("New filter: " + filter);
+
+ // Apply filter
+ PcapBpfProgram bpfFilter = new PcapBpfProgram();
+ int optimize = 0; // 1 means true, 0 means false
+ int netmask = 0;
+ int r = pcap.compile(bpfFilter, filter, optimize, netmask);
+ if (r != Pcap.OK) {
+ System.out.println("Filter error: " + pcap.getErr());
+ }
+ pcap.setFilter(bpfFilter);
+
+ dumper = pcap.dumpOpen(client.getFileName());
+
+ _client = client;
+ }
+
+ public synchronized void unregister(ILayer client) {
+ pcap.breakloop();
+ dumper.close();
+ try {
+ captureThread.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ pcap.close();
+ }
+
+ /**
+ * Thread function for jpcap capture loop
+ * @see java.lang.Runnable#run()
+ */
+ @Override
+ public void run() {
+
+ PcapPacketHandler dumpHandler = new PcapPacketHandler() {
+
+ private int counter = 0;
+
+ @Override
+ public void nextPacket(PcapPacket packet, String user) {
+ dumper.dump(packet);
+ counter += 1;
+ if (counter == 500) {
+ System.out.println("nextPacket: Flushing file");
+ dumper.flush();
+ counter = 0;
+ }
+ }
+ };
+
+ pcap.loop(-1, dumpHandler, "pcapdump");
+ }
+
+ /**
+ * Jpcap capture device
+ */
+ private Pcap pcap;
+
+ /**
+ * Jpcap capture thread instance.
+ */
+ private Thread captureThread;
+
+ PcapIf device;
+ private String filter;
+}
\ No newline at end of file
diff --git a/tools/pcapdump/src/org/etsi/its/pcapdump/pcapdump.java b/tools/pcapdump/src/org/etsi/its/pcapdump/pcapdump.java
new file mode 100644
index 0000000000000000000000000000000000000000..d679f2f77a7a09eb6ee5d7274bbd827ea722a6ec
--- /dev/null
+++ b/tools/pcapdump/src/org/etsi/its/pcapdump/pcapdump.java
@@ -0,0 +1,188 @@
+/**
+ *
+ */
+package org.etsi.its.pcapdump;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.util.Date;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.etsi.common.ByteHelper;
+import org.etsi.its.pcapdump.CmdLineParser.IllegalOptionValueException;
+import org.etsi.its.pcapdump.CmdLineParser.UnknownOptionException;
+
+/**
+ * @author yann
+ *
+ */
+public class pcapdump implements ILayer {
+
+ /**
+ * Module version
+ */
+ public static final String Version = "1.0.0.0";
+
+ /**
+ * Logger instance
+ */
+ private final static Logger _logger = Logger.getLogger("org.etsi.its.pcapdump");
+
+ private static String NicAddr = "00FF6BADBFC2";
+
+ private static String FileName = "itsdump.pcapng";
+
+ /**
+ * Debug mode. Default: false
+ */
+ private static Level Debug = Level.OFF;
+
+ /**
+ * ITS Ehter type
+ */
+ private static short FrameType = (short) 0x8947;
+
+ /**
+ * Default ctor
+ */
+ public pcapdump() {
+ // Nothing to do
+ }
+
+ @Override
+ public void dispose() {
+ PcapMultiplexer.getInstance().unregister(this);
+ }
+ /**
+ * @param args
+ */
+ public static void main(String[] args) {
+ // Process command line arguments
+ processCommandLine(args);
+
+ // Set traces
+ _logger.addHandler(new ConsoleHandler());
+ _logger.setLevel(Debug);
+
+
+ // Check if the file exist, never remove or scratch files
+ File file = new File(FileName);
+ if (file.exists()) {
+ File newFile = new File(FileName + "_" + System.currentTimeMillis());
+ file.renameTo(newFile);
+ }
+
+ ILayer layer = new pcapdump();
+ PcapMultiplexer.getInstance(NicAddr);
+ PcapMultiplexer.getInstance().register(layer, FrameType);
+
+ boolean bContinue = true;
+ while (bContinue) {
+ try {
+ // Check keyboard
+ if (System.in.available() > 0) {
+ int token = System.in.read();
+ switch (token) {
+ case 'h': // Help
+ // No break;
+ case '?': // Help
+ cmdeLineUsage();
+ break;
+ case 'q':
+ bContinue = false;
+ _logger.info("Terminate application...");
+ break;
+ } // End of 'switch' statement
+ }
+ // Wait
+ java.lang.Thread.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ } // End of 'while' statement
+
+ layer.dispose();
+ System.err.println("Terminated");
+ System.exit(0);
+ }
+
+ /**
+ * Parse the command line and set options
+ * @param args Command line arguments
+ */
+ private static void processCommandLine(String[] args) {
+ // Sanity checks
+ if (args.length == 0) {
+ return;
+ }
+
+ CmdLineParser parser = new CmdLineParser();
+ CmdLineParser.Option debug = parser.addBooleanOption("Debug");
+ CmdLineParser.Option fileName = parser.addStringOption("FileName");
+ CmdLineParser.Option frameType = parser.addStringOption("FrameType");
+ CmdLineParser.Option NICAddr = parser.addStringOption("NicAddr");
+ try {
+ parser.parse(args);
+ } catch (IllegalOptionValueException e) {
+ e.printStackTrace();
+ printUsage();
+ System.exit(2);
+ } catch (UnknownOptionException e) {
+ e.printStackTrace();
+ printUsage();
+ System.exit(3);
+ }
+
+ Object value;
+ if ((value = parser.getOptionValue(debug, false)) != null) {
+ Debug = (((Boolean)value).booleanValue() == true) ? Level.ALL : Level.OFF;
+ }
+ if ((value = parser.getOptionValue(fileName, "")) != null) {
+ if (!((String)value).isEmpty()) {
+ FileName = (String)value;
+ }
+ }
+ if ((value = parser.getOptionValue(frameType, "")) != null) {
+ if (!((String)value).isEmpty()) {
+ FrameType = (short)Integer.parseInt((String)value, 16);
+ }
+ }
+ if ((value = parser.getOptionValue(NICAddr, "")) != null) {
+ if (!((String)value).isEmpty()) {
+ NicAddr = (String)value;
+ }
+ }
+
+ } // End of method processCommandLine
+
+ /**
+ * Display application usage
+ */
+ private static void printUsage() {
+ System.err.println("Usage: [--Debug (default:false)]\n" +
+ " [--FileName=filename \"Output file name \"]\n" +
+ " [--FrameType=0x8947 \"Ethernet prototype\" (0x8947)]\n" +
+ " \n"
+ );
+ }
+
+ private static void cmdeLineUsage() {
+ System.err.println("Command Line Usage: \n" +
+ // TODO
+ " [q to exit]\n" +
+ " \n"
+ );
+
+ }
+
+ @Override
+ public String getFileName() {
+ return FileName;
+ }
+
+}