mirror of
https://github.com/emanuele-f/PCAPdroid.git
synced 2026-06-11 21:01:45 +08:00
parent
2d6cc8496d
commit
25f495335a
@ -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);
|
||||
|
||||
|
||||
@ -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<String> labels = new ArrayList<>();
|
||||
ArrayList<String> values = new ArrayList<>();
|
||||
|
||||
labels.add(getString(R.string.internet));
|
||||
values.add("@inet");
|
||||
labels.add(getString(R.string.all_interfaces));
|
||||
values.add("any");
|
||||
|
||||
try {
|
||||
Enumeration<NetworkInterface> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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:
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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")); }
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/interface_info"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:gravity="center"
|
||||
tools:text="Capturing from eth0..."
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/collector_info" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/status_view"
|
||||
android:layout_width="210dp"
|
||||
|
||||
@ -175,5 +175,9 @@
|
||||
<string name="ctrl_consent_title">PCAPdroid Control Request</string>
|
||||
<string name="ctrl_consent_denied">The control request was denied</string>
|
||||
<string name="ctrl_consent_allowed">The control request was allowed</string>
|
||||
<string name="capture_interface">Capture Interface</string>
|
||||
<string name="internet">Internet</string>
|
||||
<string name="all_interfaces">All Interfaces</string>
|
||||
<string name="capturing_from">Capturing packets from \"%1$s\"</string>
|
||||
</resources>
|
||||
|
||||
|
||||
@ -82,6 +82,13 @@
|
||||
app:summary="@string/root_capture_summary"
|
||||
app:defaultValue="false" />
|
||||
|
||||
<DropDownPreference
|
||||
app:key="capture_interface"
|
||||
app:title="@string/capture_interface"
|
||||
app:iconSpaceReserved="false"
|
||||
app:useSimpleSummaryProvider="true"
|
||||
app:defaultValue="\@inet" />
|
||||
|
||||
<SwitchPreference
|
||||
app:key="pcapdroid_trailer"
|
||||
app:title="@string/pcapdroid_trailer"
|
||||
|
||||
@ -81,3 +81,4 @@ As shown above, the capture settings can be specified by using intent extras. Th
|
||||
| ipv6_enabled | bool | true to enable IPv6 support in non-root mode |
|
||||
| root_capture | bool | true to capture packets in root mode, false to use the VPNService |
|
||||
| pcapdroid_trailer | bool | true to enable the PCAPdroid trailer |
|
||||
| capture_interface | string | @inet \| any \| ifname - network interface to use in root mode |
|
||||
|
||||
Loading…
Reference in New Issue
Block a user