Pcap4J Documentation

repository·v1·Indexed 22 days ago

https://github.com/kaitoy/pcap4j

A Java library for capturing, crafting, and sending network packets by wrapping native pcap libraries (libpcap, WinPcap, Npcap) via JNA. It supports a wide range of protocols including Ethernet, IPv4/IPv6, TCP, UDP, ARP, and DNS, and provides capabilities for converting captured packets into Java objects, dumping pcap-formatted files, and implementing custom protocol packet classes.

Tokens
4.9K
Snippets
8
Records
23
Agent score
78%

What's inside Pcap4J

  1. What is Pcap4J

    v1

    Pcap4J is a Java library designed for capturing, crafting, and sending network packets. It acts as a Java-oriented wrapper around native packet capture libraries like libpcap, WinPcap, or Npcap using JNA.

    Key capabilities include:

    • Converting captured packets into Java objects where header fields can be accessed or modified.
    • Crafting new packet objects from scratch and sending them to a real network.
    • Supporting a wide range of protocols (Ethernet, IPv4/IPv6, TCP, UDP, ARP, DNS, etc.).
    • Dumping and reading pcap-formatted files (e.g., Wireshark captures).
    • Providing serializable and thread-safe (practically immutable) packet classes.
  2. Understand Pcap4J module dependencies

    v1

    Pcap4J is divided into several modules. To run a Pcap4J application, you must always include the pcap4j-core artifact.

    For packet analysis, you must also include either pcap4j-packetfactory-static or pcap4j-packetfactory-propertiesbased. If you do not include a Packet Factory module, Pcap4J will return an UnknownPacket object for all captured packets instead of the specific packet type.

  3. How Packet Factory works in Pcap4J

    v1

    The Packet Factory is the mechanism used by the Pcap4J core module to instantiate packet objects from raw byte arrays (captured packets).

    It is a pluggable system that uses a Packet Factory Binder to connect specific factory implementations to the Pcap4J core. A factory implementation's job is to take a classifier (such as EtherType) and find the corresponding packet class (e.g., IpV4Packet) or packet piece class (e.g., IpV4Rfc1349Tos) to instantiate the object.

  4. Choose between Static and Properties-Based Packet Factory

    v1

    Pcap4J provides two different types of Packet Factory modules depending on your performance and flexibility requirements:

    1. Static Packet Factory:

      • Mechanism: Finds packet and packet piece classes using a static approach.
      • Pros: Faster performance because it does not use Java reflection.
      • Cons: Less flexible; you cannot replace packet classes without making code changes.
    2. Properties-Based Packet Factory:

      • Mechanism: Finds packet and packet piece classes via Java properties.
      • Pros: Highly flexible.
      • Cons: Slower performance due to heavy reliance on Java reflection.
  5. Use Pcap4J in a Maven project

    v1

    Add the following dependencies to your pom.xml to use Pcap4J. Note that you typically need both pcap4j-core and a packet factory implementation (like pcap4j-packetfactory-static).

    <dependencies>
      <dependency>
        <groupId>org.pcap4j</groupId>
        <artifactId>pcap4j-core</artifactId>
        <version>1.8.2</version>
      </dependency>
      <dependency>
        <groupId>org.pcap4j</groupId>
        <artifactId>pcap4j-packetfactory-static</artifactId>
        <version>1.8.2</version>
      </dependency>
    </dependencies>
  6. Build Pcap4J with distribution or test coverage profiles

    v1

    Certain modules are only built when specific Maven profiles are activated:

    To build the distribution module, use the distribution-assembly profile:

    mvn -P distribution-assembly install

    To build the test coverage module (which uses JaCoCo to measure coverage of pcap4j-packettest), use the test-coverage profile.

  7. System requirements for Pcap4J

    v1

    To use Pcap4J, ensure your environment meets the following requirements:

    Java Version

    • Pcap4J 1.1.0 and earlier: Java 5.0+
    • Pcap4J 1.2.0 and later: Java 6.0+

    Native Libraries

    • UNIX-like systems: libpcap 1.0.0 or later.
    • Windows: WinPcap 3.0+ or Npcap.

    Dependencies

    Include the following in your classpath:

    • jna
    • slf4j-api (along with a logging implementation like logback)

    Permissions

    Pcap4J requires administrative/root privileges to capture packets.

    Linux Tip: You can run Pcap4J as a non-root user by granting the CAP_NET_RAW and CAP_NET_ADMIN capabilities to the java executable:

    setcap cap_net_raw,cap_net_admin=eip /path/to/java
  8. Implement a new protocol packet class

    v1

    To add support for a new protocol, you must implement a packet class that represents the protocol's structure.

    Requirements

    1. Packet Class: Must implement org.pcap4j.packet.Packet. It is highly recommended to extend org.pcap4j.packet.AbstractPacket to reuse existing logic.
    2. Header Class: Must implement org.pcap4j.packet.Packet.Header or extend org.pcap4j.packet.AbstractPacket.AbstractHeader.
    3. Builder Class: Must implement org.pcap4j.packet.Packet.Builder or extend org.pcap4j.packet.AbstractPacket.AbstractBuilder.

    Responsibilities

    Your packet class must handle the following in its implementation:

    • Constructor: Build the header object (if applicable) and the payload object (if applicable).
    • getBuilder() method: Return a new instance of your builder class.
    • Static Factory Method: It is recommended to provide a static factory method to enable compatibility with the Properties-Based Packet Factory.

    Example Implementation Pattern

    public static YourPacket newPacket(byte[] rawData, int offset, int length) {
      return new YourPacket(rawData);
    }
    public static YourPacket newPacket(byte[] rawData, int offset, int length) {
      return new YourPacket(rawData);
    }
  9. Run Pcap4J using Docker

    v1

    A pre-configured CentOS environment for Pcap4J is available on Docker Hub. You can pull the image and run a packet capture on the container's eth0 interface immediately.

    docker pull kaitoy/pcap4j
    docker run kaitoy/pcap4j:latest
  10. Install Pcap4J in a Maven project

    v1

    To use Pcap4J in your Maven-based project, add pcap4j-core and a packet factory implementation (such as pcap4j-packetfactory-static) to your pom.xml dependencies.

    Note: You must ensure a native pcap library (libpcap, WinPcap, or Npcap) is installed on your system for the library to function.

    <dependencies>
      <dependency>
        <groupId>org.pcap4j</groupId>
        <artifactId>pcap4j-core</artifactId>
        <version>1.8.2</version>
      </dependency>
      <dependency>
        <groupId>org.pcap4j</groupId>
        <artifactId>pcap4j-packetfactory-static</artifactId>
        <version>1.8.2</version>
      </dependency>
    </dependencies>
  11. System requirements and dependencies for Pcap4J

    v1

    Before using Pcap4J, ensure your environment meets the following requirements:

    Java Version

    • Pcap4J 1.1.0 or older: Java 5.0+
    • Pcap4J 1.2.0 or newer: Java 6.0+

    Native Libraries

    A native pcap library is required:

    • Linux/UNIX: libpcap 1.0.0+
    • Windows: WinPcap 3.0+ or Npcap

    Java Dependencies

    • jna
    • slf4j-api
    • An implementation of a logger for slf4j (e.g., logback-classic)

    Privileges

    Pcap4J requires administrator or root privileges to access network interfaces.

    Linux non-root workaround: You can grant specific capabilities to your Java executable to run without full root privileges: setcap cap_net_raw,cap_net_admin=eip /path/to/java

  12. Configure the Static Packet Factory

    v1

    If you are using the pcap4j-packetfactory-static module, you can register your packet class by modifying the StaticTcpPortPacketFactory.java source code.

    Add a new entry to the instantiaters map within the constructor. This requires providing a PacketInstantiater that calls your packet class's static factory method.

    instantiaters.put(
      TcpPort.getInstance((short)1234),
      new PacketInstantiater(byte[] rawData, int offset, int length) throws IllegalRawDataException {
        return YourPacket.newPacket(rawData, offset, length);
      }
    );