aboutsummaryrefslogtreecommitdiffstats
path: root/extcap
diff options
context:
space:
mode:
authorFlorian Bezold <florian.bezold@esrlabs.com>2017-12-07 09:00:13 +0100
committerAnders Broman <a.broman58@gmail.com>2017-12-18 14:45:49 +0000
commit5ebc3277ed98c39b24d971470d1aea0efe042351 (patch)
tree349c296c225f77052f6313235326326a5a061bef /extcap
parent09ad8456906172c384a01df49a7eba5716ebfa8e (diff)
androiddump: Fix adb tcpdump PTY CR/LF handling
Devices running Android >= 7 have a different adb shell handling than before: - Before Android 7, adb always runs shell commands in a PTY (pseudoterminal), which automatically converts all \n to \r\n - Since Android 7, adb no longer uses a PTY if a command is directly started (like 'tcpdump' in our case). The original androiddump code reversed the PTY \r\n handling as for older devices. Commit 66507b9 for bug 13510 removed that which supported newer devices while breaking all older devices. This fix tries to support both by first trying to use the new "shell,raw:" adb command syntax. If that succeeds, adb/device must support non-PTY shells and we don't reverse any \r\n. If that fails, it's most likely an older device, and we fall back to the original "shell:" command and enable \r\n reversal. (To prevent misleading error popups in Wireshark, the warning log in adb_send when the first attempt fails is changed to a debug log). Ping-Bug: 13510 Change-Id: I7e0a4f594ebe5dde682cceb667330459337a0c9c Reviewed-on: https://code.wireshark.org/review/24721 Reviewed-by: Mikael Kanstrup <mikael.kanstrup@gmail.com> Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'extcap')
-rw-r--r--extcap/androiddump.c43
1 files changed, 30 insertions, 13 deletions
diff --git a/extcap/androiddump.c b/extcap/androiddump.c
index fe9e1cc7ea..33a82f0720 100644
--- a/extcap/androiddump.c
+++ b/extcap/androiddump.c
@@ -172,6 +172,7 @@ enum exit_code {
EXIT_CODE_INVALID_SOCKET_9,
EXIT_CODE_INVALID_SOCKET_10,
EXIT_CODE_INVALID_SOCKET_11,
+ EXIT_CODE_INVALID_SOCKET_12,
EXIT_CODE_GENERIC = -1
};
@@ -800,7 +801,7 @@ static int adb_send(socket_handle_t sock, const char *adb_service) {
}
if (memcmp(buffer, "OKAY", 4)) {
- g_warning("Error while receiving by ADB for <%s>", adb_service);
+ g_debug("Error while receiving by ADB for <%s>", adb_service);
return EXIT_CODE_ERROR_WHILE_RECEIVING_ADB_PACKET_DATA;
}
@@ -2303,7 +2304,8 @@ static int linktype_to_extcap_encap(const char* linktype)
/*----------------------------------------------------------------------------*/
static int capture_android_tcpdump(char *interface, char *fifo,
const char *adb_server_ip, unsigned short *adb_server_tcp_port) {
- static const char *const adb_shell_tcpdump_format = "shell:tcpdump -n -s 0 -u -i %s -w -";
+ static const char *const adb_shell_tcpdump_format = "shell,raw:tcpdump -n -s 0 -u -i %s -w -";
+ static const char *const adb_shell_legacy_tcpdump_format = "shell:tcpdump -n -s 0 -u -i %s -w -";
static const char *const regex_interface = INTERFACE_ANDROID_TCPDUMP "-(?<iface>.*?)-(?<serial>.*)";
static const char *const regex_linktype = "tcpdump: listening on .*?, link-type (?<linktype>.*?) ";
struct extcap_dumper extcap_dumper;
@@ -2325,6 +2327,7 @@ static int capture_android_tcpdump(char *interface, char *fifo,
GError *err = NULL;
GMatchInfo *match = NULL;
char tcpdump_cmd[80];
+ gboolean pty_mode = FALSE;
regex = g_regex_new(regex_interface, (GRegexCompileFlags)0, (GRegexMatchFlags)0, &err);
if (!regex) {
@@ -2352,18 +2355,34 @@ static int capture_android_tcpdump(char *interface, char *fifo,
return EXIT_CODE_INVALID_SOCKET_11;
}
+ /* Try the new raw (non-PTY) shell protocol first */
g_snprintf(tcpdump_cmd, sizeof(tcpdump_cmd), adb_shell_tcpdump_format, iface);
- g_free(iface);
- g_free(serial_number);
-
result = adb_send(sock, tcpdump_cmd);
+ if (result) {
+ g_debug("Target does not support raw shell protocol");
+ closesocket(sock);
+
+ /* Fall back to the old PTY shell */
+ sock = adb_connect_transport(adb_server_ip, adb_server_tcp_port, serial_number);
+ if (sock == INVALID_SOCKET) {
+ g_free(iface);
+ g_free(serial_number);
+ return EXIT_CODE_INVALID_SOCKET_12;
+ }
+ pty_mode = TRUE;
+ g_snprintf(tcpdump_cmd, sizeof(tcpdump_cmd), adb_shell_legacy_tcpdump_format, iface);
+ result = adb_send(sock, tcpdump_cmd);
+ }
if (result) {
g_warning("Error while setting adb transport");
closesocket(sock);
return EXIT_CODE_GENERIC;
}
+ g_free(iface);
+ g_free(serial_number);
+
regex = g_regex_new(regex_linktype, (GRegexCompileFlags)0, (GRegexMatchFlags)0, &err);
if (!regex) {
g_warning("Failed to compile regex for tcpdump data link type matching");
@@ -2431,20 +2450,18 @@ static int capture_android_tcpdump(char *interface, char *fifo,
extcap_dumper = extcap_dumper_open(fifo, linktype_to_extcap_encap(linktype));
g_free(linktype);
- /*
- * The data we are getting from the tcpdump stdoutput stream as the stdout is the text stream it is
- * convertinng the 0A=0D0A; So we need to remove these extra character.
- */
filter_buffer_length=0;
while (endless_loop) {
gssize i = 0,read_offset,j=0;
- /*Filter the received data to get rid of unwanted 0DOA*/
+
+ /*
+ * Before Android 7 adb runs tcpdump in a shell/pseudoterminal and the PTY layer on the target converts
+ * all \n to \r\n. In that case we need to undo this by changing all \r\n (0x0d0a) back to \n (0x0a).
+ */
for (i = 0; i < (used_buffer_length - 1); i++) {
-#ifdef _WIN32
- if (data[i] == 0x0d && data[i + 1] == 0x0a) {
+ if (pty_mode && data[i] == 0x0d && data[i + 1] == 0x0a) {
i++;
}
-#endif
filter_buffer[filter_buffer_length++] = data[i];
}