Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[package] libpcap/1.10.4: libpcap (on Android) defaults to pcap-null.c - preventing live packet capture #25700

Closed
Deishelon opened this issue Oct 23, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@Deishelon
Copy link
Contributor

Deishelon commented Oct 23, 2024

Description

libpcap on Android defaults to pcap-null.c which prevents the live capture.

Example error:

# /data/local/tmp/NetLogger
Available interfaces:
nflog - Linux netfilter log (NFLOG) interface
nfqueue - Linux netfilter queue (NFQUEUE) interface

Error creating handle: live packet capture not supported on this system

I believe the error is how the package configures the libpcap in here:

target_os = "linux" if self.settings.os == "Linux" else "null"

It configures only Linux able to pass --with-pcap=linux to configure script. On Android this will result --with-pcap=null
Which will result in null (no-op impl) for libpcap

null-op is implemented here: https://github.com/the-tcpdump-group/libpcap/blob/5d71e580d946a8b7cf95933f64c527dafbda35db/pcap-null.c

which corresponds to error message that I see.

I believe the fix is to set --with-pcap=linux when building for Android.

diff --git a/recipes/libpcap/all/conanfile.py b/recipes/libpcap/all/conanfile.py
index 1cbe6a152..9023196f5 100644
--- a/recipes/libpcap/all/conanfile.py
+++ b/recipes/libpcap/all/conanfile.py
@@ -130,7 +130,7 @@ class LibPcapConan(ConanFile):
             if Version(self.version) < "1.10":
                 tc.configure_args.append("--disable-packet-ring")
             if cross_building(self):
-                target_os = "linux" if self.settings.os == "Linux" else "null"
+                target_os = "linux" if self.settings.os in ["Linux", "Android"] else "null"
                 tc.configure_args.append(f"--with-pcap={target_os}")
             elif "arm" in self.settings.arch and self.settings.os == "Linux":
                 tc.configure_args.append("--host=arm-linux")

I have tested this locally, and this fixes the issue, so opening this issue to submit this change.
Before:

# /data/local/tmp/NetLogger
Available interfaces:
nflog - Linux netfilter log (NFLOG) interface
nfqueue - Linux netfilter queue (NFQUEUE) interface
Error creating handle: live packet capture not supported on this system

After:
Reciper for testing created with:

~/projects/conan-center-index/recipes/libpcap$ conan create --user=nikita --channel=dev --profile:host=~/projects/redacted/profiles/android_api21_arm64-v8a.jinja --settings:host=build_type=RelWithDebInfo --build=missing --version=1.10.4 all/
# /data/local/tmp/NetLogger
Available interfaces:
eth0:LL - No description
eth0 - No description
any - Pseudo-device that captures on all interfaces
lo - No description
nflog - Linux netfilter log (NFLOG) interface
nfqueue - Linux netfilter queue (NFQUEUE) interface

Starting packet capture on can0...
Captured packet with length: 16
ID: 0x1106ff8d
DLC: 8
Data: 60 0F 13 99 FF 01 00 13

Package and Environment Details

  • Package Name/Version: libpcap/1.10.4
  • Operating System+version: Linux Ubuntu 22.04
  • Compiler+version: NDK 28.0.12433566
  • Conan version: conan 2.7.1
  • Python version: Python 3.10.12

Conan profile

======== Input profiles ========
Profile host:
[settings]
arch=armv8
build_type=RelWithDebInfo
compiler=clang
compiler.cppstd=gnu17
compiler.libcxx=c++_shared
compiler.version=8
os=Android
os.api_level=21
[conf]
tools.android:ndk_path=/home/npustovoi/Android/Sdk/ndk/28.0.12433566
[buildenv]
CHOST=arm-linux-androideabi
AR=arm-linux-androideabi-ar
AS=arm-linux-androideabi-as
RANLIB=arm-linux-androideabi-ranlib
CC=aarch64-linux-android21-clang
CXX=aarch64-linux-android21-clang++
LD=arm-linux-androideabi-ld
STRIP=arm-linux-androideabi-strip
ANDROID_PLATFORM=21
ANDROID_ABI=arm64-v8a

Profile build:
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=11
os=Linux

Steps to reproduce

CONAN_NDK_PATH=~/Android/Sdk/ndk/20.1.5948944  conan install conanfile.py --profile:host=android_api21_arm64-v8a.jinja --output-folder=conan_build/RelWithDebInfo/arm64-v8a, --build=missing --settings:host=build_type=RelWithDebInfo --conf:host=tools.android:ndk_path=~/Android/Sdk/ndk/20.1.5948944 

Compile sample binary with NDK for Android to capture traffic, eg:

#include <iostream>
#include <pcap/pcap.h>
#include <net/if.h>
#include <linux/can.h>

int main() {
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_if_t *alldevs;

    if (pcap_findalldevs(&alldevs, errbuf) == -1) {
        std::cerr << "Error finding devices: " << errbuf << std::endl;
        return 1;
    }

    std::cout << "Available interfaces:" << std::endl;
    for (pcap_if_t *d = alldevs; d != nullptr; d = d->next) {
        std::cout << d->name << " - " << (d->description ? d->description : "No description") << std::endl;
    }

    pcap_t *handle = pcap_create("can0", errbuf);
    if (handle == nullptr) {
        std::cerr << "Error creating handle: " << errbuf << std::endl;
        pcap_freealldevs(alldevs);
        return 1;
    }

    if (pcap_set_promisc(handle, 1) != 0) {
        std::cerr << "Error setting promiscuous mode" << std::endl;
        pcap_close(handle);
        pcap_freealldevs(alldevs);
        return 1;
    }

    if (pcap_set_timeout(handle, 1000) != 0) {
        std::cerr << "Error setting timeout" << std::endl;
        pcap_close(handle);
        pcap_freealldevs(alldevs);
        return 1;
    }

    if (pcap_set_buffer_size(handle, 65536) != 0) {
        std::cerr << "Error setting buffer size" << std::endl;
        pcap_close(handle);
        pcap_freealldevs(alldevs);
        return 1;
    }

    int status = pcap_activate(handle);
    if (status < 0) {
        std::cerr << "Error activating handle: " << pcap_statustostr(status) << std::endl;
        pcap_close(handle);
        pcap_freealldevs(alldevs);
        return 1;
    }

    pcap_freealldevs(alldevs);

    std::cout << "Starting packet capture on can0..." << std::endl;

    struct pcap_pkthdr header;
    const u_char *packet;

    while ((packet = pcap_next(handle, &header)) != nullptr) {
        struct can_frame *frame = (struct can_frame *)packet;

        std::cout << "Captured packet with length: " << header.len << std::endl;
        std::cout << "ID: 0x" << std::hex << frame->can_id << std::dec << std::endl;
        std::cout << "DLC: " << (int)frame->can_dlc << std::endl;
        std::cout << "Data: ";

        for (int i = 0; i < frame->can_dlc; i++) {
            printf("%02X ", frame->data[i]);
        }
        std::cout << std::endl << std::endl;
    }

    pcap_close(handle);
    return 0;
}

Logs

Click to expand log
Available interfaces:
nflog - Linux netfilter log (NFLOG) interface
nfqueue - Linux netfilter queue (NFQUEUE) interface
Error creating handle: live packet capture not supported on this system
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant