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*