diff --git a/.gitignore b/.gitignore
index 2b75303a..603b1407 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,3 +11,4 @@
/build
/captures
.externalNativeBuild
+.cxx
diff --git a/app/src/main/java/com/emanuelef/remote_capture/Prefs.java b/app/src/main/java/com/emanuelef/remote_capture/Prefs.java
index 016f7f3e..9b0bec31 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/Prefs.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/Prefs.java
@@ -1,8 +1,26 @@
package com.emanuelef.remote_capture;
public class Prefs {
+ static final String DUMP_HTTP_SERVER = "http_server";
+ static final String DUMP_UDP_EXPORTER = "udp_exporter";
static final String PREF_COLLECTOR_IP_KEY = "collector_ip_address";
static final String PREF_COLLECTOR_PORT_KEY = "collector_port";
static final String PREF_UID_FILTER = "uid_filter";
static final String PREF_CAPTURE_UNKNOWN_APP_TRAFFIC = "capture_unknown_app";
+ static final String PREF_HTTP_SERVER_PORT = "http_server_port";
+
+ enum DumpMode {
+ NONE,
+ HTTP_SERVER,
+ UDP_EXPORTER
+ }
+
+ static DumpMode getDumpMode(String pref) {
+ if(pref.equals(DUMP_HTTP_SERVER))
+ return(DumpMode.HTTP_SERVER);
+ else if(pref.equals(DUMP_UDP_EXPORTER))
+ return(DumpMode.UDP_EXPORTER);
+ else
+ return(DumpMode.NONE);
+ }
}
diff --git a/app/src/main/java/com/emanuelef/remote_capture/SettingsActivity.java b/app/src/main/java/com/emanuelef/remote_capture/SettingsActivity.java
index 85a55f5d..62631c23 100644
--- a/app/src/main/java/com/emanuelef/remote_capture/SettingsActivity.java
+++ b/app/src/main/java/com/emanuelef/remote_capture/SettingsActivity.java
@@ -2,6 +2,7 @@ package com.emanuelef.remote_capture;
import android.os.Bundle;
import android.text.InputType;
+import android.util.Log;
import android.util.Patterns;
import android.widget.EditText;
@@ -9,13 +10,14 @@ import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.preference.EditTextPreference;
+import androidx.preference.ListPreference;
import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceFragmentCompat;
import java.util.regex.Matcher;
public class SettingsActivity extends AppCompatActivity {
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -31,13 +33,43 @@ public class SettingsActivity extends AppCompatActivity {
}
public static class SettingsFragment extends PreferenceFragmentCompat {
+ private EditTextPreference mRemoteCollectorIp;
+ private EditTextPreference mRemoteCollectorPort;
+ private EditTextPreference mHttpServerPort;
+ private ListPreference mDumpModePref;
+
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.root_preferences, rootKey);
+ mDumpModePref = findPreference("pcap_dump_mode");
+ mDumpModePref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ dumpPrefsHideShow((String) newValue);
+ return true;
+ }
+ });
+
+ setupUdpExporterPrefs();
+ setupHttpServerPrefs();
+
+ dumpPrefsHideShow(mDumpModePref.getValue());
+ }
+
+ private boolean validatePort(String value) {
+ try {
+ int val = Integer.parseInt(value);
+ return((val > 0) && (val < 65535));
+ } catch(NumberFormatException e) {
+ return false;
+ }
+ }
+
+ private void setupUdpExporterPrefs() {
/* Collector IP validation */
- EditTextPreference ip_address = getPreferenceManager().findPreference(Prefs.PREF_COLLECTOR_IP_KEY);
- ip_address.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ mRemoteCollectorIp = findPreference(Prefs.PREF_COLLECTOR_IP_KEY);
+ mRemoteCollectorIp.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Matcher matcher = Patterns.IP_ADDRESS.matcher(newValue.toString());
@@ -46,24 +78,62 @@ public class SettingsActivity extends AppCompatActivity {
});
/* Collector port validation */
- EditTextPreference port = getPreferenceManager().findPreference(Prefs.PREF_COLLECTOR_PORT_KEY);
- port.setOnBindEditTextListener(new EditTextPreference.OnBindEditTextListener() {
+ mRemoteCollectorPort = findPreference(Prefs.PREF_COLLECTOR_PORT_KEY);
+ mRemoteCollectorPort.setOnBindEditTextListener(new EditTextPreference.OnBindEditTextListener() {
@Override
public void onBindEditText(@NonNull EditText editText) {
editText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
}
});
- port.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ mRemoteCollectorPort.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
- try {
- int val = Integer.parseInt(newValue.toString());
- return((val > 0) && (val < 65535));
- } catch(NumberFormatException e) {
- return false;
- }
+ return validatePort(newValue.toString());
}
});
}
+
+ private void setupHttpServerPrefs() {
+ /* HTTP Server port validation */
+ mHttpServerPort = findPreference(Prefs.PREF_HTTP_SERVER_PORT);
+ mHttpServerPort.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ return validatePort(newValue.toString());
+ }
+ });
+ }
+
+ /* This implements a radio-button like behaviour */
+ private void dumpPrefsHideShow(String dumpMode) {
+ Prefs.DumpMode mode = Prefs.getDumpMode(dumpMode);
+ boolean show_http_prefs = (mode == Prefs.DumpMode.HTTP_SERVER);
+ boolean show_udp_prefs = (mode == Prefs.DumpMode.UDP_EXPORTER);
+
+ /* HTTP Server */
+ mHttpServerPort.setVisible(show_http_prefs);
+
+ /* UDP Receiver */
+ mRemoteCollectorIp.setVisible(show_udp_prefs);
+ mRemoteCollectorPort.setVisible(show_udp_prefs);
+
+ /* Adjust label */
+ int summary_id;
+
+ switch(mode) {
+ case HTTP_SERVER:
+ summary_id = R.string.http_server_info;
+ break;
+ case UDP_EXPORTER:
+ summary_id = R.string.udp_exporter_info;
+ break;
+ case NONE:
+ default:
+ summary_id = R.string.no_dump_info;
+ break;
+ }
+
+ mDumpModePref.setSummary(summary_id);
+ }
}
}
\ No newline at end of file
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
new file mode 100644
index 00000000..b7f82990
--- /dev/null
+++ b/app/src/main/res/values/arrays.xml
@@ -0,0 +1,14 @@
+
+
+
+ - none
+ - http_server
+ - udp_exporter
+
+
+
+ - @string/no_dump
+ - @string/http_server
+ - @string/udp_exporter
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 56fdaaaf..694b54b9 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -26,7 +26,7 @@
Instructions
Capture Unknown Traffic
When an app filter is set, also capture general purpose traffic which cannot be associated to a specific app. This is usually needed to properly capture DNS traffic.
- Capture
+ Misc
Status
Connections
No connections
@@ -40,5 +40,14 @@
Bytes
Packets
Duration
+ HTTP Server
+ UDP Exporter
+ None
+ PCAP will not be dumped
+ Start an HTTP server for the PCAP download
+ Sends the PCAP to an UDP receiver
+ HTTP Server Port
+ Receiver IP Address
+ Receiver Port
diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml
index 0872c8e9..4f908d15 100644
--- a/app/src/main/res/xml/root_preferences.xml
+++ b/app/src/main/res/xml/root_preferences.xml
@@ -14,35 +14,49 @@
~ limitations under the License.
-->
-
+
-
+
+
+
+
-
-
+
-
+
-