diff --git a/app/src/main/jni/common/utils.c b/app/src/main/jni/common/utils.c index 92dd6a37..41dba7bf 100644 --- a/app/src/main/jni/common/utils.c +++ b/app/src/main/jni/common/utils.c @@ -101,6 +101,18 @@ ssize_t xread(int fd, void *buf, size_t count) { /* ******************************************************* */ +void tupleSwapPeers(zdtun_5tuple_t *tuple) { + uint16_t tmp = tuple->dst_port; + tuple->dst_port = tuple->src_port; + tuple->src_port = tmp; + + zdtun_ip_t tmp1 = tuple->dst_ip; + tuple->dst_ip = tuple->src_ip; + tuple->src_ip = tmp1; +} + +/* ******************************************************* */ + int jniCheckException(JNIEnv *env) { jthrowable ex = (*env)->ExceptionOccurred(env); if (ex) { diff --git a/app/src/main/jni/common/utils.h b/app/src/main/jni/common/utils.h index 528dc057..b2342c83 100644 --- a/app/src/main/jni/common/utils.h +++ b/app/src/main/jni/common/utils.h @@ -23,6 +23,7 @@ #include #include #include +#include "zdtun.h" extern int loglevel; extern const char* logtag; @@ -37,6 +38,7 @@ extern void (*logcallback)(int lvl, const char *msg); void log_android(int prio, const char *fmt, ...); ssize_t xwrite(int fd, const void *buf, size_t count); ssize_t xread(int fd, void *buf, size_t count); +void tupleSwapPeers(zdtun_5tuple_t *tuple); jclass jniFindClass(JNIEnv *env, const char *name); jmethodID jniGetMethodID(JNIEnv *env, jclass cls, const char *name, const char *signature); diff --git a/app/src/main/jni/pcapd/pcapd.c b/app/src/main/jni/pcapd/pcapd.c index 6ee72e90..dd7ba561 100644 --- a/app/src/main/jni/pcapd/pcapd.c +++ b/app/src/main/jni/pcapd/pcapd.c @@ -410,7 +410,7 @@ static int is_tx_packet(pcapd_runtime_t *rt, const u_char *pkt, u_int16_t len) { pkt += 14; } else if((rt->dlink == DLT_LINUX_SLL) && (len >= SLL_HDR_LEN)) { struct sll_header *sll = (struct sll_header*) pkt; - uint8_t pkttype = sll->sll_pkttype; + uint16_t pkttype = ntohs(sll->sll_pkttype); if(pkttype == LINUX_SLL_HOST) return 0; // RX @@ -511,13 +511,7 @@ static int run_pcap_dump(int uid_filter) { if(zdtun_parse_pkt((const char*)pkt, hdr->caplen, &zpkt) == 0) { if(!is_tx) { // Packet from the internet, swap src and dst - uint16_t tmp = zpkt.tuple.dst_port; - zpkt.tuple.dst_port = zpkt.tuple.src_port; - zpkt.tuple.src_port = tmp; - - zdtun_ip_t tmp1 = zpkt.tuple.dst_ip; - zpkt.tuple.dst_ip = zpkt.tuple.src_ip; - zpkt.tuple.src_ip = tmp1; + tupleSwapPeers(&zpkt.tuple); } int uid = uid_lru_find(lru, &zpkt.tuple); diff --git a/app/src/main/jni/vpnproxy-jni/capture_root.c b/app/src/main/jni/vpnproxy-jni/capture_root.c index b73cd5ff..a3b252b5 100644 --- a/app/src/main/jni/vpnproxy-jni/capture_root.c +++ b/app/src/main/jni/vpnproxy-jni/capture_root.c @@ -187,10 +187,9 @@ static int connectPcapd(vpnproxy_data_t *proxy) { /* ******************************************************* */ static void handle_packet(vpnproxy_data_t *proxy, pcap_conn_t **connections, pcapd_hdr_t *hdr, const char *buffer) { - zdtun_5tuple_t search; zdtun_pkt_t pkt; pcap_conn_t *conn = NULL; - uint8_t from_tun = (hdr->flags & PCAPD_FLAG_TX); + uint8_t from_tun = (hdr->flags & PCAPD_FLAG_TX); // NOTE: the direction uses an heuristic so it may be wrong // NOTE: only IP packets supported if(zdtun_parse_pkt(buffer, hdr->len, &pkt) != 0) { @@ -200,56 +199,61 @@ static void handle_packet(vpnproxy_data_t *proxy, pcap_conn_t **connections, pca if(!from_tun) { // Packet from the internet, swap src and dst - search.ipver = pkt.tuple.ipver; - search.ipproto = pkt.tuple.ipproto; + tupleSwapPeers(&pkt.tuple); + } - search.dst_port = pkt.tuple.src_port; - search.src_port = pkt.tuple.dst_port; - search.dst_ip = pkt.tuple.src_ip; - search.src_ip = pkt.tuple.dst_ip; - } else - search = pkt.tuple; - - HASH_FIND(hh, *connections, &search, sizeof(zdtun_5tuple_t), conn); + HASH_FIND(hh, *connections, &pkt.tuple, sizeof(zdtun_5tuple_t), conn); if(!conn) { - conn_data_t *data = new_connection(proxy, &search, hdr->uid); + // from_tun may be wrong, search in the other direction + from_tun = !from_tun; + tupleSwapPeers(&pkt.tuple); - if (!data) - return; + HASH_FIND(hh, *connections, &pkt.tuple, sizeof(zdtun_5tuple_t), conn); - conn = malloc(sizeof(pcap_conn_t)); + if(!conn) { + // assume from_tun was correct + from_tun = !from_tun; + tupleSwapPeers(&pkt.tuple); - if (!conn) { - log_e("malloc(pcap_conn_t) failed with code %d/%s", - errno, strerror(errno)); - return; - } + conn_data_t *data = new_connection(proxy, &pkt.tuple, hdr->uid); - conn->tuple = search; - conn->data = data; + if (!data) + return; - // TODO read from linux? - data->status = CONN_STATUS_CONNECTED; + conn = malloc(sizeof(pcap_conn_t)); - HASH_ADD(hh, *connections, tuple, sizeof(search), conn); + if (!conn) { + log_e("malloc(pcap_conn_t) failed with code %d/%s", + errno, strerror(errno)); + return; + } - data->incr_id = proxy->incr_id++; - conns_add(&proxy->new_conns, &search, data); + conn->tuple = pkt.tuple; + conn->data = data; - switch(conn->tuple.ipproto) { - case IPPROTO_TCP: - proxy->stats.num_tcp_conn++; - proxy->stats.num_tcp_opened++; - break; - case IPPROTO_UDP: - proxy->stats.num_udp_conn++; - proxy->stats.num_udp_opened++; - break; - case IPPROTO_ICMP: - proxy->stats.num_icmp_conn++; - proxy->stats.num_icmp_opened++; - break; + // TODO read from linux? + data->status = CONN_STATUS_CONNECTED; + + HASH_ADD(hh, *connections, tuple, sizeof(zdtun_5tuple_t), conn); + + data->incr_id = proxy->incr_id++; + conns_add(&proxy->new_conns, &pkt.tuple, data); + + switch (conn->tuple.ipproto) { + case IPPROTO_TCP: + proxy->stats.num_tcp_conn++; + proxy->stats.num_tcp_opened++; + break; + case IPPROTO_UDP: + proxy->stats.num_udp_conn++; + proxy->stats.num_udp_opened++; + break; + case IPPROTO_ICMP: + proxy->stats.num_icmp_conn++; + proxy->stats.num_icmp_opened++; + break; + } } }