diff --git a/app/src/main/java/com/emanuelef/remote_capture/CaptureService.java b/app/src/main/java/com/emanuelef/remote_capture/CaptureService.java index 3484d51d..ce2e699c 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/CaptureService.java +++ b/app/src/main/java/com/emanuelef/remote_capture/CaptureService.java @@ -67,7 +67,7 @@ import com.emanuelef.remote_capture.model.ConnectionUpdate; import com.emanuelef.remote_capture.model.FilterDescriptor; import com.emanuelef.remote_capture.model.MatchList; import com.emanuelef.remote_capture.model.Prefs; -import com.emanuelef.remote_capture.model.VPNStats; +import com.emanuelef.remote_capture.model.CaptureStats; import com.emanuelef.remote_capture.pcap_dump.FileDumper; import com.emanuelef.remote_capture.pcap_dump.HTTPServer; import com.emanuelef.remote_capture.interfaces.PcapDumper; @@ -134,6 +134,7 @@ public class CaptureService extends VpnService implements Runnable { private String mSocks5Address; private int mSocks5Port; private String mSocks5Auth; + private CaptureStats mLastStats; /* The maximum connections to log into the ConnectionsRegister. Older connections are dropped. * Max estimated memory usage: less than 4 MB (+8 MB with payload mode minimal). */ @@ -873,7 +874,7 @@ public class CaptureService extends VpnService implements Runnable { // Notify mHandler.post(() -> { sendServiceStatus(SERVICE_STATUS_STOPPED); - CaptureCtrl.notifyCaptureStopped(this); + CaptureCtrl.notifyCaptureStopped(this, mLastStats); }); mCaptureThread = null; @@ -1015,7 +1016,7 @@ public class CaptureService extends VpnService implements Runnable { // from NetGuard @TargetApi(Build.VERSION_CODES.Q) - public int getUidQ(int version, int protocol, String saddr, int sport, String daddr, int dport) { + public int getUidQ(int protocol, String saddr, int sport, String daddr, int dport) { if (protocol != 6 /* TCP */ && protocol != 17 /* UDP */) return Utils.UID_UNKNOWN; @@ -1044,8 +1045,9 @@ public class CaptureService extends VpnService implements Runnable { } } - public void sendStatsDump(VPNStats stats) { + public void sendStatsDump(CaptureStats stats) { //Log.d(TAG, "sendStatsDump"); + mLastStats = stats; Bundle bundle = new Bundle(); bundle.putSerializable("value", stats); @@ -1160,6 +1162,10 @@ public class CaptureService extends VpnService implements Runnable { nativeSetFirewallEnabled(enabled); } + public static CaptureStats getStats() { + return((INSTANCE != null) ? INSTANCE.mLastStats : null); + } + private static native void runPacketLoop(int fd, CaptureService vpn, int sdk); private static native void stopPacketLoop(); private static native int getFdSetSize(); diff --git a/app/src/main/java/com/emanuelef/remote_capture/activities/CaptureCtrl.java b/app/src/main/java/com/emanuelef/remote_capture/activities/CaptureCtrl.java index c6a8974d..f4cee651 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/activities/CaptureCtrl.java +++ b/app/src/main/java/com/emanuelef/remote_capture/activities/CaptureCtrl.java @@ -51,6 +51,7 @@ import com.emanuelef.remote_capture.Utils; import com.emanuelef.remote_capture.model.AppDescriptor; import com.emanuelef.remote_capture.model.CaptureSettings; import com.emanuelef.remote_capture.model.CtrlPermissions; +import com.emanuelef.remote_capture.model.CaptureStats; public class CaptureCtrl extends AppCompatActivity { public static final String ACTION_START = "start"; @@ -204,12 +205,20 @@ public class CaptureCtrl extends AppCompatActivity { CaptureService.stopService(); mStarterApp = null; + + CaptureStats stats = CaptureService.getStats(); + if(stats != null) + putStats(res, stats); } else if(action.equals(ACTION_STATUS)) { Log.d(TAG, "Returning status"); res.putExtra("running", CaptureService.isServiceActive()); res.putExtra("version_name", BuildConfig.VERSION_NAME); res.putExtra("version_code", BuildConfig.VERSION_CODE); + + CaptureStats stats = CaptureService.getStats(); + if(stats != null) + putStats(res, stats); } else { Log.e(TAG, "unknown action: " + action); abort(); @@ -220,12 +229,14 @@ public class CaptureCtrl extends AppCompatActivity { finish(); } - public static void notifyCaptureStopped(Context ctx) { + public static void notifyCaptureStopped(Context ctx, CaptureStats stats) { if((mStarterApp != null) && (mReceiverClass != null)) { Log.d(TAG, "Notifying receiver"); Intent intent = new Intent(ACTION_NOTIFY_STATUS); intent.putExtra("running", false); + if(stats != null) + putStats(intent, stats); intent.setComponent(new ComponentName(mStarterApp.getPackageName(), mReceiverClass)); try { @@ -238,4 +249,13 @@ public class CaptureCtrl extends AppCompatActivity { mStarterApp = null; mReceiverClass = null; } + + private static void putStats(Intent intent, CaptureStats stats) { + intent.putExtra("bytes_sent", stats.bytes_sent); + intent.putExtra("bytes_rcvd", stats.bytes_rcvd); + intent.putExtra("bytes_dumped", stats.pcap_dump_size); + intent.putExtra("pkts_sent", stats.pkts_sent); + intent.putExtra("pkts_rcvd", stats.pkts_rcvd); + intent.putExtra("pkts_dropped", stats.pkts_dropped); + } } diff --git a/app/src/main/java/com/emanuelef/remote_capture/activities/StatsActivity.java b/app/src/main/java/com/emanuelef/remote_capture/activities/StatsActivity.java index df5371ff..6778bf05 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/activities/StatsActivity.java +++ b/app/src/main/java/com/emanuelef/remote_capture/activities/StatsActivity.java @@ -38,7 +38,7 @@ import android.widget.TextView; import com.emanuelef.remote_capture.CaptureService; import com.emanuelef.remote_capture.R; import com.emanuelef.remote_capture.Utils; -import com.emanuelef.remote_capture.model.VPNStats; +import com.emanuelef.remote_capture.model.CaptureStats; public class StatsActivity extends BaseActivity { private BroadcastReceiver mReceiver; @@ -89,7 +89,7 @@ public class StatsActivity extends BaseActivity { mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - updateVPNStats(intent); + updateStats(intent); } }; @@ -109,8 +109,8 @@ public class StatsActivity extends BaseActivity { .unregisterReceiver(mReceiver); } - private void updateVPNStats(Intent intent) { - VPNStats stats = (VPNStats) intent.getSerializableExtra("value"); + private void updateStats(Intent intent) { + CaptureStats stats = (CaptureStats) intent.getSerializableExtra("value"); mBytesSent.setText(Utils.formatBytes(stats.bytes_sent)); mBytesRcvd.setText(Utils.formatBytes(stats.bytes_rcvd)); diff --git a/app/src/main/java/com/emanuelef/remote_capture/fragments/StatusFragment.java b/app/src/main/java/com/emanuelef/remote_capture/fragments/StatusFragment.java index 44660a07..5409a969 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/fragments/StatusFragment.java +++ b/app/src/main/java/com/emanuelef/remote_capture/fragments/StatusFragment.java @@ -59,7 +59,7 @@ import com.emanuelef.remote_capture.Utils; import com.emanuelef.remote_capture.activities.MainActivity; import com.emanuelef.remote_capture.interfaces.AppStateListener; import com.emanuelef.remote_capture.model.Prefs; -import com.emanuelef.remote_capture.model.VPNStats; +import com.emanuelef.remote_capture.model.CaptureStats; import com.emanuelef.remote_capture.views.AppsListView; import com.emanuelef.remote_capture.views.PrefSpinner; import com.pcapdroid.mitm.MitmAPI; @@ -269,7 +269,7 @@ public class StatusFragment extends Fragment implements AppStateListener, AppsLo } private void processStatsUpdateIntent(Intent intent) { - VPNStats stats = (VPNStats) intent.getSerializableExtra("value"); + CaptureStats stats = (CaptureStats) intent.getSerializableExtra("value"); Log.d("MainReceiver", "Got StatsUpdate: bytes_sent=" + stats.pkts_sent + ", bytes_rcvd=" + stats.bytes_rcvd + ", pkts_sent=" + stats.pkts_sent + ", pkts_rcvd=" + stats.pkts_rcvd); diff --git a/app/src/main/java/com/emanuelef/remote_capture/model/VPNStats.java b/app/src/main/java/com/emanuelef/remote_capture/model/CaptureStats.java similarity index 87% rename from app/src/main/java/com/emanuelef/remote_capture/model/VPNStats.java rename to app/src/main/java/com/emanuelef/remote_capture/model/CaptureStats.java index aa3cffa2..724f0fda 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/model/VPNStats.java +++ b/app/src/main/java/com/emanuelef/remote_capture/model/CaptureStats.java @@ -21,10 +21,11 @@ package com.emanuelef.remote_capture.model; import java.io.Serializable; -public class VPNStats implements Serializable { +public class CaptureStats implements Serializable { public String alloc_summary; public long bytes_sent; public long bytes_rcvd; + public long pcap_dump_size; public int pkts_sent; public int pkts_rcvd; public int pkts_dropped; @@ -37,12 +38,14 @@ public class VPNStats implements Serializable { /* Invoked by native code */ public void setData(String _alloc_summary, - long _bytes_sent, long _bytes_rcvd, int _pkts_sent, int _pkts_rcvd, + long _bytes_sent, long _bytes_rcvd, long _pcap_dump_size, + int _pkts_sent, int _pkts_rcvd, int _pkts_dropped, int _num_dropped_conns, int _num_open_sockets, int _max_fd, int _active_conns, int _tot_conns, int _num_dns_queries) { alloc_summary = _alloc_summary; bytes_sent = _bytes_sent; bytes_rcvd = _bytes_rcvd; + pcap_dump_size = _pcap_dump_size; pkts_sent = _pkts_sent; pkts_rcvd = _pkts_rcvd; pkts_dropped = _pkts_dropped; diff --git a/app/src/main/jni/common/uid_resolver.c b/app/src/main/jni/common/uid_resolver.c index 2437a279..221370d8 100644 --- a/app/src/main/jni/common/uid_resolver.c +++ b/app/src/main/jni/common/uid_resolver.c @@ -187,7 +187,7 @@ static int get_uid_q(uid_resolver_t *resolver, // Resolve method jclass vpn_service_cls = (*env)->GetObjectClass(env, resolver->vpn_service); resolver->getUidQ = jniGetMethodID(env, vpn_service_cls, "getUidQ", - "(IILjava/lang/String;ILjava/lang/String;I)I"); + "(ILjava/lang/String;ILjava/lang/String;I)I"); if(!resolver->getUidQ) return UID_UNKNOWN; @@ -205,7 +205,7 @@ static int get_uid_q(uid_resolver_t *resolver, if((jsource != NULL) && (jdest != NULL)) { juid = (*env)->CallIntMethod( env, resolver->vpn_service, resolver->getUidQ, - version, conn_info->ipproto, jsource, sport, jdest, dport); + conn_info->ipproto, jsource, sport, jdest, dport); jniCheckException(env); } diff --git a/app/src/main/jni/core/jni_impl.c b/app/src/main/jni/core/jni_impl.c index 76fe2f13..b1ac52a3 100644 --- a/app/src/main/jni/core/jni_impl.c +++ b/app/src/main/jni/core/jni_impl.c @@ -72,13 +72,13 @@ static void sendStatsDump(pcapdroid_t *pd) { jobject stats_obj = (*env)->NewObject(env, cls.stats, mids.statsInit); if((stats_obj == NULL) || jniCheckException(env)) { - log_e("NewObject(VPNStats) failed"); + log_e("NewObject(CaptureStats) failed"); return; } (*env)->CallVoidMethod(env, stats_obj, mids.statsSetData, allocs_summary, - capstats->sent_bytes, capstats->rcvd_bytes, + capstats->sent_bytes, capstats->rcvd_bytes, pd->pcap_dump.tot_size, capstats->sent_pkts, capstats->rcvd_pkts, min(pd->num_dropped_pkts, INT_MAX), pd->num_dropped_connections, stats->num_open_sockets, stats->all_max_fd, active_conns, tot_conns, @@ -490,7 +490,7 @@ Java_com_emanuelef_remote_1capture_CaptureService_runPacketLoop(JNIEnv *env, jcl cls.vpn_service = vpn_class; cls.conn = jniFindClass(env, "com/emanuelef/remote_capture/model/ConnectionDescriptor"); cls.conn_update = jniFindClass(env, "com/emanuelef/remote_capture/model/ConnectionUpdate"); - cls.stats = jniFindClass(env, "com/emanuelef/remote_capture/model/VPNStats"); + cls.stats = jniFindClass(env, "com/emanuelef/remote_capture/model/CaptureStats"); cls.blacklist_status = jniFindClass(env, "com/emanuelef/remote_capture/Blacklists$NativeBlacklistStatus"); cls.blacklist_descriptor = jniFindClass(env, "com/emanuelef/remote_capture/model/BlacklistDescriptor"); cls.matchlist_descriptor = jniFindClass(env, "com/emanuelef/remote_capture/model/MatchList$ListDescriptor"); @@ -505,7 +505,7 @@ Java_com_emanuelef_remote_1capture_CaptureService_runPacketLoop(JNIEnv *env, jcl mids.dumpPcapData = jniGetMethodID(env, vpn_class, "dumpPcapData", "([B)V"); mids.stopPcapDump = jniGetMethodID(env, vpn_class, "stopPcapDump", "()V"); mids.updateConnections = jniGetMethodID(env, vpn_class, "updateConnections", "([Lcom/emanuelef/remote_capture/model/ConnectionDescriptor;[Lcom/emanuelef/remote_capture/model/ConnectionUpdate;)V"); - mids.sendStatsDump = jniGetMethodID(env, vpn_class, "sendStatsDump", "(Lcom/emanuelef/remote_capture/model/VPNStats;)V"); + mids.sendStatsDump = jniGetMethodID(env, vpn_class, "sendStatsDump", "(Lcom/emanuelef/remote_capture/model/CaptureStats;)V"); mids.sendServiceStatus = jniGetMethodID(env, vpn_class, "sendServiceStatus", "(Ljava/lang/String;)V"); mids.getLibprogPath = jniGetMethodID(env, vpn_class, "getLibprogPath", "(Ljava/lang/String;)Ljava/lang/String;"); mids.notifyBlacklistsLoaded = jniGetMethodID(env, vpn_class, "notifyBlacklistsLoaded", "([Lcom/emanuelef/remote_capture/Blacklists$NativeBlacklistStatus;)V"); @@ -517,7 +517,7 @@ Java_com_emanuelef_remote_1capture_CaptureService_runPacketLoop(JNIEnv *env, jcl mids.connUpdateSetInfo = jniGetMethodID(env, cls.conn_update, "setInfo", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V"); mids.connUpdateSetPayload = jniGetMethodID(env, cls.conn_update, "setPayload", "(Ljava/util/ArrayList;Z)V"); mids.statsInit = jniGetMethodID(env, cls.stats, "", "()V"); - mids.statsSetData = jniGetMethodID(env, cls.stats, "setData", "(Ljava/lang/String;JJIIIIIIIII)V"); + mids.statsSetData = jniGetMethodID(env, cls.stats, "setData", "(Ljava/lang/String;JJJIIIIIIIII)V"); mids.blacklistStatusInit = jniGetMethodID(env, cls.blacklist_status, "", "(Ljava/lang/String;I)V"); mids.listSize = jniGetMethodID(env, cls.list, "size", "()I"); mids.listGet = jniGetMethodID(env, cls.list, "get", "(I)Ljava/lang/Object;"); diff --git a/app/src/main/jni/core/pcapdroid.c b/app/src/main/jni/core/pcapdroid.c index 8cc618b5..75e27064 100644 --- a/app/src/main/jni/core/pcapdroid.c +++ b/app/src/main/jni/core/pcapdroid.c @@ -1191,6 +1191,8 @@ int pd_run(pcapdroid_t *pd) { log_d("Stopped packet loop"); // send last dump + if(pd->cb.send_stats_dump) + pd->cb.send_stats_dump(pd); if(pd->cb.send_connections_dump) pd->cb.send_connections_dump(pd);