Search code examples
javatcpnullpointerexceptionpacketpcap4j

I'm trying to send TCP SYN packet in java using Pcap4j library, but I get a NullPointerException on line "ipv4Builder.build();"


Code and Error should explain my problem (and if not, I can explain more)

Code:

import org.pcap4j.core.*;
import org.pcap4j.packet.*;
import org.pcap4j.packet.namednumber.TcpPort;
import org.pcap4j.util.MacAddress;
import org.pcap4j.packet.namednumber.EtherType;
import org.pcap4j.packet.namednumber.IpNumber;
import org.pcap4j.packet.namednumber.IpVersion;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.util.Collections;
import java.util.List;

public class SYN {

    public static void send() {
        String targetIp = "8.8.8.8";
        int targetPort = 80;

        try {
            List<PcapNetworkInterface> allDevs = Pcaps.findAllDevs();
            Collections.shuffle(allDevs);
            PcapNetworkInterface nif = null;
            Inet4Address sourceIp = null;
            
            for (PcapNetworkInterface dev : allDevs) {
                System.out.println("Interface: " + dev.getName() + " (" + dev.getDescription() + ")");
                
                for (PcapAddress pcapAddress : dev.getAddresses()) {
                    InetAddress addr = pcapAddress.getAddress();
                    if (addr instanceof Inet4Address) {
                        System.out.println("Found IPv4 Address: " + addr.getHostAddress());
                        if (nif == null) {
                            nif = dev;
                            sourceIp = (Inet4Address) addr;
                            break;
                        }
                    }
                }
                if (nif != null) {
                    break;
                }
            }

            if (nif == null || sourceIp == null) {
                System.out.println("No suitable network interface found.");
                return;
            }
            
            System.out.println("Selected Interface: " + nif.getName());
            System.out.println("Source IP: " + sourceIp.getHostAddress());

            PcapHandle handle = nif.openLive(65536, PcapNetworkInterface.PromiscuousMode.PROMISCUOUS, 10);

            TcpPacket.Builder tcpBuilder = new TcpPacket.Builder();
            tcpBuilder
                    .srcPort(TcpPort.getInstance((short) 80))
                    .dstPort(TcpPort.getInstance((short) targetPort))
                    .sequenceNumber(100)
                    .acknowledgmentNumber(0)
                    .dataOffset((byte) 5)
                    .syn(true)
                    .window((short) 65535)
                    .correctChecksumAtBuild(true)
                    .correctLengthAtBuild(true);

            Inet4Address destIp = (Inet4Address) InetAddress.getByName(targetIp);

            IpV4Packet.Builder ipv4Builder = new IpV4Packet.Builder();
            ipv4Builder
                    .version(IpVersion.IPV4)
                    .tos(IpV4Rfc791Tos.newInstance((byte) 0))
                    .ttl((byte) 64)
                    .protocol(IpNumber.TCP)
                    .srcAddr(sourceIp)
                    .dstAddr(destIp)
                    .payloadBuilder(tcpBuilder)
                    .correctChecksumAtBuild(true)
                    .correctLengthAtBuild(true);
            
            System.out.println(sourceIp == null);
            System.out.println(destIp == null);
            Packet p1 = ipv4Builder.build(); // Error

            handle.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Error:

false // sourceIp is not null
false // destIp is not null
java.lang.NullPointerException: builder.srcAddr: null builder.dstAddr: null
    at org.pcap4j.packet.TcpPacket.<init>(TcpPacket.java:100)
    at org.pcap4j.packet.TcpPacket.<init>(TcpPacket.java:33)
    at org.pcap4j.packet.TcpPacket$Builder.build(TcpPacket.java:432)
    at org.pcap4j.packet.TcpPacket$Builder.build(TcpPacket.java:169)
    at org.pcap4j.packet.IpV4Packet.<init>(IpV4Packet.java:121)
    at org.pcap4j.packet.IpV4Packet.<init>(IpV4Packet.java:32)
    at org.pcap4j.packet.IpV4Packet$Builder.build(IpV4Packet.java:370)

What I've already tried to do:

I've debugged the code with no succes, after that I've tried to search the error online. (I haven't found anyting). Asking AI also didn't help (it just generated some compilation errors)


Solution

  • When you use TcpPacket.Builder.correctChecksumAtBuild(), it will use the srcAddr field and dstAddr field to calculate the checksum later on. These fields must therefore be set when using correctChecksumAtBuild, see the source code of the org.pcap4j.packet.TcpPacket class:

    if (builder.correctChecksumAtBuild) {
      if (builder.srcAddr == null || builder.dstAddr == null) {
        StringBuilder sb = new StringBuilder();
        sb.append("builder.srcAddr: ")
            .append(builder.srcAddr)
            .append(" builder.dstAddr: ")
            .append(builder.dstAddr);
        throw new NullPointerException(sb.toString());
      }
    

    Depending on what you want to do, set the srcAddr field and dstAddr field for the TcpPacket object as well or not use the correctChecksumAtBuild setting.