I found a bug while writing some new test cases and having to use JPacket.transferTo(JPacket) to copy contents of one packet to another.
I was writing a neat routine to get a single packet out of a file by packet index, perfect as an example on the website so I'll add it in, but here is what happened. First packet is as received from the packet handler, the second a new packet that allocates a
2K memory block to hold the packet content.
JPacket shared = // from JPacketHandler
JPacket dst = new JPacket(2 * 1024); // Allocate memory
Next we copy contents of shared packet to dest.
shared.transferStateAndDataTo(dst);
And although everything seem to copy (I verified the contents of both shard and dst data and state buffers, the packet accessors were giving me real strange data.
Turns out that the packet_state_t structure wasn't being copied in its entirety. It has a variable number of header_t structures attached at the end and therefore its not a static size structure. I fixed it up in the scanner to properly update the state size field and to include the header_t[] memory as well.
So now every correctly copies over.
I've setup the bug and feature trackers in SF.net. I defined meanings for categories and group artifacts.
Categories: API, Protocol, Platform and Installation
Group is simply the jnetpcap version number the issue or feature is related to: Version 1.0, 1.1, 1.2 and the future 1.3.
This should make it easy for people to lookup bugs in any version of the software or feature and in which version it occurred or the feature is expected to be included in.
Version 1.2 RC1 is released and I have not heard of any issues from the initial testers. It does usually take a few days before I get any feedback.
There were a few things that did not make it in RC1 but need to be included in the general 1.2 release. Mainly the existing protocol headers need to be fixed up and completed.
I'm keeping track of these omissions and bugs here:
https://sourceforge.net/tracker2/?func=browse&group_id=164277&atid=83108...
Main thing that was left out, because of time pressure, was protocol sub headers. That is things like Ip options which are optional headers. I'm working on adding them in. Very small changes to the formatter package basically added another public format method that takes 2 JHeaders as argument, 1st the parent and second the sub-header. And Text and Xml subclasses just needed to implement 2 new abstract methods, beforeSubHeader and afterSubHeader. All they do is properly setup the indent levels and print out nice summary of the sub header i.e. ("ip4: ******* ip4 optional header (timestamp)"). Xml formatter was even simpler. All they do is call on existing header formatting methods at increased indent level.
Also I'm completing the protocol header implementations. Like I said, Ip and the Tcp protocols don't have their options defined in RC1. Also ICMP definition is incomplete, so I need to just add in all the ICMP cases and that will be it for RC2.
So RC2 is definitely coming after I get these last few tidbits in. Of course any bugs that come up will be fixed very quickly as well.
I'd appreciate any feedback about any bugs or API issues (anything clumsy for example.)
Released version 1.2 candidate #1. This release adds significant features, specifically "packet decoder framework" and additional missing capabilities from native libpcap.
You can now get the hardware mac address for any physical interface that has one. New JPacketHandler dispatches packets that are fully decoded and the user works with specific protocol headers and with java compile time safety. Two packet formatters are included for generating textual output from packets. TextFormatter generates human readable output while XmlFormatter is targeted toward a software application and/or storage persistence in XML form.
For detailed overview of the release 1.2 please visit its overview page:
http://jnetpcap.com/release1.2
Javadocs for the API can be found here:
http://jnetpcap.com/docs/javadoc/jnetpcap-1.2-javadoc/index.html
Q: I get this exception when I try to access any methods from org.jnetpcap.winpcap package.
A: The exception is telling you that on this particular platform the winpcap extension is not available and can not be used.
WinPcap native library is a windows implementation of libpcap library. It supports all of the libpcap functions and adds several new capabilities but only on windows platforms. jNetPcap API provides WinPcap extention only on windows platform.
In order to avoid having this error thrown, the user must check if WinPcap extension is supported on this particular platform at runtime. To check for support use WinPcap.isSupported():boolean method which will return a boolean true if it is supported, otherwise false. This method never throws an exception and needs to be used before your code relies on any features within that winpcap package.
Q: When accessing jNetPcap API I get this exception thrown: "UnsatisfiedLinkError".
A: The exception is thrown when you access a method that requires the native jnetpcap shared library (.dll or .so library on different systems) and its not found.
The library is supplied with jNetPcap. You need to ensure that you correctly define on each particular system, the folder or directory where the library is located.
You can use a OS specific environment variable to define the directory where the library resides or you can tell java VM directly using -Djava.library.path=path bypassing and overriding any environmental settings. Notice that its directory path not a fully qualified path to the library itself. Another words don't include the name of the library file in the path, just the directory.
On any unix system make sure that that variable is exported in the environment
LD_LIBRARY_PATH=/usr/lib
In your c:\autoexec.bat
set path="%path%;/windows/system32"
This example gets a list of interfaces then iterates through the list. For each interface it acquires MAC address, formats it and prints it out. The example skips any interfaces that do not have a MAC address assigned such as loop interfaces non datalink interfaces.
Source code: GetInterfaceHardwareAddress.java
package org.jnetpcap.examples;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.jnetpcap.Pcap;
import org.jnetpcap.PcapIf;
public class GetInterfaceHardwareAddress {
public static void main(String[] args) throws IOException {
List<PcapIf> alldevs = new ArrayList<PcapIf>(); // Will be filled with NICs
StringBuilder errbuf = new StringBuilder(); // For any error msgs
/***************************************************************************
* First get a list of devices on this system
**************************************************************************/
int r = Pcap.findAllDevs(alldevs, errbuf);
if (r == Pcap.NOT_OK || alldevs.isEmpty()) {
System.err.printf("Can't read list of devices, error is %s", errbuf
.toString());
return;
}
/***************************************************************************
* Second iterate through all the interface and get the HW addresses
**************************************************************************/
for (final PcapIf i : alldevs) {
final byte[] mac = i.getHardwareAddress();
if (mac == null) {
continue; // Interface doesn't have a hardware address
}
System.out.printf("%s=%s\n", i.getName(), asString(mac));
}
}
private static String asString(final byte[] mac) { I'm done with all the testing. The code compiles without any warnings and all the jUnit test cases pass. There are a few javadoc warnings that come up though.
Tomorrow I will finish up documenting all the classes and functions in javadoc and will clean up the few javadoc warnings as well.
We're good to go for release on Sunday evening.
Here is a large jUnit test case that shows off numerous capabilities of jNetPcap:
package org.jnetpcap;
import java.io.File;
import java.io.IOException;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import junit.framework.TestCase;
import junit.textui.TestRunner;
import org.jnetpcap.nio.JBuffer;
import org.jnetpcap.nio.JMemory;
import org.jnetpcap.nio.JNumber;
import org.jnetpcap.nio.JNumber.Type;
/**
* @author Mark Bednarczyk
* @author Sly Technologies, Inc.
*/
@SuppressWarnings("deprecation")
public class TestPcapJNI
extends TestCase {
// private final static String device =
// "\\Device\\NPF_{BC81C4FC-242F-4F1C-9DAD-EA9523CC992D}";
private final static String win =
"\\Device\\NPF_{BC81C4FC-242F-4F1C-9DAD-EA9523CC992D}";
private final static String linux = "any";
private final static boolean isWindows =
"Windows XP".equals(System.getProperty("os.name"));
private final static String device = (isWindows) ? win : linux;
private final static String fname = "tests/test-l2tp.pcap";
private static final int OK = 0;
private static final int snaplen = 64 * 1024;
private static final int promisc = 1;
private static final int oneSecond = 1000;
/**
* Will generate HTTP traffic to a website. Use start() to start in a test
* method, and always put stop() in tearDown. Safe to call stop even when
* never started.
*/
private static final HttpTrafficGenerator gen = new HttpTrafficGenerator();
private static File tmpFile;
static {
try {
tmpFile = File.createTempFile("temp-", "-TestPcapJNI");
} catch (IOException e) {
tmpFile = null;
System.err.println("Unable to initialize a temporary file");
}
}
private StringBuilder errbuf = new StringBuilder();
private final PcapHandler<?> doNothingHandler = new PcapHandler There are a number of deprecated classes and methods in version 1.2. I'm keeping a list of them in feature ticket requests:
https://sourceforge.net/tracker2/?func=browse&group_id=164277&atid=83108...
All the deprecated methods are still fully implemented, but will be removed from the API at some point in a future release. They also contain new counter parts.