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 d48411a6..d9269b83 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/CaptureService.java +++ b/app/src/main/java/com/emanuelef/remote_capture/CaptureService.java @@ -584,6 +584,8 @@ public class CaptureService extends VpnService implements Runnable { public int getAppFilterUid() { return(app_filter_uid); } + public String getCaptureInterface() { return(mSettings.capture_interface); } + public int getOwnAppUid() { AppDescriptor app = AppsResolver.resolve(getPackageManager(), BuildConfig.APPLICATION_ID, 0); diff --git a/app/src/main/java/com/emanuelef/remote_capture/activities/SettingsActivity.java b/app/src/main/java/com/emanuelef/remote_capture/activities/SettingsActivity.java index f1eea210..6ec3f213 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/activities/SettingsActivity.java +++ b/app/src/main/java/com/emanuelef/remote_capture/activities/SettingsActivity.java @@ -37,6 +37,10 @@ import com.emanuelef.remote_capture.Utils; import com.emanuelef.remote_capture.model.Prefs; import com.emanuelef.remote_capture.R; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.ArrayList; +import java.util.Enumeration; import java.util.regex.Matcher; public class SettingsActivity extends BaseActivity { @@ -74,6 +78,7 @@ public class SettingsActivity extends BaseActivity { private Preference mTlsHelp; private Preference mProxyPrefs; private Preference mIpv6Enabled; + private DropDownPreference mCapInterface; @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { @@ -82,6 +87,7 @@ public class SettingsActivity extends BaseActivity { setupUdpExporterPrefs(); setupHttpServerPrefs(); setupSocks5ProxyPrefs(); + setupCapturePrefs(); setupOtherPrefs(); socks5ProxyHideShow(mTlsDecryptionEnabled.isChecked()); @@ -117,6 +123,40 @@ public class SettingsActivity extends BaseActivity { mHttpServerPort.setOnPreferenceChangeListener((preference, newValue) -> validatePort(newValue.toString())); } + private void refreshInterfaces() { + ArrayList labels = new ArrayList<>(); + ArrayList values = new ArrayList<>(); + + labels.add(getString(R.string.internet)); + values.add("@inet"); + labels.add(getString(R.string.all_interfaces)); + values.add("any"); + + try { + Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); + + while (ifaces.hasMoreElements()) { + NetworkInterface iface = ifaces.nextElement(); + if(!iface.isUp()) + continue; + + String name = iface.getName(); + labels.add(name); + values.add(name); + } + } catch (SocketException e) { + e.printStackTrace(); + } + + mCapInterface.setEntryValues(values.toArray(new String[0])); + mCapInterface.setEntries(labels.toArray(new String[0])); + } + + private void setupCapturePrefs() { + mCapInterface = findPreference(Prefs.PREF_CAPTURE_INTERFACE); + refreshInterfaces(); + } + private void setupSocks5ProxyPrefs() { mProxyPrefs = findPreference("proxy_prefs"); mTlsHelp = findPreference("tls_how_to"); @@ -194,6 +234,7 @@ public class SettingsActivity extends BaseActivity { private void rootCaptureHideShow(boolean enabled) { mProxyPrefs.setVisible(!enabled); mIpv6Enabled.setVisible(!enabled); + mCapInterface.setVisible(enabled); } } } \ No newline at end of file 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 60cbe8c6..325e01d2 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 @@ -74,6 +74,7 @@ public class StatusFragment extends Fragment implements AppStateListener, AppsLo private Menu mMenu; private MenuItem mMenuItemStartBtn; private MenuItem mMenuSettings; + private TextView mInterfaceInfo; private TextView mCollectorInfo; private TextView mCaptureStatus; private View mQuickSettings; @@ -140,6 +141,7 @@ public class StatusFragment extends Fragment implements AppStateListener, AppsLo @SuppressLint("ClickableViewAccessibility") @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + mInterfaceInfo = view.findViewById(R.id.interface_info); mCollectorInfo = view.findViewById(R.id.collector_info); mCaptureStatus = view.findViewById(R.id.status_view); mQuickSettings = view.findViewById(R.id.quick_settings); @@ -339,6 +341,7 @@ private void refreshPcapDumpInfo() { mCaptureStatus.setText(R.string.ready); mCollectorInfo.setVisibility(View.GONE); + mInterfaceInfo.setVisibility(View.GONE); mQuickSettings.setVisibility(View.VISIBLE); break; case starting: @@ -358,6 +361,18 @@ private void refreshPcapDumpInfo() { mCaptureStatus.setText(Utils.formatBytes(CaptureService.getBytes())); mCollectorInfo.setVisibility(View.VISIBLE); mQuickSettings.setVisibility(View.GONE); + if(CaptureService.isCapturingAsRoot()) { + CaptureService service = CaptureService.requireInstance(); + String capiface = service.getCaptureInterface(); + + if(capiface.equals("@inet")) + capiface = getString(R.string.internet); + else if(capiface.equals("any")) + capiface = getString(R.string.all_interfaces); + + mInterfaceInfo.setText(String.format(getResources().getString(R.string.capturing_from), capiface)); + mInterfaceInfo.setVisibility(View.VISIBLE); + } refreshPcapDumpInfo(); break; default: diff --git a/app/src/main/java/com/emanuelef/remote_capture/model/CaptureSettings.java b/app/src/main/java/com/emanuelef/remote_capture/model/CaptureSettings.java index 21052908..07b9926b 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/model/CaptureSettings.java +++ b/app/src/main/java/com/emanuelef/remote_capture/model/CaptureSettings.java @@ -17,6 +17,7 @@ public class CaptureSettings implements Serializable { public final boolean ipv6_enabled; public final boolean root_capture; public final boolean pcapdroid_trailer; + public final String capture_interface; public CaptureSettings(SharedPreferences prefs) { dump_mode = Prefs.getDumpMode(prefs); @@ -30,6 +31,7 @@ public class CaptureSettings implements Serializable { ipv6_enabled = Prefs.getIPv6Enabled(prefs); root_capture = Prefs.isRootCaptureEnabled(prefs); pcapdroid_trailer = Prefs.isPcapdroidTrailerEnabled(prefs); + capture_interface = Prefs.getCaptureInterface(prefs); } public CaptureSettings(Intent intent) { @@ -44,6 +46,7 @@ public class CaptureSettings implements Serializable { ipv6_enabled = intent.getBooleanExtra(Prefs.PREF_IPV6_ENABLED, false); root_capture = intent.getBooleanExtra(Prefs.PREF_ROOT_CAPTURE, false); pcapdroid_trailer = intent.getBooleanExtra(Prefs.PREF_PCAPDROID_TRAILER, false); + capture_interface = getString(intent, Prefs.PREF_CAPTURE_INTERFACE, "@inet"); } private static String getString(Intent intent, String key, String def_value) { diff --git a/app/src/main/java/com/emanuelef/remote_capture/model/Prefs.java b/app/src/main/java/com/emanuelef/remote_capture/model/Prefs.java index 035ed83d..e82b8eea 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/model/Prefs.java +++ b/app/src/main/java/com/emanuelef/remote_capture/model/Prefs.java @@ -31,6 +31,7 @@ public class Prefs { public static final String PREF_COLLECTOR_PORT_KEY = "collector_port"; public static final String PREF_SOCKS5_PROXY_IP_KEY = "socks5_proxy_ip_address"; public static final String PREF_SOCKS5_PROXY_PORT_KEY = "socks5_proxy_port"; + public static final String PREF_CAPTURE_INTERFACE = "capture_interface"; public static final String PREF_TLS_DECRYPTION_ENABLED_KEY = "tls_decryption_enabled"; public static final String PREF_APP_FILTER = "app_filter"; public static final String PREF_HTTP_SERVER_PORT = "http_server_port"; @@ -75,4 +76,5 @@ public class Prefs { public static boolean useEnglishLanguage(SharedPreferences p){ return("english".equals(p.getString(PREF_APP_LANGUAGE, "system")));} public static boolean isRootCaptureEnabled(SharedPreferences p) { return(Utils.isRootAvailable() && p.getBoolean(PREF_ROOT_CAPTURE, false)); } public static boolean isPcapdroidTrailerEnabled(SharedPreferences p) { return(p.getBoolean(PREF_PCAPDROID_TRAILER, false)); } + public static String getCaptureInterface(SharedPreferences p) { return(p.getString(PREF_CAPTURE_INTERFACE, "@inet")); } } diff --git a/app/src/main/jni/vpnproxy-jni/capture_root.c b/app/src/main/jni/vpnproxy-jni/capture_root.c index aadaad32..f137afa6 100644 --- a/app/src/main/jni/vpnproxy-jni/capture_root.c +++ b/app/src/main/jni/vpnproxy-jni/capture_root.c @@ -111,9 +111,11 @@ static int connectPcapd(vpnproxy_data_t *proxy) { int client = -1; char bpf[256]; char workdir[PATH_MAX], pcapd[PATH_MAX]; + char capture_interface[16]; getStringPref(proxy, "getPcapDumperBpf", bpf, sizeof(bpf)); getStringPref(proxy, "getPcapdWorkingDir", workdir, PATH_MAX); + getStringPref(proxy, "getCaptureInterface", capture_interface, sizeof(capture_interface)); get_libprog_path(proxy, "pcapd", pcapd, sizeof(pcapd)); if(!pcapd[0]) @@ -157,7 +159,7 @@ static int connectPcapd(vpnproxy_data_t *proxy) { // Start the daemon char args[256]; - snprintf(args, sizeof(args), "-l pcapd.log -d -u %d -b \"%s\"", proxy->app_filter, bpf); + snprintf(args, sizeof(args), "-l pcapd.log -i %s -d -u %d -b \"%s\"", capture_interface, proxy->app_filter, bpf); su_cmd(pcapd, args); // Wait for pcapd to start diff --git a/app/src/main/res/layout/status.xml b/app/src/main/res/layout/status.xml index ba20f35d..95f24f0d 100644 --- a/app/src/main/res/layout/status.xml +++ b/app/src/main/res/layout/status.xml @@ -24,10 +24,20 @@ android:drawablePadding="10dp" tools:text="Collector Info" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/status_view" /> + + PCAPdroid Control Request The control request was denied The control request was allowed + Capture Interface + Internet + All Interfaces + Capturing packets from \"%1$s\" diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml index 77c031f1..f0abb83a 100644 --- a/app/src/main/res/xml/root_preferences.xml +++ b/app/src/main/res/xml/root_preferences.xml @@ -82,6 +82,13 @@ app:summary="@string/root_capture_summary" app:defaultValue="false" /> + +