Commit 6395e27c authored by garciay's avatar garciay

Import Pcap Capture tool on file

parent c2fbe606
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="lib" path="F:/FSCOM/ETSI/ITS/STF517_ITS_Valid_Conform_Frmwk.2016/workspace_ttwb/STF517/tt3plugins/EtsiItsAdapter/jnetpcap-1.4.r1425/jnetpcap.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>pcapdump</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
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
@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
<?xml version="1.0" encoding="WINDOWS-1252" standalone="no"?>
<jardesc>
<jar path="pcapdump/lib/PcapDump.jar"/>
<options buildIfNeeded="true" compress="true" descriptionLocation="/pcapdump/PcapDump.jardesc" exportErrors="true" exportWarnings="true" includeDirectoryEntries="false" overwrite="true" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
<storedRefactorings deprecationInfo="true" structuralOnly="false"/>
<selectedProjects/>
<manifest generateManifest="true" mainClassHandleIdentifier="=pcapdump/src&lt;org.etsi.its.pcapdump{pcapdump.java[pcapdump" manifestLocation="/STF517_ITS_Valid_Conform_Frmwk.2016/tool/org/etsi/its/tool/elvior/ManifestCodec.mf" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true">
<sealing sealJar="false">
<packagesToSeal/>
<packagesToUnSeal/>
</sealing>
</manifest>
<selectedElements exportClassFiles="true" exportJavaFiles="false" exportOutputFolder="false">
<javaElement handleIdentifier="=pcapdump/src"/>
</selectedElements>
</jardesc>
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()));
}
}
}
}
/**
* @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 <A> Type of the first member of the Tuple
* @param <B> Type of the second member of the Tuple
*/
public interface ITuple<A, B> {
/** 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
/**
* 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
/**
* @author STF 424_ITS_Test_Platform
* @version $URL$
* $Id$
*/
package org.etsi.common;
/**
* This class implements the ITuple interface
* @param <A> Type of the first member of the Tuple
* @param <B> Type of the second member of the Tuple
*/
public class Tuple<A, B> implements ITuple<A, B> {
/**
* 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;
}
}
This diff is collapsed.
package org.etsi.its.pcapdump;
public interface ILayer {
public void dispose();
public String getFileName();
} // End of interface ILayer
/**
* Pcap capture multiplexor
*
* @author ETSI / STF424
* @version $URL$
* $Id$
* Note Copy jnetpcap.jar in C:\WINDOWS\Sun\Java\lib\ext, location of jpcap library
*/
package org.etsi.its.pcapdump;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.etsi.common.ByteHelper;
import org.jnetpcap.Pcap;
import org.jnetpcap.PcapBpfProgram;
import org.jnetpcap.PcapDumper;
import org.jnetpcap.PcapIf;
import org.jnetpcap.packet.PcapPacket;
import org.jnetpcap.packet.PcapPacketHandler;
public class PcapMultiplexer implements Runnable {
private static String ExpectedIface = "D4BED91269BD";
/**
* Unique instance of the factory
*/
private static PcapMultiplexer instance = null;
private StringBuilder errbuf = new StringBuilder(); // For any error msgs
private ILayer _client;
private PcapDumper dumper;
private PcapMultiplexer() {
filter = "";
// Obtain the list of network interfaces
List<PcapIf> alldevs = new ArrayList<PcapIf>(); // 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<String> dumpHandler = new PcapPacketHandler<String>() {
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;
}
}
};