2.3 - Opening a Network Interface for Capture

Java package: org.jnetpcap

Once we have a network interface in the form of a NetIf object the user or the application is interested in opening, we can proceed to opening it. The main call which does this is Pcap.openLive(). This method takes a number of parameters, but the most important one is the name of the network interface. The name is a string, not the NetIf object itself, but we can easily acquire the name using NetIf.getName() and pass that in directly to openLive() call.

int snaplen = 64 * 1024;           // Capture all packets, no truncation
int flags = Pcap.MODE_PROMISCUOUS; // capture all packets
int timeout = 10 * 1000;           // 10 seconds in millis
Pcap pcap = Pcap.openLive(device.getName(), snaplen, flags, timeout, errbuf);

if (pcap == null) {
  System.err.printf("Error while opening device for capture: "
        + errbuf.toString());

Where device is our NetIf object (acquired in previous section's example.) When successful the call returns an instance of Pcap object. Notice that we used a static Pcap call to open, but then when successful we will be working with specific instance of Pcap which is bound to the network interface we opened.

The other parameters set various libpcap options which can limit the number of packets captured and if the capture should ever timeout when no packets are being received. The last parameter is an error buffer, a simple StringBuilder object which will be filled in with any warnings or error messages. If the call to openLive() fails, a null will be returned from the call. We can check for that null and expect an error message to be present in our error buffer.

Pcap.openLive(): Pcap.MODE_PROMISCOUS flag

What is a promiscous mode. Here is the definition from wiki pedia:

"In computing, promiscuous mode or promisc mode is a configuration of a network card that makes the card pass all traffic it receives to the central processing unit rather than just packets addressed to it — a feature normally used for packet sniffing." - Source: Wikipedia

So if you want to see all network traffic that your network card can see, you need to set this mode. If you don't set this mode, the network interface will only see network packets that are specifically addressed for the machine the capture is taking place. It will also always see all broadcast packets and may be some multicast packets.

Pcap.openLive(): snaplen parameter

This option to Pcap.openLive sets the maximum number of bytes to capture from the network. If the packet being captured is bigger than the snaplen length set, then that packet will be truncated in length to snaplen, otherwise it will be captured full length.

This is the reason in jNP API you will frequently encounter to lengths, caplen and wirelen. Caplen is used by jNP API as the number of bytes that were captured and kept, while wirelen parameters and properties specify the original length of the packet as it was seen on the network.

Why would you want to set a snaplen? If your application is only interested in headers that are always found at the beginning of a network packet and it doesn't care about the data, packets are typically truncated to 128 bytes or less. 128 bytes is usually enough to capture all the headers present and drop the data portion. Note that this is simply an estimate which may not capture all the headers if the packet is complex or it may still capture a number of data bytes of the packet past the last header. This all depends on the packet itself and type of network and communication involved. Tunneled packets will usually have a significantly greater number of headers than non tunneled packets. Icmp error messages also carry original packets that caused the error in the first place which adds significant amount of headers to a packet.

IMPORTANT WARNING: libpcap has a quirk with snaplen. Snaplen is only applied when there is also a filter applied at the same time. Without setting a filter using Pcap.setFilter(), even the most basic one such as "1", the snaplen parameter is ignored and packets will not be truncated. This is a know libpcap issue and is not an issue with jNetPcap API.

Pcap.openLive(): timeout parameter

The read timeout is used to arrange that the read not necessarily return immediately when a packet is seen, but that it wait for some amount of time to allow more packets to arrive and to read multiple packets from the OS kernel in one operation. Not all platforms support a read timeout; on platforms that don't, the read timeout is ignored. A zero value for to_ms, on platforms that support a read timeout, will cause a read to wait forever to allow enough packets to arrive, with no timeout.