seladb / PcapPlusPlus

PcapPlusPlus is a multiplatform C++ library for capturing, parsing and crafting of network packets. It is designed to be efficient, powerful and easy to use. It provides C++ wrappers for the most popular packet processing engines such as libpcap, Npcap, WinPcap, DPDK, AF_XDP and PF_RING.
https://pcapplusplus.github.io/
The Unlicense
2.64k stars 640 forks source link

About fatal bugs on the aarch64 platform #732

Closed ghost closed 2 years ago

ghost commented 2 years ago

This tool is very easy to use, but there is currently no aarch64 linux support version. I hope to add cross-compilation and run on the target aarch64 Linux platform.

ghost commented 2 years ago

I tried to compile on Pi 4b aarch64(Pi OS 64bit). Although it can compile normally without error, it can't run normally after compiling! , Such as TcpSorter is a good example:

Normally, when the build target is linux x64 on the linux x64 platform, the operation is normal, such as:

ubuntu@ubuntu:~/Desktop/PacketSorter/build$ uname -m
x86_64
ubuntu@ubuntu:~/Desktop/PacketSorter/build$ sudo HttpAnalyzer -i eno1

Current HTTP rates
--------------------

Rate of HTTP packets:                             0.000 [Packets/sec]
Rate of HTTP flows:                               0.000 [Flows/sec]
Rate of HTTP transactions:                        0.000 [Transactions/sec]
Rate of HTTP data:                                0.000 [Bytes/sec]
Rate of HTTP requests:                            0.000 [Requests/sec]
Rate of HTTP responses:                           0.000 [Responses/sec]

Current HTTP rates
--------------------

Rate of HTTP packets:                             0.000 [Packets/sec]
Rate of HTTP flows:                               0.000 [Flows/sec]
Rate of HTTP transactions:                        0.000 [Transactions/sec]
Rate of HTTP data:                                0.000 [Bytes/sec]
Rate of HTTP requests:                            0.000 [Requests/sec]
Rate of HTTP responses:                           0.000 [Responses/sec]

But it is also compiled in the same way on Raspberry Pi 4b:

apt install make g++ libpcap-dev

./configure-linux.sh --default
make all
sudo make install

In the end, it was very embarrassing and unexpected that after compiling on Pi 4b, executing TcpSorter (at this time aarch64) failed to run normally, but infinitely prompted a Usage help panel:

pi@raspberrypi:~/PacketSorter/build $ uname -m
aarch64
pi@raspberrypi:~/PacketSorter/build $ sudo HttpAnalyzer -l

Network interfaces:
    -> Name: 'eth0'   IP address: 192.168.31.41
    -> Name: 'any'   IP address: 0.0.0.0
    -> Name: 'lo'   IP address: 127.0.0.1
    -> Name: 'wlan0'   IP address: 0.0.0.0
    -> Name: 'bluetooth0'   IP address: 0.0.0.0
    -> Name: 'nflog'   IP address: 0.0.0.0
    -> Name: 'nfqueue'   IP address: 0.0.0.0
    -> Name: 'usbmon1'   IP address: 0.0.0.0
pi@raspberrypi:~/PacketSorter/build $ sudo HttpAnalyzer i eth0

Usage: PCAP file mode:
----------------------
HttpAnalyzer [-vh] -f input_file

Options:

    -f           : The input pcap/pcapng file to analyze. Required argument for this mode
    -v             : Displays the current version and exists
    -h           : Displays this help message and exits

Usage: Live traffic mode:
-------------------------
HttpAnalyzer [-hvld] [-o output_file] [-r calc_period] -i interface

Options:

    -i interface   : Use the specified interface. Can be interface name (e.g eth0) or interface IPv4 address
    -o output_file : Save all captured HTTP packets to a pcap file. Notice this may cause performance degradation
    -r calc_period : The period in seconds to calculate rates. If not provided default is 2 seconds
    -d             : Disable periodic rates calculation
    -h             : Displays this help message and exits
    -v             : Displays the current version and exists
    -l             : Print the list of interfaces and exists

Similarly, I moved the compiled PcapPlusPlus to openwrt of aarch64, and the same bug occurred.

root@OpenWrt:~# uname -m
aarch64
root@OpenWrt:~# 
root@OpenWrt:~# ./HttpAnalyzer -l

Network interfaces:
    -> Name: 'eth0'   IP address: 0.0.0.0
    -> Name: 'wlan0'   IP address: 0.0.0.0
    -> Name: 'br-lan'   IP address: 192.168.31.10
    -> Name: 'any'   IP address: 0.0.0.0
    -> Name: 'lo'   IP address: 127.0.0.1
    -> Name: 'docker0'   IP address: 172.17.0.1
    -> Name: 'bluetooth-monitor'   IP address: 0.0.0.0
    -> Name: 'nflog'   IP address: 0.0.0.0
    -> Name: 'nfqueue'   IP address: 0.0.0.0
