slytechs-repos / jnetpcap-legacy

jNetPcap v1 (Maintenance Only)
https://www.jnetpcap.org
GNU Lesser General Public License v2.1
4 stars 0 forks source link

Undefined symbol: mac_addr_dlpi #7

Closed Belippo closed 1 year ago

Belippo commented 1 year ago

Jnetpcap v1.4 works well in windows but when i run the same code (i send a simple syn tcp packet) in Linux amd64 i got the error: Undefined symbol: mac_addr_dlpi

slytechs-repos commented 1 year ago

This was also a problem in jNetPcap v1 at one point. I will look into it right away:

https://sourceforge.net/p/jnetpcap/bugs/116/

V2 is different, we don't compile anything and rely on FF to resolve all symbols. Its likely another native library needs to be loaded or is not found besides libpcap.so

slytechs-repos commented 1 year ago

Can you run the command:

Starship:/usr/lib/x86_64-linux-gnu> ldd libpcap.so
    linux-vdso.so.1 (0x00007fff25085000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007efe28000000)
    libdbus-1.so.3 => /lib/x86_64-linux-gnu/libdbus-1.so.3 (0x00007efe282f2000)
    /lib64/ld-linux-x86-64.so.2 (0x00007efe283ae000)
    libsystemd.so.0 => /lib/x86_64-linux-gnu/libsystemd.so.0 (0x00007efe2822b000)
    liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007efe27fd5000)
    libzstd.so.1 => /lib/x86_64-linux-gnu/libzstd.so.1 (0x00007efe27f06000)
    liblz4.so.1 => /lib/x86_64-linux-gnu/liblz4.so.1 (0x00007efe27ee6000)
    libcap.so.2 => /lib/x86_64-linux-gnu/libcap.so.2 (0x00007efe27edb000)
    libgcrypt.so.20 => /lib/x86_64-linux-gnu/libgcrypt.so.20 (0x00007efe27d9d000)
    libgpg-error.so.0 => /lib/x86_64-linux-gnu/libgpg-error.so.0 (0x00007efe27d77000)

on your linux system so I can compare your linked/found dependencies?

Belippo commented 1 year ago
└─# ldd libpcap.so
        linux-vdso.so.1 (0x00007fff3238d000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f011d9a5000)
        libdbus-1.so.3 => /lib/x86_64-linux-gnu/libdbus-1.so.3 (0x00007f011d94f000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f011dbea000)
        libsystemd.so.0 => /lib/x86_64-linux-gnu/libsystemd.so.0 (0x00007f011d880000)
        libcap.so.2 => /lib/x86_64-linux-gnu/libcap.so.2 (0x00007f011d874000)
        libgcrypt.so.20 => /lib/x86_64-linux-gnu/libgcrypt.so.20 (0x00007f011d72d000)
        liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007f011d6fc000)
        libzstd.so.1 => /lib/x86_64-linux-gnu/libzstd.so.1 (0x00007f011d640000)
        liblz4.so.1 => /lib/x86_64-linux-gnu/liblz4.so.1 (0x00007f011d61a000)
        libgpg-error.so.0 => /lib/x86_64-linux-gnu/libgpg-error.so.0 (0x00007f011d5f2000)

Erro i got in detail: /usr/lib/jvm/java-17-openjdk-amd64/bin/java: symbol lookup error: /usr/lib/libjnetpcap.so: undefined symbol: mac_addr_dlpi

slytechs-repos commented 1 year ago

Are you compiling from source or using the downloadable binary?

If you make the change in jnetpcaputils.cpp file (around line 612):

#if defined(Linux) || defined(HPUX) || defined(AIX) || defined(DARWIN) || \
        defined(FREE_BSD) || defined(NET_BSD) || defined(OPEN_BSD) || \
        defined(__APPLE__) || defined(__linux__) || defined(__unix__)

    mac_addr_sys(buf, mac);

#else

    mac_addr_dlpi(buf, mac);

#endif

That should fix it. I will test it and check in the changes.

slytechs-repos commented 1 year ago

Also I encourage you to move on from V1 and try jNetPcap v2 going forward.

Belippo commented 1 year ago

I'am using the downloadable binary, how can i add that lines?

slytechs-repos commented 1 year ago

It has to be recompiled or DLPI stream package added. This is supported on SysV unixes as far as I remember.

Belippo commented 1 year ago

Oh no! There is no the .so with that fix?

slytechs-repos commented 1 year ago

The latest one should be linked properly. I'm not sure what the issue is yet or why.

Belippo commented 1 year ago

I'am using the jnetpcap-1.4.r1425-1.linux64.x86_64.tgz .so . Where can i find the latest one?

slytechs-repos commented 1 year ago

Still checking, its working on my system with r1425.

slytechs-repos commented 1 year ago

I just ran the PcapSendPacketExample using jnetpcap-1.4.r1425-1.linux64.x86_64.tgz package and it works.

Make sure that you your LD_LIBRARY_PATH is pointing at the right jnetpcap and not some SysV variant.

When I run the example, it properly resolves the PcapIf interface (which is where the error is occuring) and then it sends the bogus packet which I can capture with wireshark:

Screenshot from 2023-04-27 12-13-02

Copy of the example found in the /examples/java directory in root jnetpcap install package:

public class PcapSendPacketExample {

    public static void main(String[] args) {
        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;
        }
        PcapIf device = alldevs.stream()
                .filter(d -> d.getName().equals("enp0s25"))
                .findAny().orElseThrow(IllegalStateException::new); // We know we have atleast 1 device

