From 2ea12299386af0548f61ae88f1316919724a4e7e Mon Sep 17 00:00:00 2001 From: emanuele-f Date: Thu, 20 Jan 2022 12:05:31 +0100 Subject: [PATCH] Add pcap_reader and blacklist tests The pcap_reader can be used to test the native PCAPdroid implementation. Native tests can be run with run_tests.sh --- app/src/main/jni/CMakeLists.txt | 4 + app/src/main/jni/common/utils.c | 5 +- app/src/main/jni/core/CMakeLists.txt | 2 - app/src/main/jni/core/blacklist.c | 19 ++++- app/src/main/jni/core/blacklist.h | 1 + app/src/main/jni/core/capture_root.c | 39 +++++----- app/src/main/jni/core/jni_impl.c | 4 +- app/src/main/jni/core/pcapdroid.c | 6 ++ app/src/main/jni/core/pcapdroid.h | 7 +- app/src/main/jni/pcapd/pcapd.c | 52 ++++++++----- app/src/main/jni/tests/CMakeLists.txt | 32 ++++++++ app/src/main/jni/tests/blacklist.c | 59 +++++++++++++++ app/src/main/jni/tests/pcap_reader.c | 104 ++++++++++++++++++++++++++ app/src/main/jni/tests/run_tests.sh | 4 + app/src/main/jni/tests/test_utils.c | 90 ++++++++++++++++++++++ app/src/main/jni/tests/test_utils.h | 38 ++++++++++ 16 files changed, 422 insertions(+), 44 deletions(-) create mode 100644 app/src/main/jni/tests/CMakeLists.txt create mode 100644 app/src/main/jni/tests/blacklist.c create mode 100644 app/src/main/jni/tests/pcap_reader.c create mode 100755 app/src/main/jni/tests/run_tests.sh create mode 100644 app/src/main/jni/tests/test_utils.c create mode 100644 app/src/main/jni/tests/test_utils.h diff --git a/app/src/main/jni/CMakeLists.txt b/app/src/main/jni/CMakeLists.txt index 14512bfa..74f47613 100644 --- a/app/src/main/jni/CMakeLists.txt +++ b/app/src/main/jni/CMakeLists.txt @@ -13,6 +13,10 @@ set(ZDTUN_ROOT ${ROOTDIR}/submodules/zdtun) include_directories(${ZDTUN_ROOT}) add_subdirectory(${ZDTUN_ROOT} zdtun_build) +# nDPI +set(NDPI_ROOT ${ROOTDIR}/submodules/nDPI) +include_directories(${NDPI_ROOT}/src/include ${NDPI_ROOT}/src/lib/third_party/include) + # base include_directories(${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/app/src/main/jni/common/utils.c b/app/src/main/jni/common/utils.c index c4bbb364..f72492df 100644 --- a/app/src/main/jni/common/utils.c +++ b/app/src/main/jni/common/utils.c @@ -108,6 +108,7 @@ ssize_t xwrite(int fd, const void *buf, size_t count) { /* ******************************************************* */ +// returns < 0 on error, 0 if fd is closed ssize_t xread(int fd, void *buf, size_t count) { size_t sofar = 0; ssize_t rv; @@ -125,9 +126,9 @@ ssize_t xread(int fd, void *buf, size_t count) { } while((sofar != count) && (rv != 0)); if(sofar != count) - return -1; + return (rv == 0) ? 0 : -1; - return 0; + return count; } /* ******************************************************* */ diff --git a/app/src/main/jni/core/CMakeLists.txt b/app/src/main/jni/core/CMakeLists.txt index 949c2649..173fa906 100644 --- a/app/src/main/jni/core/CMakeLists.txt +++ b/app/src/main/jni/core/CMakeLists.txt @@ -12,9 +12,7 @@ add_library(capture SHARED jni_impl.c) # nDPI -set(NDPI_ROOT ${ROOTDIR}/submodules/nDPI) add_definitions(-DNDPI_LIB_COMPILATION) -include_directories(${NDPI_ROOT}/src/include ${NDPI_ROOT}/src/lib/third_party/include) AUX_SOURCE_DIRECTORY(${NDPI_ROOT}/src/lib ndpiSources) AUX_SOURCE_DIRECTORY(${NDPI_ROOT}/src/lib/third_party/src ndpiSources) AUX_SOURCE_DIRECTORY(${NDPI_ROOT}/src/lib/protocols ndpiSources) diff --git a/app/src/main/jni/core/blacklist.c b/app/src/main/jni/core/blacklist.c index 773d2dc6..ea501af4 100644 --- a/app/src/main/jni/core/blacklist.c +++ b/app/src/main/jni/core/blacklist.c @@ -253,6 +253,23 @@ bool blacklist_match_ip(blacklist_t *bl, const zdtun_ip_t *ip, int ipver) { /* ******************************************************* */ +bool blacklist_match_ipstr(blacklist_t *bl, const char *ip_str) { + ndpi_ip_addr_t addr; + int ipver = ndpi_parse_ip_string(ip_str, &addr); + zdtun_ip_t ip; + + if(ipver == 4) + ip.ip4 = addr.ipv4; + else if(ipver == 6) + memcpy(&ip.ip6, &addr.ipv6, 16); + else + return false; + + return blacklist_match_ip(bl, &ip, ipver); +} + +/* ******************************************************* */ + bool blacklist_match_domain(blacklist_t *bl, const char *domain) { string_entry_t *entry = NULL; @@ -337,4 +354,4 @@ int blacklist_load_list_descriptor(blacklist_t *bl, JNIEnv *env, jobject ld) { return 0; } -#endif // ANDROID \ No newline at end of file +#endif // ANDROID diff --git a/app/src/main/jni/core/blacklist.h b/app/src/main/jni/core/blacklist.h index 4ffcfdcf..1fefa8f9 100644 --- a/app/src/main/jni/core/blacklist.h +++ b/app/src/main/jni/core/blacklist.h @@ -76,6 +76,7 @@ int blacklist_load_file(blacklist_t *bl, const char *path, blacklist_type btype, int blacklist_load_list_descriptor(blacklist_t *bl, JNIEnv *env, jobject ld); #endif bool blacklist_match_ip(blacklist_t *bl, const zdtun_ip_t *ip, int ipver); +bool blacklist_match_ipstr(blacklist_t *bl, const char *ip); bool blacklist_match_domain(blacklist_t *bl, const char *domain); bool blacklist_match_uid(blacklist_t *bl, int uid); void blacklist_get_stats(const blacklist_t *bl, blacklists_stats_t *stats); diff --git a/app/src/main/jni/core/capture_root.c b/app/src/main/jni/core/capture_root.c index 4c3e5e48..65ed0795 100644 --- a/app/src/main/jni/core/capture_root.c +++ b/app/src/main/jni/core/capture_root.c @@ -45,7 +45,7 @@ struct pcap_conn { /* ******************************************************* */ -static int su_cmd(const char *prog, const char *args, bool check_error) { +static int run_cmd(const char *prog, const char *args, bool as_root, bool check_error) { int in_p[2], out_p[2]; int rv = -1; pid_t pid; @@ -57,7 +57,7 @@ static int su_cmd(const char *prog, const char *args, bool check_error) { if((pid = fork()) == 0) { // child - char *argp[] = {"sh", "-c", "su", NULL}; + char *argp[] = {"sh", "-c", as_root ? "su" : "sh", NULL}; close(in_p[1]); close(out_p[0]); @@ -76,7 +76,7 @@ static int su_cmd(const char *prog, const char *args, bool check_error) { close(out_p[1]); // write "su" command input - log_d("su_cmd[%d]: %s %s", pid, prog, args); + log_d("run_cmd[%d]: %s %s", pid, prog, args); write(in_p[1], prog, strlen(prog)); write(in_p[1], " ", 1); write(in_p[1], args, strlen(args)); @@ -133,7 +133,7 @@ static void kill_pcapd(pcapdroid_t *nc) { if(pid != 0) { log_d("Killing old pcapd with pid %d", pid); - su_cmd("kill", pid_s, false); + run_cmd("kill", pid_s, true, false); } fclose(f); @@ -144,15 +144,8 @@ static void kill_pcapd(pcapdroid_t *nc) { static int connectPcapd(pcapdroid_t *pd) { int sock; int client = -1; - char bpf[256]; char pcapd[PATH_MAX]; - char capture_interface[16] = "@inet"; - bpf[0] = '\0'; - -#if ANDROID - getStringPref(pd, "getPcapDumperBpf", bpf, sizeof(bpf)); - getStringPref(pd, "getCaptureInterface", capture_interface, sizeof(capture_interface)); -#endif + char *bpf = pd->root.bpf ? pd->root.bpf : ""; if(pd->cb.get_libprog_path) pd->cb.get_libprog_path(pd, "pcapd", pcapd, sizeof(pcapd)); @@ -198,8 +191,8 @@ static int connectPcapd(pcapdroid_t *pd) { // Start the daemon char args[256]; - snprintf(args, sizeof(args), "-l pcapd.log -i %s -d -u %d -t -b \"%s\"", capture_interface, pd->app_filter, bpf); - if(su_cmd(pcapd, args, true) != 0) + snprintf(args, sizeof(args), "-l pcapd.log -i %s -d -u %d -t -b \"%s\"", pd->root.capture_interface, pd->app_filter, bpf); + if(run_cmd(pcapd, args, pd->root.as_root, true) != 0) goto cleanup; // Wait for pcapd to start @@ -497,6 +490,16 @@ int run_root(pcapdroid_t *pd) { u_int64_t next_purge_ms; zdtun_callbacks_t callbacks = {.send_client = (void*)1}; +#if ANDROID + char capture_interface[16] = "@inet"; + char bpf[256]; + bpf[0] = '\0'; + + pd->root.as_root = true; // TODO support read from PCAP file + pd->root.bpf = getStringPref(pd, "getPcapDumperBpf", bpf, sizeof(bpf)); + pd->root.capture_interface = getStringPref(pd, "getCaptureInterface", capture_interface, sizeof(capture_interface)); +#endif + if((pd->zdt = zdtun_init(&callbacks, NULL)) == NULL) return(-1); @@ -531,15 +534,17 @@ int run_root(pcapdroid_t *pd) { if(!FD_ISSET(sock, &fdset)) goto housekeeping; - if(xread(sock, &hdr, sizeof(hdr)) < 0) { - log_e("read hdr from pcapd failed[%d]: %s", errno, strerror(errno)); + ssize_t xrv = xread(sock, &hdr, sizeof(hdr)); + if(xrv != sizeof(hdr)) { + if(xrv < 0) + log_e("read hdr from pcapd failed[%d]: %s", errno, strerror(errno)); goto cleanup; } if(hdr.len > sizeof(buffer)) { log_e("packet too big (%d B)", hdr.len); goto cleanup; } - if(xread(sock, buffer, hdr.len) < 0) { + if(xread(sock, buffer, hdr.len) != hdr.len) { log_e("read %d B packet from pcapd failed[%d]: %s", hdr.len, errno, strerror(errno)); goto cleanup; } diff --git a/app/src/main/jni/core/jni_impl.c b/app/src/main/jni/core/jni_impl.c index 236ac8f2..c1a7e3ed 100644 --- a/app/src/main/jni/core/jni_impl.c +++ b/app/src/main/jni/core/jni_impl.c @@ -473,10 +473,8 @@ Java_com_emanuelef_remote_1capture_CaptureService_runPacketLoop(JNIEnv *env, jcl .notify_service_status = notifyServiceStatus, .notify_blacklists_loaded = notifyBlacklistsLoaded, }, - .ip_to_host = ip_lru_init(MAX_HOST_LRU_SIZE), .app_filter = getIntPref(env, vpn, "getAppFilterUid"), .root_capture = (bool) getIntPref(env, vpn, "isRootCapture"), - .new_conn_id = 0, .pcap_dump = { .enabled = (bool) getIntPref(env, vpn, "pcapDumpEnabled"), }, @@ -792,4 +790,4 @@ void getApplicationByUid(pcapdroid_t *pd, jint uid, char *buf, int bufsize) { if(obj) (*env)->DeleteLocalRef(env, obj); } -#endif // ANDROID \ No newline at end of file +#endif // ANDROID diff --git a/app/src/main/jni/core/pcapdroid.c b/app/src/main/jni/core/pcapdroid.c index 7c20286c..90399919 100644 --- a/app/src/main/jni/core/pcapdroid.c +++ b/app/src/main/jni/core/pcapdroid.c @@ -1039,6 +1039,8 @@ int pd_run(pcapdroid_t *pd) { return(-1); } + pd->ip_to_host = ip_lru_init(MAX_HOST_LRU_SIZE); + if(pd->malware_detection.enabled && pd->cb.load_blacklists_info) pd->cb.load_blacklists_info(pd); @@ -1075,6 +1077,10 @@ int pd_run(pcapdroid_t *pd) { log_d("Stopped packet loop"); + // send last dump + if(pd->cb.send_connections_dump) + pd->cb.send_connections_dump(pd); + conns_clear(&pd->new_conns, true); conns_clear(&pd->conns_updates, true); diff --git a/app/src/main/jni/core/pcapdroid.h b/app/src/main/jni/core/pcapdroid.h index 06a38e5a..d662af46 100644 --- a/app/src/main/jni/core/pcapdroid.h +++ b/app/src/main/jni/core/pcapdroid.h @@ -138,7 +138,7 @@ struct pcapdroid; // Used to decouple pcapdroid.c from the JNI calls typedef struct { void (*get_libprog_path)(struct pcapdroid *pd, const char *prog_name, char *buf, int bufsize); - int (*load_blacklists_info)(struct pcapdroid *pd); + int (*load_blacklists_info)(struct pcapdroid *pd); void (*send_stats_dump)(struct pcapdroid *pd); void (*send_connections_dump)(struct pcapdroid *pd); void (*send_pcap_dump)(struct pcapdroid *pd); @@ -193,7 +193,10 @@ typedef struct pcapdroid { } vpn; struct { pcap_conn_t *connections; - } root; + bool as_root; + char *bpf; + char *capture_interface; + } root; // TODO rename: it can run without root to read a PCAP file }; struct { diff --git a/app/src/main/jni/pcapd/pcapd.c b/app/src/main/jni/pcapd/pcapd.c index 060fe7bb..5f4e4db9 100644 --- a/app/src/main/jni/pcapd/pcapd.c +++ b/app/src/main/jni/pcapd/pcapd.c @@ -73,6 +73,7 @@ typedef struct { char name[IFNAMSIZ]; int ifidx; uint8_t ifid; // positional interface index + uint8_t is_file; pcap_t *pd; int pf; int dlink; @@ -395,22 +396,28 @@ static void init_interface(pcapd_iface_t *iface) { static int open_interface(pcapd_iface_t *iface, pcapd_runtime_t *rt, const char *ifname, int ifid) { #ifndef READ_FROM_PCAP + int is_file = 0; int mtu = get_iface_mtu(ifname); - if(mtu < 0) { - mtu = 1500; - log_w("Could not get \"%s\" interface MTU, assuming %d", ifname, mtu); - } - /* The snaplen includes the datalink overhead. Max datalink overhead (SLL2): 20 B */ int snaplen = mtu + SLL2_HDR_LEN; - log_d("Using a %d snaplen (MTU %d)", snaplen, mtu); pcap_t *pd = pcap_open_live(ifname, snaplen, 0, 1, errbuf); - if(!pd) { - log_i("pcap_open_live(%s) failed: %s", ifname, errbuf); - return -1; + // try to open as file + pd = pcap_open_offline(ifname, errbuf); + + if(!pd) { + log_i("pcap_open(%s) failed: %s", ifname, errbuf); + return -1; + } + is_file = 1; + } else { + if(mtu < 0) { + mtu = 1500; + log_w("Could not get \"%s\" interface MTU, assuming %d", ifname, mtu); + } + log_d("Using a %d snaplen (MTU %d)", snaplen, mtu); } // Fixes pcap_next_ex sometimes hanging on interface down @@ -479,20 +486,21 @@ static int open_interface(pcapd_iface_t *iface, pcapd_runtime_t *rt, const char // Success iface->pd = pd; + iface->is_file = is_file; iface->mac = 0; iface->ifid = ifid; iface->ifidx = if_nametoindex(ifname); errno = 0; - if((dlink == DLT_EN10MB) && (get_iface_mac(ifname, &iface->mac) < 0)) + if(!is_file && (dlink == DLT_EN10MB) && (get_iface_mac(ifname, &iface->mac) < 0)) log_i("Could not get interface \"%s\" MAC[%d]: %s", ifname, errno, strerror(errno)); uint32_t netmask; iface->ip = 0; - if(get_iface_ip(ifname, &iface->ip, &netmask) < 0) + if(!is_file && get_iface_ip(ifname, &iface->ip, &netmask) < 0) log_i("Could not get interface \"%s\" IP[%d]: %s", ifname, errno, strerror(errno)); - if(get_iface_ip6(ifname, &iface->ip6) < 0) { + if(!is_file && get_iface_ip6(ifname, &iface->ip6) < 0) { log_i("Could not get interface \"%s\" IPv6[%d]: %s", ifname, errno, strerror(errno)); memset(&iface->ip6, 0, sizeof(iface->ip6)); } @@ -744,9 +752,12 @@ static int read_pkt(pcapd_runtime_t *rt, pcapd_iface_t *iface, time_t now) { // abort, resuming other interfaces is not supported yet return -1; + } else if(rv != 1) { + // TODO handle EOF without error + return -1; } - if((rv == 1) && (hdr->caplen >= to_skip)) { + if(hdr->caplen >= to_skip) { pcapd_hdr_t phdr; zdtun_pkt_t zpkt; int len = hdr->caplen; @@ -764,11 +775,15 @@ static int read_pkt(pcapd_runtime_t *rt, pcapd_iface_t *iface, time_t now) { tupleSwapPeers(&zpkt.tuple); } - int uid = uid_lru_find(rt->lru, &zpkt.tuple); + int uid = UID_UNKNOWN; - if(uid == -2) { - uid = get_uid(rt->resolver, &zpkt.tuple); - uid_lru_add(rt->lru, &zpkt.tuple, uid); + if(!iface->is_file) { + uid = uid_lru_find(rt->lru, &zpkt.tuple); + + if(uid == -2) { + uid = get_uid(rt->resolver, &zpkt.tuple); + uid_lru_add(rt->lru, &zpkt.tuple, uid); + } } if((rt->conf->uid_filter == -1) || (rt->conf->uid_filter == uid)) { @@ -1011,6 +1026,9 @@ int main(int argc, char *argv[]) { rv = run_pcap_dump(&conf); unlink(PCAPD_PID); + for(int i=0; i. + * + * Copyright 2022 - Emanuele Faranda + */ + +#include "test_utils.h" + +/* ******************************************************* */ + +static void test_match() { + blacklist_t *bl = blacklist_init(); + assert(bl != NULL); + + // Load blacklist + assert0(blacklist_add_domain(bl, "example.org")); + assert0(blacklist_add_ipstr(bl, "1.2.3.4")); + assert0(blacklist_add_ipstr(bl, "::2")); + assert0(blacklist_add_uid(bl, 777)); + assert0(blacklist_add_uid(bl, 888)); + + // Use blacklist + assert1(blacklist_match_domain(bl, "www.example.org")); + //assert1(blacklist_match_domain(bl, "some.example.org")); // TODO support subdomains matching + + assert0(blacklist_match_ipstr(bl, "1.2.3.0")); + assert1(blacklist_match_ipstr(bl, "1.2.3.4")); + + assert0(blacklist_match_ipstr(bl, "::1")); + assert1(blacklist_match_ipstr(bl, "::2")); + + assert0(blacklist_match_uid(bl, 0)); + assert0(blacklist_match_uid(bl, 999)); + assert1(blacklist_match_uid(bl, 777)); + + blacklist_destroy(bl); +} + +/* ******************************************************* */ + +int main(int argc, char **argv) { + add_test("match", test_match); + run_test(argc, argv); + + return 0; +} diff --git a/app/src/main/jni/tests/pcap_reader.c b/app/src/main/jni/tests/pcap_reader.c new file mode 100644 index 00000000..1c9b4dfc --- /dev/null +++ b/app/src/main/jni/tests/pcap_reader.c @@ -0,0 +1,104 @@ +/* + * This file is part of PCAPdroid. + * + * PCAPdroid is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PCAPdroid is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with PCAPdroid. If not, see . + * + * Copyright 2022 - Emanuele Faranda + */ + +#include +#include +#include "test_utils.h" +#include "common/utils.h" + +/* ******************************************************* */ + +static void usage() { + fprintf(stderr, "pcap_reader - test for PCAPdroid\n" + "Copyright 2022 Emanuele Faranda \n\n" + "Usage: pcap_reader -i ifname\n" + " -i [ifname] capture packets on the specified interface or PCAP file.\n" + " The '@inet' keyword can be used to capture from the internet\n" + " interface\n" + ); + + exit(1); +} + +/* ******************************************************* */ + +static void sig_handler(int signo) { + if(running) { + running = false; + return; + } + + fprintf(stderr, "exit now"); + exit(1); +} + +/* ******************************************************* */ + +static void dump_connections(pcapdroid_t *pd) { + char buf[256]; + + for(int i=0; i < pd->new_conns.cur_items; i++) { + conn_and_tuple_t *conn = &pd->new_conns.items[i]; + + zdtun_5tuple2str(&conn->tuple, buf, sizeof(buf)); + printf("%s [%s]\n", buf, + //pd_get_proto_name(pd, conn->data->l7proto, conn->tuple.ipproto), + conn->data->info ? conn->data->info : ""); + } +} + +/* ******************************************************* */ + +int main(int argc, char *argv[]) { + int c; + char *ifname = NULL; + uint8_t verbose = 0; + + while((c = getopt(argc, argv, "hi:v")) != -1) { + switch(c) { + case 'i': + ifname = strdup(optarg); + break; + case 'v': + verbose = 1; + break; + default: + usage(); + } + } + + if(ifname == NULL) + usage(); + + loglevel = verbose ? ANDROID_LOG_DEBUG : ANDROID_LOG_INFO; + + pcapdroid_t *pd = pd_init(ifname); + pd->cb.send_connections_dump = dump_connections; + + signal(SIGINT, sig_handler); + signal(SIGTERM, sig_handler); + signal(SIGHUP, sig_handler); + + log_i("Capturing packets from %s", ifname); + pd_run(pd); + + log_i("Terminated"); + pd_free(pd); + free(ifname); +} diff --git a/app/src/main/jni/tests/run_tests.sh b/app/src/main/jni/tests/run_tests.sh new file mode 100755 index 00000000..5dd3a268 --- /dev/null +++ b/app/src/main/jni/tests/run_tests.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +mkdir -p build +cd build && cmake .. && make -j$(nproc) run_tests diff --git a/app/src/main/jni/tests/test_utils.c b/app/src/main/jni/tests/test_utils.c new file mode 100644 index 00000000..14ae2fac --- /dev/null +++ b/app/src/main/jni/tests/test_utils.c @@ -0,0 +1,90 @@ +/* + * This file is part of PCAPdroid. + * + * PCAPdroid is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PCAPdroid is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with PCAPdroid. If not, see . + * + * Copyright 2022 - Emanuele Faranda + */ + +#include "test_utils.h" + +#define TEST_NAME_MAX_LENGTH 32 +#define MAX_TESTS 32 + +typedef struct { + char name[TEST_NAME_MAX_LENGTH]; + void (*cb)(); +} test_spec; + +static test_spec all_tests[MAX_TESTS] = {0}; + +static void getPcapdPath(struct pcapdroid *pd, const char *prog_name, char *buf, int bufsize) { + snprintf(buf, bufsize, "main/pcapd/libpcapd.so"); +} + +/* ******************************************************* */ + +void add_test(const char *name, void (*test_cb)()) { + int len = strlen(name); + assert(len < TEST_NAME_MAX_LENGTH); + + for(int i=0; icb(); +} + +/* ******************************************************* */ + +pcapdroid_t* pd_init(const char *ifname) { + pcapdroid_t *pd = calloc(1, sizeof(pcapdroid_t)); + assert(pd != NULL); + + pd->root_capture = true; + pd->root.capture_interface = (char*) ifname; + pd->root.as_root = false; // don't run as root + pd->app_filter = -1; // don't filter + pd->cb.get_libprog_path = getPcapdPath; + + strcpy(pd->cachedir, "."); + pd->cachedir_len = 1; + + return pd; +} diff --git a/app/src/main/jni/tests/test_utils.h b/app/src/main/jni/tests/test_utils.h new file mode 100644 index 00000000..85708ffd --- /dev/null +++ b/app/src/main/jni/tests/test_utils.h @@ -0,0 +1,38 @@ +/* + * This file is part of PCAPdroid. + * + * PCAPdroid is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PCAPdroid is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with PCAPdroid. If not, see . + * + * Copyright 2022 - Emanuele Faranda + */ + +#ifndef __TEST_UTILS_H__ +#define __TEST_UTILS_H__ + +#include "core/pcapdroid.h" +#include + +#define assert0(x) assert((x) == 0) +#define assert1(x) assert((x) == 1) + +void add_test(const char *name, void (*test_cb)()); +void run_test(int argc, char **argv); + +pcapdroid_t* pd_init(const char *ifname); + +static inline void pd_free(pcapdroid_t *pd) { + free(pd); +} + +#endif