root@OpenWrt:~# 
root@OpenWrt:~# ./HttpAnalyzer -i eth0

Usage: PCAP file mode:
----------------------
HttpAnalyzer [-vh] -f input_file

Options:

    -f           : The input pcap/pcapng file to analyze. Required argument for this mode
    -v             : Displays the current version and exists
    -h           : Displays this help message and exits

Usage: Live traffic mode:
-------------------------
HttpAnalyzer [-hvld] [-o output_file] [-r calc_period] -i interface

Options:

    -i interface   : Use the specified interface. Can be interface name (e.g eth0) or interface IPv4 address
    -o output_file : Save all captured HTTP packets to a pcap file. Notice this may cause performance degradation
    -r calc_period : The period in seconds to calculate rates. If not provided default is 2 seconds
    -d             : Disable periodic rates calculation
    -h             : Displays this help message and exits
    -v             : Displays the current version and exists
    -l             : Print the list of interfaces and exists

I hope the author can fix this bug, I don’t know what caused it at the moment

ghost commented 2 years ago
F8197333-2425-4566-B6CF-33CC741E57DB 342C4925-EB5C-434E-87E7-115DCCA53377
seladb commented 2 years ago

@inSilo please correct me if I'm wrong, but I think your command is missing the - character before the i argument, it should be:

root@OpenWrt:~# ./HttpAnalyzer -i eth0
ghost commented 2 years ago

please correct me if I'm wrong, but I think your command is missing the - character before the i argument, it should be:

F3DBF57A-7ABE-42AB-94E1-BD1A78385365

This seems to be a problem with getopt_long function! ! I am on aarch64, the getopt_long does have this problem! Instead of parameter missing-character

ghost commented 2 years ago

@inSilo please correct me if I'm wrong, but I think your command is missing the - character before the i argument, it should be:

root@OpenWrt:~# ./HttpAnalyzer -i eth0

You may have misunderstood me. On aarch64, the getopt_long function seems to read garbled characters, but the garbled characters are not what I specified! The best way is that you are on the aarch64 platform, and the restoring process will be clear!

@inSilo please correct me if I'm wrong, but I think your command is missing the - character before the i argument, it should be:

root@OpenWrt:~# ./HttpAnalyzer -i eth0

Tested on openwrt, I did miss "-", but if I add "-", it is the same error! The current preliminary judgment is a problem with the getopt_long function

seladb commented 2 years ago

getopt_long is a part of GNU: https://www.gnu.org/software/libc/manual/html_node/Getopt-Long-Options.html

Do you know of any specific issue it has on aarch64? Unfortunately I don't have a aarch64 device so I can't test it...

ghost commented 2 years ago

getopt_long is a part of GNU: https://www.gnu.org/software/libc/manual/html_node/Getopt-Long-Options.html

Do you know of any specific issue it has on aarch64? Unfortunately I don't have a aarch64 device so I can't test it...

137068898-d3a7169a-f74f-431e-bb59-69dfae364c2b 137069115-e0378dc9-f52f-4f99-99fb-ca3e8b5d0a2a

In aarch64, there are garbled characters in the opt variable acquisition. According to reason, this will not appear.

seladb commented 2 years ago

According to reason, this will not appear.

I'm not sure I understand... I do understand that there is an issue with getopt_long on aarch64 but I'm not sure why it happens and how to fix it

ghost commented 2 years ago
while((opt = getopt_long(argc, argv, "i:r:o:e:f:p:t:n:d:g:svhlx", TcpSorterOptions, &optionIndex)) != -1) {
    switch (opt) {
    }
}

E.g: sudo ./bin/Packet Shorter -i eth0 -o /home/pi/Desktop/tcpsorter -x -p 16. On the x86_64 platform, opt variable only getsi, o, ,x,p.But it’s different on aarch64, there is an extra "�", which becomes i,o,x, p,

seladb commented 2 years ago

I think I found a similar issue in some other project: https://github.com/wg/wrk/issues/87

The fix was to define opt as an int instead of char: https://github.com/wg/wrk/commit/b8431944edfd122f91ab8879a8d9c3f29a7d880c#diff-8f28ea08d2b754de6ba485bb5a3da17434336407cb9ab13b786bc4f82490014d

Can you check if that solves the problem?

ghost commented 2 years ago

I think I found a similar issue in some other project: wg/wrk#87

The fix was to define opt as an int instead of char: wg/wrk@b843194#diff-8f28ea08d2b754de6ba485bb5a3da17434336407cb9ab13b786bc4f82490014d