        System.out.printf("Opening device:  %s%n", device.getName());

        /***************************************************************************
         * Second we open a network interface
         **************************************************************************/
        int snaplen = 64 * 1024; // Capture all packets, no trucation
        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.println(errbuf);
            System.exit(1);
        }

        /***************************************************************************
         * Third we create our crude packet we will transmit out This creates a
         * broadcast packet
         **************************************************************************/
        byte[] a = new byte[14];
        Arrays.fill(a, (byte) 0xff);
        ByteBuffer b = ByteBuffer.wrap(a);

        /***************************************************************************
         * Fourth We send our packet off using open device
         **************************************************************************/
        if (pcap.sendPacket(b) != Pcap.OK) {
            System.err.println(pcap.getErr());
        }

        /***************************************************************************
         * Lastly we close
         **************************************************************************/
        pcap.close();

    }

}
slytechs-repos commented 1 year ago

Also make sure your have SUDO privileges to the network interface. Set that up with the following:

sudo setcap cap_net_raw,cap_net_admin=eip $JAVA_HOME/bin/java

And the target can not be a link for JDK8 you may have to use path $JAVA_HOME/jre/bin/java, if the first doesn't work.

Belippo commented 1 year ago

i think it's pointing to the right jnetpcap, i installed only that ,indeed if i try to delete libjnetpcap.so in /usr/lib i got "Unsatisfied link error". I have tried sudo setcap cap_net_raw,cap_net_admin=eip /usr/lib/jvm/java-17-openjdk-amd64/bin/java but it doesn't work

Belippo commented 1 year ago

I also tried on WSL kali linux and on another machine with parrotOSx64 and i got the same issue

slytechs-repos commented 1 year ago

I'm still looking

slytechs-repos commented 1 year ago

Can you also do the same thing on jnetpcap shared library:

Starship:~/lib/jnetpcap-1.4.r1425-1.linux64.x86_64/jnetpcap-1.4.r1425> ldd libjnetpcap.so
    linux-vdso.so.1 (0x00007ffe06302000)
    libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f701f400000)
    libpcap.so => /lib/x86_64-linux-gnu/libpcap.so (0x00007f701fae7000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f701f000000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f701f719000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f701fb55000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f701fac7000)
    libdbus-1.so.3 => /lib/x86_64-linux-gnu/libdbus-1.so.3 (0x00007f701f6cb000)
    libsystemd.so.0 => /lib/x86_64-linux-gnu/libsystemd.so.0 (0x00007f701f339000)
    liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007f701f6a0000)
    libzstd.so.1 => /lib/x86_64-linux-gnu/libzstd.so.1 (0x00007f701f26a000)
    liblz4.so.1 => /lib/x86_64-linux-gnu/liblz4.so.1 (0x00007f701f680000)
    libcap.so.2 => /lib/x86_64-linux-gnu/libcap.so.2 (0x00007f701faba000)
    libgcrypt.so.20 => /lib/x86_64-linux-gnu/libgcrypt.so.20 (0x00007f701eec2000)
    libgpg-error.so.0 => /lib/x86_64-linux-gnu/libgpg-error.so.0 (0x00007f701f65a000)

I'm just trying to see what is different between your install and our labs.

slytechs-repos commented 1 year ago

Ok, I am able to reproduce the error now. Its not your installation but the .so file compiled with the wrong flags. I missed that you were using PcapUtils.getHardwareAddress() call, which does reproduce the error:

/usr/lib/jvm/java-8-openjdk-amd64/bin/java: symbol lookup error: ~/lib/jnetpcap-1.4.r1425-1.linux64.x86_64/jnetpcap-1.4.r1425/libjnetpcap.so: undefined symbol: mac_addr_dlpi

Also the symbol is clearely defined and not linked:

Starship:~/lib/jnetpcap-1.4.r1425-1.linux64.x86_64/jnetpcap-1.4.r1425> nm libjnetpcap.so | grep mac_addr
                 U mac_addr_dlpi
0000000000019c38 T mac_addr_sys
slytechs-repos commented 1 year ago

Lastly, this ticket belongs under https://github.com/slytechs-repos/jnetpcap-legacy.

I'll transerfer the ticket to the correct project/repo.

Belippo commented 1 year ago

Oh ok. So should you correct and recompile to fix the bug?

slytechs-repos commented 1 year ago

I'm having trouble recompiling from source right now. I am not sure you would have any more luck. Its been many years since I've had to touch this code, but it needs to be done/refreshed for latest everything.

For now I would suggest you no use PcapUtils.getHardwareAddress and use the JDK API https://docs.oracle.com/javase/7/docs/api/java/net/NetworkInterface.html#getHardwareAddress() until I fix this.

Belippo commented 1 year ago

Ok without that function it works! Thank you, i really appreciate your support, so available...Keep it up. JNETPcap is the only updated API in java as i see. As final user i can suggest to provide high level method to craft and send packets. Keep me update if you can recompile

slytechs-repos commented 1 year ago

provide high level method to craft and send packets

This functionality is coming, again in jNetPcap Pro.

jNetPcap v2 module is pure libpcap functionality. jNetPcap Pro is the high level protocol extension to jNetPcap which adds all of the higher level functionality. This separation allows greater stability for the libpcap API and to be independent of new features which are provided by the rest of the modules.

The jNetPcap v1 (legacy) is only supported for bug fixes and won't get any additional features. When you can, I would suggest you start integrating with v2 API.

I hope that explains it.