0

I wrote a c function to call libpcap, and compile it to .dylib

#include "capture.h"
#include <stdio.h>
#include <pcap.h>

int run_capture(const char * dev) {
    printf("start capture\n");
    pcap_t* pcap;
    const u_char* pkt;
    struct pcap_pkthdr ph;
    char ebuf[PCAP_ERRBUF_SIZE];
    pcap = pcap_open_live(dev, 65535, 0, 0, ebuf);
    if (!pcap) {
        fprintf(stderr, "%s\n", ebuf);
        return -1;
    }

    pcap_dumper_t *dumper = pcap_dump_open(pcap, "./cap.pcap");

    if (pcap_loop(pcap, 2000, &pcap_dump, (u_char *)dumper) < 0) {
        /*
            * Print out appropriate text, followed by the error message
            * generated by the packet capture library.
            */
        printf("Error reading packets from interface %s", "en0");
        return 8;
    }

    pcap_dump_flush(dumper);
    pcap_dump_close(dumper);
    pcap_close(pcap);

    printf("stoped capture\n");
    return 0;
}

dart ffi binding code:

import 'dart:ffi' as ffi;

import 'package:ffi/ffi.dart';

typedef run_capture_native_t = ffi.Int Function(ffi.Pointer<Utf8> dev);
typedef run_capture_t        = int Function(ffi.Pointer<Utf8> dev);

final dylib = ffi.DynamicLibrary.open('libpacket_worker.dylib');

final runCapture = dylib.lookupFunction<run_capture_native_t, run_capture_t>('run_capture');

main.dart code

import 'dart:ffi' as ffi;
import 'dart:isolate';
import 'libpcap/libpcap_bindings.dart';
import 'packet_worker/packet_worker_bindings.dart';
import 'dart:io' show Platform, Directory;
import 'package:ffi/ffi.dart';

// Define the function type for inet_ntoa()
typedef inet_ntoa_native_t = ffi.Pointer<Utf8> Function(ffi.Pointer<in_addr>);
typedef inet_ntoa_t = ffi.Pointer<Utf8> Function(ffi.Pointer<in_addr>);

int main(List<String> args) {
  final recvPort = ReceivePort();
  final worker = Isolate.spawn((message) {
    runCapture("en0".toNativeUtf8());
  }, recvPort.sendPort);
  print("Isolate spawnd.");
  return 0;
}

it works fine and output a .pcap file

lake@LakedeMBP dart_pcap_test % dart compile exe main.dart -o sniff
Info: Compiling with sound null safety
Generated: /Users/lake/Projects/dart_pcap_test/sniff
lake@LakedeMBP dart_pcap_test % ./sniff 
Isolate spawnd.
start capture
stoped capture
^C
lake@LakedeMBP dart_pcap_test % ls
cap.pcap                libpcap                 packet_worker           pubspec.yaml
libpacket_worker.dylib  main.dart               pubspec.lock            sniff
lake@LakedeMBP dart_pcap_test % ls -al
total 11816
-rw-r--r--   1 lake  staff   886300 Jan 22 01:58 cap.pcap
-rwxr-xr-x   1 lake  staff    34035 Jan 22 01:12 libpacket_worker.dylib
drwxr-xr-x  11 lake  staff      352 Jan 20 23:03 libpcap
-rw-r--r--   1 lake  staff      624 Jan 21 22:39 main.dart
drwxr-xr-x   9 lake  staff      288 Jan 21 22:09 packet_worker
-rw-r--r--   1 lake  staff     8261 Jan  9 15:35 pubspec.lock
-rw-r--r--   1 lake  staff      516 Jan  9 15:35 pubspec.yaml
-rwxr-xr-x   1 lake  staff  5063216 Jan 22 01:57 sniff

But it have permission problem when i move the same code to flutter project:

lake@LakedeMBP MacOS % ./flutter_pcap_test
flutter: err: en0: (cannot open BPF device) /dev/bpf0: Operation not permitted

I don't know why. I upload the 2 samples to Github, Any one can help me? environment: Macbook M1

Dart Proj that works fine: https://github.com/dev-lake/dart_pcap_test

Flutter Proj that have permittion problem: https://github.com/dev-lake/flutter_pcap_test

I Have tried: chmod 777 /dev/bpf*

Lake
  • 11
  • 3

0 Answers0