Can you check if that solves the problem?

AA31F784-76C2-4E04-84BB-908ED88D8E8F

Yes, if you change it to int type, the problem is fixed and resolved!

seladb commented 2 years ago

Thanks for checking! Would you consider opening a PR with the fix?

ghost commented 2 years ago

Thanks for checking! Would you consider opening a PR with the fix?

You are welcome, you can correct it, after all, this problem is a minor problem. This problem may only occur in aarch64。 But I suggest that the project can be cross-compiled to aarch64 version, first compile libpcap, and then cross-compile to aarach64 through aarch64-linux-gnu-g++。

Or clang++,For example: platform.mk.linux.aarch64

...
CXX := clang++
CC := clang
AR := llvm-ar
....
GLOBAL_FLAGS := --target=aarch64-linux-gnu
seladb commented 2 years ago

You are welcome, you can correct it, after all, this problem is a minor problem. This problem may only occur in aarch64

Sure, I can make the fix

But I suggest that the project can be cross-compiled to aarch64 version, first compile libpcap, and then cross-compile to aarach64 through aarch64-linux-gnu-g++。

Or clang++,For example: platform.mk.linux.aarch64

...
CXX := clang++
CC := clang
AR := llvm-ar
....
GLOBAL_FLAGS := --target=aarch64-linux-gnu

Here I need your help because I don't have a lot of experience with aarch64. I just saw that CirrusCI supports Arm containers so we may be able to run it there: https://cirrus-ci.org/guide/linux/ Will you be able to help?

ghost commented 2 years ago

You are welcome, you can correct it, after all, this problem is a minor problem. This problem may only occur in aarch64

Sure, I can make the fix

But I suggest that the project can be cross-compiled to aarch64 version, first compile libpcap, and then cross-compile to aarach64 through aarch64-linux-gnu-g++。 Or clang++,For example: platform.mk.linux.aarch64

...
CXX := clang++
CC := clang
AR := llvm-ar
....
GLOBAL_FLAGS := --target=aarch64-linux-gnu

Here I need your help because I don't have a lot of experience with aarch64. I just saw that CirrusCI supports Arm containers so we may be able to run it there: https://cirrus-ci.org/guide/linux/ Will you be able to help?

I recommend cross-compiling to aarch64 through x86_64 without compiling on a specific arm64 host platform.

ghost commented 2 years ago

You are welcome, you can correct it, after all, this problem is a minor problem. This problem may only occur in aarch64

Sure, I can make the fix

But I suggest that the project can be cross-compiled to aarch64 version, first compile libpcap, and then cross-compile to aarach64 through aarch64-linux-gnu-g++。 Or clang++,For example: platform.mk.linux.aarch64

...
CXX := clang++
CC := clang
AR := llvm-ar
....
GLOBAL_FLAGS := --target=aarch64-linux-gnu

Here I need your help because I don't have a lot of experience with aarch64. I just saw that CirrusCI supports Arm containers so we may be able to run it there: https://cirrus-ci.org/guide/linux/ Will you be able to help?

Also, I suggest that your project be compiled directly with the libpcap source code, so that it can be compiled for cross-platform use. (After all, I see that the official Android build has to manually specify the path of the libpcap source, which is extremely inconvenient), the above is my suggestion.

Which version of my warehouse is relatively old, because some of my old projects still use the old version of the header file dependency,but the cross-compilation ideas provided therein can be used for reference . If the author agrees with my approach, can the project be modified according to this idea?

seladb commented 2 years ago

Also, I suggest that your project be compiled directly with the libpcap source code, so that it can be compiled for cross-platform use. (After all, I see that the official Android build has to manually specify the path of the libpcap source, which is extremely inconvenient), the above is my suggestion.

Thanks for your suggestion, but I don't think PcapPlusPlus should be compiled with libpcap source code for a number of reasons:

Android is indeed a unique use case, but I don't think we should follow this pattern on all platforms.

Which version of my warehouse is relatively old, because some of my old projects still use the old version of the header file dependency,but the cross-compilation ideas provided therein can be used for reference, TyraProdoehl/PcapPlusPlus@649e66a TyraProdoehl/PcapPlusPlus@ea823e3 . If the author agrees with my approach, can the project be modified according to this idea?

I took a quick on these commits. I agree with the approach of adding platform.mk.linux.aarch64 and integrating it into configure-linux.sh, but would avoid the part that compiles libpcap. Would you consider opening a PR with these changes?

seladb commented 2 years ago

@inSilo the bugfix has been merged to master in this commit: https://github.com/seladb/PcapPlusPlus/commit/df2a1200e61ba145170a67f649d826dfa83c2d5b

I suggest we close this issue and open a new one to discuss the aarch64 support. I'll open it