2015-02-14 18:10:21 +00:00
/* androiddump.c
* androiddump is extcap tool used to capture Android specific stuff
*
* Copyright 2015 , Michal Labedzki for Tieto Corporation
*
* Wireshark - Network traffic analyzer
* By Gerald Combs < gerald @ wireshark . org >
* Copyright 1998 Gerald Combs
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA .
*/
# include "config.h"
2016-02-22 15:12:44 +00:00
# include "extcap-base.h"
2015-02-14 18:10:21 +00:00
# include <stdio.h>
# include <stdint.h>
# include <string.h>
# include <errno.h>
# include <time.h>
2016-08-31 08:14:33 +00:00
# include <wsutil/strtoi.h>
2016-12-09 10:52:42 +00:00
# include <wsutil/filesystem.h>
2015-02-14 18:10:21 +00:00
2015-05-15 11:30:02 +00:00
# ifdef HAVE_NETINET_IN_H
# include <netinet / in.h>
# endif
2015-02-14 18:10:21 +00:00
# ifdef HAVE_UNISTD_H
# include <unistd.h>
# endif
2015-04-08 10:44:50 +00:00
# ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
# endif
2015-04-11 21:36:21 +00:00
# ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
# endif
2016-12-29 18:16:53 +00:00
# ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
# endif
2015-02-14 18:10:21 +00:00
/* Configuration options */
/* #define ANDROIDDUMP_USE_LIBPCAP */
# define EXTCAP_ENCAP_BLUETOOTH_H4_WITH_PHDR 1
# define EXTCAP_ENCAP_WIRESHARK_UPPER_PDU 2
2015-09-07 09:37:20 +00:00
# define EXTCAP_ENCAP_ETHERNET 3
# define PCAP_GLOBAL_HEADER_LENGTH 24
# define PCAP_RECORD_HEADER_LENGTH 16
2015-02-14 18:10:21 +00:00
# ifdef ANDROIDDUMP_USE_LIBPCAP
# include <pcap.h>
# include <pcap-bpf.h>
# include <pcap/bluetooth.h>
# ifndef DLT_BLUETOOTH_H4_WITH_PHDR
# define DLT_BLUETOOTH_H4_WITH_PHDR 201
# endif
# ifndef DLT_WIRESHARK_UPPER_PDU
# define DLT_WIRESHARK_UPPER_PDU 252
# endif
# ifndef PCAP_TSTAMP_PRECISION_MICRO
# define PCAP_TSTAMP_PRECISION_MICRO 0
# endif
# ifndef PCAP_TSTAMP_PRECISION_NANO
# define PCAP_TSTAMP_PRECISION_NANO 1
# endif
# else
# include "wiretap/wtap.h"
# endif
# define WIRESHARK_UPPER_PDU_TAG_DISSECTOR_NAME 0x000C
# define INTERFACE_ANDROID_LOGCAT_MAIN "android-logcat-main"
# define INTERFACE_ANDROID_LOGCAT_SYSTEM "android-logcat-system"
# define INTERFACE_ANDROID_LOGCAT_RADIO "android-logcat-radio"
# define INTERFACE_ANDROID_LOGCAT_EVENTS "android-logcat-events"
# define INTERFACE_ANDROID_LOGCAT_TEXT_MAIN "android-logcat-text-main"
# define INTERFACE_ANDROID_LOGCAT_TEXT_SYSTEM "android-logcat-text-system"
# define INTERFACE_ANDROID_LOGCAT_TEXT_RADIO "android-logcat-text-radio"
# define INTERFACE_ANDROID_LOGCAT_TEXT_EVENTS "android-logcat-text-events"
# define INTERFACE_ANDROID_LOGCAT_TEXT_CRASH "android-logcat-text-crash"
# define INTERFACE_ANDROID_BLUETOOTH_HCIDUMP "android-bluetooth-hcidump"
# define INTERFACE_ANDROID_BLUETOOTH_EXTERNAL_PARSER "android-bluetooth-external-parser"
# define INTERFACE_ANDROID_BLUETOOTH_BTSNOOP_NET "android-bluetooth-btsnoop-net"
2015-09-07 09:37:20 +00:00
# define INTERFACE_ANDROID_WIFI_TCPDUMP "android-wifi-tcpdump"
2015-02-14 18:10:21 +00:00
2016-02-23 10:12:17 +00:00
# define ANDROIDDUMP_VERSION_MAJOR "1"
2017-01-28 18:16:15 +00:00
# define ANDROIDDUMP_VERSION_MINOR "1"
# define ANDROIDDUMP_VERSION_RELEASE "0"
2015-11-29 16:58:39 +00:00
2016-04-08 09:49:36 +00:00
# define SERIAL_NUMBER_LENGTH_MAX 512
# define MODEL_NAME_LENGTH_MAX 64
2015-02-14 18:10:21 +00:00
# define PACKET_LENGTH 65535
2017-01-23 14:51:58 +00:00
# define SOCKET_RW_TIMEOUT_MS 500
# define SOCKET_CONNECT_TIMEOUT_TRIES 10
# define SOCKET_CONNECT_DELAY_US 1000 /* (1000us = 1ms) * SOCKET_CONNECT_TIMEOUT_TRIES (10) = 10ms worst-case */
2016-11-10 08:10:44 +00:00
2016-03-12 18:24:56 +00:00
enum exit_code {
EXIT_CODE_SUCCESS = 0 ,
EXIT_CODE_CANNOT_GET_INTERFACES_LIST = 1 ,
EXIT_CODE_UNKNOWN_ENCAPSULATION_WIRETAP ,
EXIT_CODE_UNKNOWN_ENCAPSULATION_LIBPCAP ,
EXIT_CODE_CANNOT_SAVE_WIRETAP_DUMP ,
EXIT_CODE_CANNOT_SAVE_LIBPCAP_DUMP ,
EXIT_CODE_NO_INTERFACE_SPECIFIED ,
EXIT_CODE_INVALID_INTERFACE ,
EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_1 ,
EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_2 ,
EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_3 ,
EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_4 ,
EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_5 ,
EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_6 ,
EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_7 ,
EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_8 ,
EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_9 ,
EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_10 ,
EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_11 ,
EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_12 ,
EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_13 ,
EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_14 ,
EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_15 ,
EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_16 ,
EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_17 ,
EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_18 ,
EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_19 ,
EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_20 ,
EXIT_CODE_ERROR_WHILE_SENDING_ADB_PACKET_1 ,
EXIT_CODE_ERROR_WHILE_SENDING_ADB_PACKET_2 ,
EXIT_CODE_ERROR_WHILE_SENDING_ADB_PACKET_3 ,
EXIT_CODE_ERROR_WHILE_SENDING_ADB_PACKET_4 ,
EXIT_CODE_ERROR_WHILE_RECEIVING_ADB_PACKET_STATUS ,
EXIT_CODE_ERROR_WHILE_RECEIVING_ADB_PACKET_DATA ,
EXIT_CODE_INVALID_SOCKET_INTERFACES_LIST ,
EXIT_CODE_INVALID_SOCKET_1 ,
EXIT_CODE_INVALID_SOCKET_2 ,
EXIT_CODE_INVALID_SOCKET_3 ,
EXIT_CODE_INVALID_SOCKET_4 ,
EXIT_CODE_INVALID_SOCKET_5 ,
EXIT_CODE_INVALID_SOCKET_6 ,
EXIT_CODE_INVALID_SOCKET_7 ,
EXIT_CODE_INVALID_SOCKET_8 ,
EXIT_CODE_INVALID_SOCKET_9 ,
EXIT_CODE_INVALID_SOCKET_10 ,
EXIT_CODE_INVALID_SOCKET_11 ,
EXIT_CODE_GENERIC = - 1
} ;
2015-02-14 18:10:21 +00:00
enum {
2016-02-22 15:12:44 +00:00
EXTCAP_BASE_OPTIONS_ENUM ,
OPT_HELP ,
2015-02-14 18:10:21 +00:00
OPT_VERSION ,
OPT_CONFIG_ADB_SERVER_IP ,
OPT_CONFIG_ADB_SERVER_TCP_PORT ,
OPT_CONFIG_LOGCAT_TEXT ,
2017-01-28 18:16:15 +00:00
OPT_CONFIG_LOGCAT_IGNORE_LOG_BUFFER ,
OPT_CONFIG_LOGCAT_CUSTOM_OPTIONS ,
2015-02-14 18:10:21 +00:00
OPT_CONFIG_BT_SERVER_TCP_PORT ,
OPT_CONFIG_BT_FORWARD_SOCKET ,
OPT_CONFIG_BT_LOCAL_IP ,
OPT_CONFIG_BT_LOCAL_TCP_PORT
} ;
static struct option longopts [ ] = {
2016-02-22 15:12:44 +00:00
EXTCAP_BASE_OPTIONS ,
2017-01-28 18:16:15 +00:00
{ " help " , no_argument , NULL , OPT_HELP } ,
{ " version " , no_argument , NULL , OPT_VERSION } ,
{ " adb-server-ip " , required_argument , NULL , OPT_CONFIG_ADB_SERVER_IP } ,
{ " adb-server-tcp-port " , required_argument , NULL , OPT_CONFIG_ADB_SERVER_TCP_PORT } ,
{ " logcat-text " , optional_argument , NULL , OPT_CONFIG_LOGCAT_TEXT } ,
{ " logcat-ignore-log-buffer " , optional_argument , NULL , OPT_CONFIG_LOGCAT_IGNORE_LOG_BUFFER } ,
{ " logcat-custom-options " , required_argument , NULL , OPT_CONFIG_LOGCAT_CUSTOM_OPTIONS } ,
{ " bt-server-tcp-port " , required_argument , NULL , OPT_CONFIG_BT_SERVER_TCP_PORT } ,
{ " bt-forward-socket " , required_argument , NULL , OPT_CONFIG_BT_FORWARD_SOCKET } ,
{ " bt-local-ip " , required_argument , NULL , OPT_CONFIG_BT_LOCAL_IP } ,
{ " bt-local-tcp-port " , required_argument , NULL , OPT_CONFIG_BT_LOCAL_TCP_PORT } ,
2015-02-14 18:10:21 +00:00
{ 0 , 0 , 0 , 0 }
} ;
struct interface_t {
const char * display_name ;
const char * interface_name ;
struct interface_t * next ;
} ;
struct exported_pdu_header {
uint16_t tag ;
uint16_t length ;
/* unsigned char value[0]; */
} ;
typedef struct _own_pcap_bluetooth_h4_header {
uint32_t direction ;
} own_pcap_bluetooth_h4_header ;
2015-09-07 09:37:20 +00:00
typedef struct pcaprec_hdr_s {
guint32 ts_sec ; /* timestamp seconds */
guint32 ts_usec ; /* timestamp microseconds */
guint32 incl_len ; /* number of octets of packet saved in file */
guint32 orig_len ; /* actual length of packet */
} pcaprec_hdr_t ;
2015-02-14 18:10:21 +00:00
/* This fix compilator warning like "warning: cast from 'char *' to 'uint32_t *' (aka 'unsigned int *') increases required alignment from 1 to 4 " */
typedef union {
char * value_char ;
uint8_t * value_u8 ;
uint16_t * value_u16 ;
uint32_t * value_u32 ;
uint64_t * value_u64 ;
int8_t * value_i8 ;
int16_t * value_i16 ;
int32_t * value_i32 ;
int64_t * value_i64 ;
own_pcap_bluetooth_h4_header * value_own_pcap_bluetooth_h4_header ;
} data_aligned_t ;
# define SET_DATA(dest, type, src) \
{ \
data_aligned_t data_aligned ; \
\
data_aligned . value_char = src ; \
dest = data_aligned . type ; \
}
struct extcap_dumper {
int encap ;
union {
# ifdef ANDROIDDUMP_USE_LIBPCAP
pcap_dumper_t * pcap ;
# else
wtap_dumper * wtap ;
# endif
} dumper ;
} ;
/* Globals */
static int endless_loop = 1 ;
/* Functions */
static inline int is_specified_interface ( char * interface , const char * interface_prefix ) {
return ! strncmp ( interface , interface_prefix , strlen ( interface_prefix ) ) ;
}
2016-11-10 08:10:44 +00:00
static void useSndTimeout ( socket_handle_t sock ) {
2016-11-17 10:33:02 +00:00
int res ;
2016-11-10 08:10:44 +00:00
# ifdef _WIN32
2017-01-23 14:51:58 +00:00
const DWORD socket_timeout = SOCKET_RW_TIMEOUT_MS ;
2016-11-10 08:10:44 +00:00
2017-01-26 07:15:13 +00:00
res = setsockopt ( sock , SOL_SOCKET , SO_SNDTIMEO , ( const char * ) & socket_timeout , ( socklen_t ) sizeof ( socket_timeout ) ) ;
2016-11-10 08:10:44 +00:00
# else
const struct timeval socket_timeout = {
2017-01-23 14:51:58 +00:00
. tv_sec = SOCKET_RW_TIMEOUT_MS / 1000 ,
. tv_usec = ( SOCKET_RW_TIMEOUT_MS % 1000 ) * 1000
2016-11-10 08:10:44 +00:00
} ;
2017-01-26 07:15:13 +00:00
res = setsockopt ( sock , SOL_SOCKET , SO_SNDTIMEO , & socket_timeout , ( socklen_t ) sizeof ( socket_timeout ) ) ;
2016-11-10 08:10:44 +00:00
# endif
2016-11-17 10:33:02 +00:00
if ( res ! = 0 )
g_debug ( " Can't set socket timeout, using default " ) ;
2016-11-10 08:10:44 +00:00
}
2017-01-23 14:51:58 +00:00
static void useNonBlockingConnectTimeout ( socket_handle_t sock ) {
int res_snd ;
int res_rcv ;
# ifdef _WIN32
const DWORD socket_timeout = SOCKET_RW_TIMEOUT_MS ;
2017-02-26 01:49:43 +00:00
unsigned long non_blocking = 1 ;
2017-01-23 14:51:58 +00:00
res_snd = setsockopt ( sock , SOL_SOCKET , SO_SNDTIMEO , ( const char * ) & socket_timeout , sizeof ( socket_timeout ) ) ;
res_rcv = setsockopt ( sock , SOL_SOCKET , SO_RCVTIMEO , ( const char * ) & socket_timeout , sizeof ( socket_timeout ) ) ;
2017-02-26 01:49:43 +00:00
/* set socket to non-blocking */
ioctlsocket ( sock , FIONBIO , & non_blocking ) ;
2017-01-23 14:51:58 +00:00
# else
const struct timeval socket_timeout = {
. tv_sec = SOCKET_RW_TIMEOUT_MS / 1000 ,
. tv_usec = ( SOCKET_RW_TIMEOUT_MS % 1000 ) * 1000
} ;
res_snd = setsockopt ( sock , SOL_SOCKET , SO_SNDTIMEO , & socket_timeout , sizeof ( socket_timeout ) ) ;
res_rcv = setsockopt ( sock , SOL_SOCKET , SO_RCVTIMEO , & socket_timeout , sizeof ( socket_timeout ) ) ;
# endif
if ( res_snd ! = 0 )
g_debug ( " Can't set socket timeout, using default " ) ;
if ( res_rcv ! = 0 )
g_debug ( " Can't set socket timeout, using default " ) ;
}
static void useNormalConnectTimeout ( socket_handle_t sock ) {
int res_rcv ;
# ifdef _WIN32
const DWORD socket_timeout = 0 ;
2017-02-27 06:44:39 +00:00
unsigned long non_blocking = 0 ;
2017-01-23 14:51:58 +00:00
res_rcv = setsockopt ( sock , SOL_SOCKET , SO_RCVTIMEO , ( const char * ) & socket_timeout , sizeof ( socket_timeout ) ) ;
2017-02-27 06:44:39 +00:00
ioctlsocket ( sock , FIONBIO , & non_blocking ) ;
2017-01-23 14:51:58 +00:00
# else
const struct timeval socket_timeout = {
. tv_sec = SOCKET_RW_TIMEOUT_MS / 1000 ,
. tv_usec = ( SOCKET_RW_TIMEOUT_MS % 1000 ) * 1000
} ;
res_rcv = setsockopt ( sock , SOL_SOCKET , SO_RCVTIMEO , & socket_timeout , sizeof ( socket_timeout ) ) ;
# endif
if ( res_rcv ! = 0 )
g_debug ( " Can't set socket timeout, using default " ) ;
}
2015-02-14 18:10:21 +00:00
static struct extcap_dumper extcap_dumper_open ( char * fifo , int encap ) {
struct extcap_dumper extcap_dumper ;
int encap_ext ;
# ifdef ANDROIDDUMP_USE_LIBPCAP
pcap_t * pcap ;
if ( encap = = EXTCAP_ENCAP_BLUETOOTH_H4_WITH_PHDR )
encap_ext = DLT_BLUETOOTH_H4_WITH_PHDR ;
else if ( encap = = EXTCAP_ENCAP_WIRESHARK_UPPER_PDU )
encap_ext = DLT_WIRESHARK_UPPER_PDU ;
2015-09-07 09:37:20 +00:00
else if ( encap = = EXTCAP_ENCAP_ETHERNET )
encap_ext = DLT_EN10MB ;
2015-02-14 18:10:21 +00:00
else {
2016-08-02 20:39:28 +00:00
g_warning ( " Unknown encapsulation " ) ;
2016-03-12 18:24:56 +00:00
exit ( EXIT_CODE_UNKNOWN_ENCAPSULATION_LIBPCAP ) ;
2015-02-14 18:10:21 +00:00
}
pcap = pcap_open_dead_with_tstamp_precision ( encap_ext , PACKET_LENGTH , PCAP_TSTAMP_PRECISION_NANO ) ;
extcap_dumper . dumper . pcap = pcap_dump_open ( pcap , fifo ) ;
2015-06-18 07:10:55 +00:00
if ( ! extcap_dumper . dumper . pcap ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Cannot save lipcap dump file " ) ;
2016-03-12 18:24:56 +00:00
exit ( EXIT_CODE_CANNOT_SAVE_LIBPCAP_DUMP ) ;
2015-06-18 07:10:55 +00:00
}
2015-02-14 18:10:21 +00:00
extcap_dumper . encap = encap ;
pcap_dump_flush ( extcap_dumper . dumper . pcap ) ;
# else
int err = 0 ;
2016-12-04 21:42:07 +00:00
wtap_init ( ) ;
2016-03-13 18:04:06 +00:00
# ifdef HAVE_PLUGINS
register_all_wiretap_modules ( ) ;
# endif
2015-02-14 18:10:21 +00:00
if ( encap = = EXTCAP_ENCAP_BLUETOOTH_H4_WITH_PHDR )
encap_ext = WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR ;
else if ( encap = = EXTCAP_ENCAP_WIRESHARK_UPPER_PDU )
encap_ext = WTAP_ENCAP_WIRESHARK_UPPER_PDU ;
2015-09-07 09:37:20 +00:00
else if ( encap = = EXTCAP_ENCAP_ETHERNET )
encap_ext = WTAP_ENCAP_ETHERNET ;
2015-02-14 18:10:21 +00:00
else {
2016-08-02 20:39:28 +00:00
g_warning ( " Unknown Wiretap encapsulation " ) ;
2016-03-12 18:24:56 +00:00
exit ( EXIT_CODE_UNKNOWN_ENCAPSULATION_WIRETAP ) ;
2015-02-14 18:10:21 +00:00
}
extcap_dumper . dumper . wtap = wtap_dump_open ( fifo , WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC , encap_ext , PACKET_LENGTH , FALSE , & err ) ;
2015-06-18 07:10:55 +00:00
if ( ! extcap_dumper . dumper . wtap ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Cannot save dump file " ) ;
2016-03-12 18:24:56 +00:00
exit ( EXIT_CODE_CANNOT_SAVE_WIRETAP_DUMP ) ;
2015-06-18 07:10:55 +00:00
}
2015-02-14 18:10:21 +00:00
extcap_dumper . encap = encap ;
wtap_dump_flush ( extcap_dumper . dumper . wtap ) ;
# endif
return extcap_dumper ;
}
2015-11-29 16:45:12 +00:00
static gboolean extcap_dumper_dump ( struct extcap_dumper extcap_dumper , char * buffer ,
2015-08-05 15:30:47 +00:00
gssize captured_length , gssize reported_length ,
2015-11-09 13:49:20 +00:00
time_t seconds , int nanoseconds ) {
2015-02-14 18:10:21 +00:00
# ifdef ANDROIDDUMP_USE_LIBPCAP
struct pcap_pkthdr pcap_header ;
pcap_header . caplen = ( bpf_u_int32 ) captured_length ;
pcap_header . len = ( bpf_u_int32 ) reported_length ;
pcap_header . ts . tv_sec = seconds ;
pcap_header . ts . tv_usec = nanoseconds / 1000 ;
pcap_dump ( ( u_char * ) extcap_dumper . dumper . pcap , & pcap_header , buffer ) ;
pcap_dump_flush ( extcap_dumper . dumper . pcap ) ;
# else
int err = 0 ;
char * err_info ;
struct wtap_pkthdr hdr ;
hdr . presence_flags = WTAP_HAS_TS ;
hdr . caplen = ( guint32 ) captured_length ;
hdr . len = ( guint32 ) reported_length ;
hdr . ts . secs = seconds ;
hdr . ts . nsecs = ( int ) nanoseconds ;
hdr . opt_comment = 0 ;
hdr . opt_comment = NULL ;
hdr . drop_count = 0 ;
hdr . pack_flags = 0 ;
hdr . rec_type = REC_TYPE_PACKET ;
/* NOTE: Try to handle pseudoheaders manually */
if ( extcap_dumper . encap = = EXTCAP_ENCAP_BLUETOOTH_H4_WITH_PHDR ) {
uint32_t * direction ;
SET_DATA ( direction , value_u32 , buffer )
hdr . pseudo_header . bthci . sent = GINT32_FROM_BE ( * direction ) ? 0 : 1 ;
2015-04-11 20:13:09 +00:00
hdr . len - = ( guint32 ) sizeof ( own_pcap_bluetooth_h4_header ) ;
hdr . caplen - = ( guint32 ) sizeof ( own_pcap_bluetooth_h4_header ) ;
2015-02-14 18:10:21 +00:00
buffer + = sizeof ( own_pcap_bluetooth_h4_header ) ;
hdr . pkt_encap = WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR ;
2015-09-07 09:37:20 +00:00
}
else if ( extcap_dumper . encap = = EXTCAP_ENCAP_ETHERNET ) {
hdr . pkt_encap = WTAP_ENCAP_ETHERNET ;
}
else {
2015-02-14 18:10:21 +00:00
hdr . pkt_encap = WTAP_ENCAP_WIRESHARK_UPPER_PDU ;
}
2015-11-29 16:45:12 +00:00
if ( ! wtap_dump ( extcap_dumper . dumper . wtap , & hdr , ( const guint8 * ) buffer , & err , & err_info ) ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Cannot dump: %s " , err_info ) ;
2015-11-29 16:45:12 +00:00
return FALSE ;
}
2015-02-14 18:10:21 +00:00
wtap_dump_flush ( extcap_dumper . dumper . wtap ) ;
# endif
2015-11-29 16:45:12 +00:00
return TRUE ;
2015-02-14 18:10:21 +00:00
}
2015-04-08 14:09:03 +00:00
static socket_handle_t adb_connect ( const char * server_ip , unsigned short * server_tcp_port ) {
2016-08-02 20:39:28 +00:00
socket_handle_t sock ;
socklen_t length ;
struct sockaddr_in server ;
struct sockaddr_in client ;
2017-01-23 14:51:58 +00:00
int status ;
int tries = 0 ;
2015-02-14 18:10:21 +00:00
2015-09-21 14:06:36 +00:00
memset ( & server , 0x0 , sizeof ( server ) ) ;
2015-02-14 18:10:21 +00:00
server . sin_family = AF_INET ;
server . sin_port = GINT16_TO_BE ( * server_tcp_port ) ;
server . sin_addr . s_addr = inet_addr ( server_ip ) ;
2015-04-08 14:09:03 +00:00
if ( ( sock = socket ( AF_INET , SOCK_STREAM , IPPROTO_TCP ) ) = = INVALID_SOCKET ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Cannot open system TCP socket: %s " , strerror ( errno ) ) ;
2015-04-08 14:09:03 +00:00
return INVALID_SOCKET ;
2015-02-14 18:10:21 +00:00
}
2017-01-23 14:51:58 +00:00
useNonBlockingConnectTimeout ( sock ) ;
while ( tries < SOCKET_CONNECT_TIMEOUT_TRIES ) {
status = connect ( sock , ( struct sockaddr * ) & server , ( socklen_t ) sizeof ( server ) ) ;
tries + = 1 ;
if ( status ! = SOCKET_ERROR )
break ;
g_usleep ( SOCKET_CONNECT_DELAY_US ) ;
}
useNormalConnectTimeout ( sock ) ;
2016-11-10 08:10:44 +00:00
2017-01-23 14:51:58 +00:00
if ( status = = SOCKET_ERROR ) {
2015-04-12 16:44:07 +00:00
#if 0
/* NOTE: This does not work well - make significant delay while initializing Wireshark.
Do fork ( ) then call " adb " also does not make sense , because there is need to
do something like sleep ( 1 ) to ensure adb is started . . . system ( ) cannot be used
on Windows , because open console window . This helper does not work as expected ,
so disable it and user must ensure that adb is started ( adb start - server ,
but also all other command start - server automatically )
*/
2015-04-08 14:09:03 +00:00
# ifdef _WIN32
if ( _execlp ( " adb " , " adb " , " start-server " , NULL ) ) {
# else
if ( execlp ( " adb " , " adb " , " start-server " , NULL ) ) {
# endif
2016-02-22 15:12:44 +00:00
errmsg ( " WARNING: Cannot execute system command to start adb: %s " , strerror ( errno ) ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2015-04-08 14:09:03 +00:00
return INVALID_SOCKET ;
2015-02-14 18:10:21 +00:00
} ;
2017-01-26 07:15:13 +00:00
if ( connect ( sock , ( struct sockaddr * ) & server , ( socklen_t ) sizeof ( server ) ) = = SOCKET_ERROR ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Cannot connect to ADB: <%s> Please check that adb daemon is running. " , strerror ( errno ) ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2015-04-08 14:09:03 +00:00
return INVALID_SOCKET ;
2015-02-14 18:10:21 +00:00
}
2015-04-12 16:44:07 +00:00
# else
2016-08-02 20:39:28 +00:00
g_debug ( " Cannot connect to ADB: <%s> Please check that adb daemon is running. " , strerror ( errno ) ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2015-04-12 16:44:07 +00:00
return INVALID_SOCKET ;
# endif
2015-02-14 18:10:21 +00:00
}
2016-08-02 20:39:28 +00:00
length = sizeof ( client ) ;
if ( getsockname ( sock , ( struct sockaddr * ) & client , & length ) ) {
g_warning ( " getsockname: %s " , strerror ( errno ) ) ;
closesocket ( sock ) ;
return INVALID_SOCKET ;
}
2015-02-14 18:10:21 +00:00
2016-08-02 20:39:28 +00:00
if ( length ! = sizeof ( client ) ) {
g_warning ( " incorrect length " ) ;
closesocket ( sock ) ;
return INVALID_SOCKET ;
2015-02-14 18:10:21 +00:00
}
2016-08-02 20:39:28 +00:00
g_debug ( " Client port %u " , GUINT16_FROM_BE ( client . sin_port ) ) ;
2015-02-14 18:10:21 +00:00
return sock ;
}
2015-04-08 14:09:03 +00:00
static char * adb_send_and_receive ( socket_handle_t sock , const char * adb_service ,
2016-09-16 18:40:31 +00:00
char * buffer , size_t buffer_length , size_t * data_length ) {
size_t used_buffer_length ;
size_t bytes_to_read ;
2016-09-16 17:41:11 +00:00
guint32 length ;
2015-08-05 15:30:47 +00:00
gssize result ;
2015-02-14 18:10:21 +00:00
char status [ 4 ] ;
2015-08-05 15:30:47 +00:00
char tmp_buffer ;
2015-12-01 18:02:04 +00:00
size_t adb_service_length ;
2015-02-14 18:10:21 +00:00
2015-12-01 18:02:04 +00:00
adb_service_length = strlen ( adb_service ) ;
2016-09-16 18:40:31 +00:00
if ( adb_service_length > INT_MAX ) {
g_warning ( " Service name too long when sending <%s> to ADB daemon " , adb_service ) ;
if ( data_length )
* data_length = 0 ;
return NULL ;
}
/* 8 bytes of hex length + terminating NUL */
if ( buffer_length < 9 ) {
g_warning ( " Buffer for response too short while sending <%s> to ADB daemon " , adb_service ) ;
if ( data_length )
* data_length = 0 ;
return NULL ;
}
2015-12-01 18:02:04 +00:00
result = send ( sock , adb_service , ( int ) adb_service_length , 0 ) ;
if ( result ! = ( gssize ) adb_service_length ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while sending <%s> to ADB daemon " , adb_service ) ;
2015-02-14 18:10:21 +00:00
if ( data_length )
* data_length = 0 ;
2016-03-12 18:24:56 +00:00
return NULL ;
2015-02-14 18:10:21 +00:00
}
used_buffer_length = 0 ;
while ( used_buffer_length < 8 ) {
2016-09-16 18:40:31 +00:00
bytes_to_read = buffer_length - used_buffer_length ;
if ( bytes_to_read > INT_MAX )
bytes_to_read = INT_MAX ;
result = recv ( sock , buffer + used_buffer_length , ( int ) bytes_to_read , 0 ) ;
2016-02-06 18:14:20 +00:00
if ( result < = 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Broken socket connection while fetching reply status for <%s> " , adb_service ) ;
2016-09-16 18:40:31 +00:00
if ( data_length )
* data_length = 0 ;
2016-03-12 18:24:56 +00:00
return NULL ;
2016-02-06 18:14:20 +00:00
}
used_buffer_length + = result ;
2015-02-14 18:10:21 +00:00
}
memcpy ( status , buffer , 4 ) ;
2015-08-05 15:30:47 +00:00
tmp_buffer = buffer [ 8 ] ;
2015-02-14 18:10:21 +00:00
buffer [ 8 ] = ' \0 ' ;
2016-09-16 17:41:11 +00:00
if ( ! ws_hexstrtou32 ( buffer + 4 , NULL , & length ) ) {
g_warning ( " Invalid reply length <%s> while reading reply for <%s> " , buffer + 4 , adb_service ) ;
2016-09-16 18:40:31 +00:00
if ( data_length )
* data_length = 0 ;
2016-09-16 17:41:11 +00:00
return NULL ;
}
2015-08-05 15:30:47 +00:00
buffer [ 8 ] = tmp_buffer ;
2015-02-14 18:10:21 +00:00
2016-09-16 18:40:31 +00:00
if ( buffer_length < length + 8 ) {
g_warning ( " Buffer for response too short while sending <%s> to ADB daemon " , adb_service ) ;
if ( data_length )
* data_length = 0 ;
return NULL ;
}
2015-02-14 18:10:21 +00:00
while ( used_buffer_length < length + 8 ) {
2016-09-16 18:40:31 +00:00
bytes_to_read = buffer_length - used_buffer_length ;
if ( bytes_to_read > INT_MAX )
bytes_to_read = INT_MAX ;
result = recv ( sock , buffer + used_buffer_length , ( int ) bytes_to_read , 0 ) ;
2016-02-06 18:14:20 +00:00
if ( result < = 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Broken socket connection while reading reply for <%s> " , adb_service ) ;
2016-09-16 18:40:31 +00:00
if ( data_length )
* data_length = 0 ;
2016-03-12 18:24:56 +00:00
return NULL ;
2016-02-06 18:14:20 +00:00
}
used_buffer_length + = result ;
2015-02-14 18:10:21 +00:00
}
if ( data_length )
* data_length = used_buffer_length - 8 ;
if ( memcmp ( status , " OKAY " , 4 ) ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while receiving by ADB for <%s> " , adb_service ) ;
2015-02-14 18:10:21 +00:00
if ( data_length )
* data_length = 0 ;
2016-03-12 18:24:56 +00:00
return NULL ;
2015-02-14 18:10:21 +00:00
}
return buffer + 8 ;
}
2015-04-08 14:09:03 +00:00
static char * adb_send_and_read ( socket_handle_t sock , const char * adb_service , char * buffer ,
2015-08-05 15:30:47 +00:00
int buffer_length , gssize * data_length ) {
gssize used_buffer_length ;
gssize result ;
2015-02-14 18:10:21 +00:00
char status [ 4 ] ;
2015-12-01 18:02:04 +00:00
size_t adb_service_length ;
adb_service_length = strlen ( adb_service ) ;
2015-02-14 18:10:21 +00:00
2015-12-17 19:33:15 +00:00
result = send ( sock , adb_service , ( int ) adb_service_length , 0 ) ;
2015-12-01 18:02:04 +00:00
if ( result ! = ( gssize ) adb_service_length ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while sending <%s> to ADB " , adb_service ) ;
2015-02-14 18:10:21 +00:00
if ( data_length )
* data_length = 0 ;
2016-03-12 18:24:56 +00:00
return NULL ;
2015-02-14 18:10:21 +00:00
}
used_buffer_length = 0 ;
while ( used_buffer_length < 4 ) {
2016-02-06 18:14:20 +00:00
result = recv ( sock , buffer + used_buffer_length , ( int ) ( buffer_length - used_buffer_length ) , 0 ) ;
if ( result < = 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Broken socket connection while fetching reply status for <%s> " , adb_service ) ;
2016-02-06 18:14:20 +00:00
2016-03-12 18:24:56 +00:00
return NULL ;
2016-02-06 18:14:20 +00:00
}
used_buffer_length + = result ;
2015-02-14 18:10:21 +00:00
}
memcpy ( status , buffer , 4 ) ;
while ( result > 0 ) {
2015-08-05 15:30:47 +00:00
result = recv ( sock , buffer + used_buffer_length , ( int ) ( buffer_length - used_buffer_length ) , 0 ) ;
2016-02-06 18:14:20 +00:00
if ( result < 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Broken socket connection while reading reply for <%s> " , adb_service ) ;
2016-02-06 18:14:20 +00:00
2016-03-12 18:24:56 +00:00
return NULL ;
2016-02-06 18:14:20 +00:00
} else if ( result = = 0 ) {
break ;
}
used_buffer_length + = result ;
2015-02-14 18:10:21 +00:00
}
if ( data_length )
* data_length = used_buffer_length - 4 ;
if ( memcmp ( status , " OKAY " , 4 ) ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while receiving by ADB for <%s> " , adb_service ) ;
2015-02-14 18:10:21 +00:00
if ( data_length )
* data_length = 0 ;
2016-03-12 18:24:56 +00:00
return NULL ;
2015-02-14 18:10:21 +00:00
}
return buffer + 4 ;
}
2015-04-08 14:09:03 +00:00
static int adb_send ( socket_handle_t sock , const char * adb_service ) {
2015-02-14 18:10:21 +00:00
char buffer [ 4 ] ;
2015-08-05 15:30:47 +00:00
gssize used_buffer_length ;
gssize result ;
2015-12-01 18:02:04 +00:00
size_t adb_service_length ;
2015-02-14 18:10:21 +00:00
2015-12-01 18:02:04 +00:00
adb_service_length = strlen ( adb_service ) ;
result = send ( sock , adb_service , ( int ) adb_service_length , 0 ) ;
if ( result ! = ( gssize ) adb_service_length ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while sending <%s> to ADB " , adb_service ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_ERROR_WHILE_SENDING_ADB_PACKET_1 ;
2015-02-14 18:10:21 +00:00
}
used_buffer_length = 0 ;
while ( used_buffer_length < 4 ) {
2016-02-06 18:14:20 +00:00
result = recv ( sock , buffer + used_buffer_length , ( int ) ( sizeof ( buffer ) - used_buffer_length ) , 0 ) ;
if ( result < = 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Broken socket connection while fetching reply status for <%s> " , adb_service ) ;
2016-02-06 18:14:20 +00:00
2016-03-12 18:24:56 +00:00
return EXIT_CODE_ERROR_WHILE_RECEIVING_ADB_PACKET_STATUS ;
2016-02-06 18:14:20 +00:00
}
used_buffer_length + = result ;
2015-02-14 18:10:21 +00:00
}
if ( memcmp ( buffer , " OKAY " , 4 ) ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while receiving by ADB for <%s> " , adb_service ) ;
2016-02-06 18:14:20 +00:00
2016-03-12 18:24:56 +00:00
return EXIT_CODE_ERROR_WHILE_RECEIVING_ADB_PACKET_DATA ;
2015-02-14 18:10:21 +00:00
}
2016-03-12 18:24:56 +00:00
return EXIT_CODE_SUCCESS ;
2015-02-14 18:10:21 +00:00
}
2016-02-23 10:12:17 +00:00
static void new_interface ( extcap_parameters * extcap_conf , const gchar * interface_id ,
2016-04-08 09:49:36 +00:00
const gchar * model_name , const gchar * serial_number , const gchar * display_name )
2015-02-14 18:10:21 +00:00
{
2016-04-08 09:49:36 +00:00
char * interface = g_strdup_printf ( " %s-%s " , interface_id , serial_number ) ;
char * ifdisplay = g_strdup_printf ( " %s %s %s " , display_name , model_name , serial_number ) ;
2016-02-23 10:12:17 +00:00
if ( is_specified_interface ( interface , INTERFACE_ANDROID_BLUETOOTH_HCIDUMP ) | |
is_specified_interface ( interface , INTERFACE_ANDROID_BLUETOOTH_EXTERNAL_PARSER ) | |
is_specified_interface ( interface , INTERFACE_ANDROID_BLUETOOTH_BTSNOOP_NET ) ) {
extcap_base_register_interface_ext ( extcap_conf , interface , ifdisplay , 99 , " BluetoothH4 " , " Bluetooth HCI UART transport layer plus pseudo-header " ) ;
} else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_MAIN ) | |
is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_SYSTEM ) | |
is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_RADIO ) | |
is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_EVENTS ) | |
is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_TEXT_MAIN ) | |
is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_TEXT_SYSTEM ) | |
is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_TEXT_RADIO ) | |
is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_TEXT_EVENTS ) | |
is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_TEXT_CRASH ) ) {
extcap_base_register_interface ( extcap_conf , interface , ifdisplay , 252 , " Upper PDU " ) ;
} else if ( is_specified_interface ( interface , INTERFACE_ANDROID_WIFI_TCPDUMP ) ) {
extcap_base_register_interface ( extcap_conf , interface , ifdisplay , 1 , " Ethernet " ) ;
}
2016-06-15 15:45:54 +00:00
g_free ( interface ) ;
g_free ( ifdisplay ) ;
2015-11-29 16:58:39 +00:00
}
2016-02-23 10:12:17 +00:00
static int register_interfaces ( extcap_parameters * extcap_conf , const char * adb_server_ip , unsigned short * adb_server_tcp_port ) {
2015-02-14 18:10:21 +00:00
static char packet [ PACKET_LENGTH ] ;
static char helpful_packet [ PACKET_LENGTH ] ;
char * response ;
char * device_list ;
2015-08-05 15:30:47 +00:00
gssize data_length ;
2016-09-16 18:40:31 +00:00
size_t device_length ;
2015-04-08 14:09:03 +00:00
socket_handle_t sock ;
2015-02-14 18:10:21 +00:00
const char * adb_transport_serial_templace = " %04x " " host:transport:%s " ;
const char * adb_check_port_templace = " %04x " " shell:cat /proc/%s/net/tcp " ;
2016-04-08 09:49:36 +00:00
const char * adb_devices = " 000E " " host:devices-l " ;
2015-02-14 18:10:21 +00:00
const char * adb_api_level = " 0022 " " shell:getprop ro.build.version.sdk " ;
const char * adb_hcidump_version = " 0017 " " shell:hcidump --version " ;
const char * adb_ps_droid_bluetooth = " 0018 " " shell:ps droid.bluetooth " ;
2015-10-19 12:03:43 +00:00
const char * adb_ps_bluetooth_app = " 001E " " shell:ps com.android.bluetooth " ;
2016-11-03 09:46:25 +00:00
const char * adb_ps_with_grep = " 0025 " " shell:ps | grep com.android.bluetooth " ;
2015-09-07 09:37:20 +00:00
const char * adb_tcpdump_help = " 0010 " " shell:tcpdump -h " ;
2016-04-08 09:49:36 +00:00
char serial_number [ SERIAL_NUMBER_LENGTH_MAX ] ;
2015-12-01 18:02:04 +00:00
size_t serial_number_length ;
2016-04-08 09:49:36 +00:00
char model_name [ MODEL_NAME_LENGTH_MAX ] ;
2015-02-14 18:10:21 +00:00
int result ;
char * pos ;
2016-04-08 09:49:36 +00:00
char * i_pos ;
char * model_pos ;
char * device_pos ;
2015-02-14 18:10:21 +00:00
char * prev_pos ;
int api_level ;
int disable_interface ;
/* NOTE: It seems that "adb devices" and "adb shell" closed connection
so cannot send next command after them , there is need to reconnect */
sock = adb_connect ( adb_server_ip , adb_server_tcp_port ) ;
2015-04-08 14:09:03 +00:00
if ( sock = = INVALID_SOCKET )
2016-03-12 18:24:56 +00:00
return EXIT_CODE_INVALID_SOCKET_INTERFACES_LIST ;
2015-02-14 18:10:21 +00:00
device_list = adb_send_and_receive ( sock , adb_devices , packet , sizeof ( packet ) , & device_length ) ;
closesocket ( sock ) ;
2016-02-06 18:14:20 +00:00
if ( ! device_list ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Cannot get list of interfaces from devices " ) ;
2016-02-06 18:14:20 +00:00
2016-03-12 18:24:56 +00:00
return EXIT_CODE_CANNOT_GET_INTERFACES_LIST ;
2016-02-06 18:14:20 +00:00
}
2015-02-14 18:10:21 +00:00
device_list [ device_length ] = ' \0 ' ;
pos = ( char * ) device_list ;
while ( pos < ( char * ) ( device_list + device_length ) ) {
prev_pos = pos ;
2016-04-08 09:49:36 +00:00
pos = strchr ( pos , ' ' ) ;
i_pos = pos ;
2015-02-14 18:10:21 +00:00
result = ( int ) ( pos - prev_pos ) ;
2015-04-09 20:36:13 +00:00
pos = strchr ( pos , ' \n ' ) + 1 ;
2015-04-15 10:55:09 +00:00
if ( result > = ( int ) sizeof ( serial_number ) ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Serial number too long, ignore device " ) ;
2015-04-09 20:36:13 +00:00
continue ;
}
2015-02-14 18:10:21 +00:00
memcpy ( serial_number , prev_pos , result ) ;
serial_number [ result ] = ' \0 ' ;
2015-12-01 18:02:04 +00:00
serial_number_length = strlen ( serial_number ) ;
2015-02-14 18:10:21 +00:00
2016-04-08 09:49:36 +00:00
model_name [ 0 ] = ' \0 ' ;
model_pos = g_strstr_len ( i_pos , pos - i_pos , " model: " ) ;
if ( model_pos ) {
device_pos = g_strstr_len ( i_pos , pos - i_pos , " device: " ) ;
if ( device_pos & & device_pos - model_pos - 6 - 1 < MODEL_NAME_LENGTH_MAX ) {
memcpy ( model_name , model_pos + 6 , device_pos - model_pos - 6 - 1 ) ;
model_name [ device_pos - model_pos - 6 - 1 ] = ' \0 ' ;
}
}
if ( model_name [ 0 ] = = ' \0 ' )
strcpy ( model_name , " unknown " ) ;
2016-08-02 20:39:28 +00:00
g_debug ( " Processing device: \" %s \" <%s> " , serial_number , model_name ) ;
2016-02-06 18:14:20 +00:00
2015-09-07 09:37:20 +00:00
/* Check for the presence of tcpdump in the android device. */
2015-02-14 18:10:21 +00:00
sock = adb_connect ( adb_server_ip , adb_server_tcp_port ) ;
2015-09-07 09:37:20 +00:00
if ( sock = = INVALID_SOCKET ) continue ;
2015-11-29 16:45:12 +00:00
2016-03-14 07:09:54 +00:00
result = g_snprintf ( ( char * ) helpful_packet , PACKET_LENGTH , adb_transport_serial_templace , 15 + serial_number_length , serial_number ) ;
if ( result < = 0 | | result > PACKET_LENGTH ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while completing adb packet for transport " ) ;
2016-03-14 07:09:54 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_1 ;
2016-03-14 07:09:54 +00:00
}
2015-09-07 09:37:20 +00:00
result = adb_send ( sock , helpful_packet ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport for <%s> " , helpful_packet ) ;
2015-09-07 09:37:20 +00:00
closesocket ( sock ) ;
2016-02-06 18:14:20 +00:00
} else {
response = adb_send_and_read ( sock , adb_tcpdump_help , helpful_packet , sizeof ( helpful_packet ) , & data_length ) ;
closesocket ( sock ) ;
if ( response ) {
response [ data_length ] = ' \0 ' ;
2015-09-07 09:37:20 +00:00
2016-02-06 18:14:20 +00:00
/* If tcpdump is found in the android device, add Android Wifi Tcpdump as an interface */
if ( strstr ( response , " tcpdump version " ) ) {
2016-04-08 09:49:36 +00:00
new_interface ( extcap_conf , INTERFACE_ANDROID_WIFI_TCPDUMP , model_name , serial_number , " Android WiFi " ) ;
2016-02-06 18:14:20 +00:00
}
} else {
2016-08-02 20:39:28 +00:00
g_warning ( " Error on socket: <%s> " , helpful_packet ) ;
2016-02-06 18:14:20 +00:00
}
2015-09-07 09:37:20 +00:00
}
2015-02-14 18:10:21 +00:00
2015-09-07 09:37:20 +00:00
sock = adb_connect ( adb_server_ip , adb_server_tcp_port ) ;
2016-02-06 18:14:20 +00:00
if ( sock = = INVALID_SOCKET ) continue ;
2015-11-29 16:45:12 +00:00
2016-03-14 07:09:54 +00:00
result = g_snprintf ( ( char * ) helpful_packet , PACKET_LENGTH , adb_transport_serial_templace , 15 + serial_number_length , serial_number ) ;
if ( result < = 0 | | result > PACKET_LENGTH ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while completing adb packet " ) ;
2016-03-14 07:09:54 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_2 ;
2016-03-14 07:09:54 +00:00
}
2015-02-14 18:10:21 +00:00
result = adb_send ( sock , helpful_packet ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport for <%s> " , helpful_packet ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-02-06 18:14:20 +00:00
continue ;
2015-02-14 18:10:21 +00:00
}
response = adb_send_and_read ( sock , adb_api_level , helpful_packet , sizeof ( helpful_packet ) , & data_length ) ;
closesocket ( sock ) ;
2016-02-06 18:14:20 +00:00
if ( ! response ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error on socket: <%s> " , helpful_packet ) ;
2016-02-06 18:14:20 +00:00
continue ;
}
2015-02-14 18:10:21 +00:00
response [ data_length ] = ' \0 ' ;
2015-08-05 15:30:47 +00:00
api_level = ( int ) g_ascii_strtoll ( response , NULL , 10 ) ;
2016-08-02 20:39:28 +00:00
g_debug ( " Android API Level for %s is %i " , serial_number , api_level ) ;
2015-02-14 18:10:21 +00:00
if ( api_level < 21 ) {
2016-04-08 09:49:36 +00:00
new_interface ( extcap_conf , INTERFACE_ANDROID_LOGCAT_MAIN , model_name , serial_number , " Android Logcat Main " ) ;
new_interface ( extcap_conf , INTERFACE_ANDROID_LOGCAT_SYSTEM , model_name , serial_number , " Android Logcat System " ) ;
new_interface ( extcap_conf , INTERFACE_ANDROID_LOGCAT_RADIO , model_name , serial_number , " Android Logcat Radio " ) ;
new_interface ( extcap_conf , INTERFACE_ANDROID_LOGCAT_EVENTS , model_name , serial_number , " Android Logcat Events " ) ;
2017-01-28 18:16:15 +00:00
new_interface ( extcap_conf , INTERFACE_ANDROID_LOGCAT_TEXT_MAIN , model_name , serial_number , " Android Logcat Main " ) ;
new_interface ( extcap_conf , INTERFACE_ANDROID_LOGCAT_TEXT_SYSTEM , model_name , serial_number , " Android Logcat System " ) ;
new_interface ( extcap_conf , INTERFACE_ANDROID_LOGCAT_TEXT_RADIO , model_name , serial_number , " Android Logcat Radio " ) ;
new_interface ( extcap_conf , INTERFACE_ANDROID_LOGCAT_TEXT_EVENTS , model_name , serial_number , " Android Logcat Events " ) ;
2015-02-14 18:10:21 +00:00
} else {
2016-04-08 09:49:36 +00:00
new_interface ( extcap_conf , INTERFACE_ANDROID_LOGCAT_TEXT_MAIN , model_name , serial_number , " Android Logcat Main " ) ;
new_interface ( extcap_conf , INTERFACE_ANDROID_LOGCAT_TEXT_SYSTEM , model_name , serial_number , " Android Logcat System " ) ;
new_interface ( extcap_conf , INTERFACE_ANDROID_LOGCAT_TEXT_RADIO , model_name , serial_number , " Android Logcat Radio " ) ;
new_interface ( extcap_conf , INTERFACE_ANDROID_LOGCAT_TEXT_EVENTS , model_name , serial_number , " Android Logcat Events " ) ;
new_interface ( extcap_conf , INTERFACE_ANDROID_LOGCAT_TEXT_CRASH , model_name , serial_number , " Android Logcat Crash " ) ;
2015-02-14 18:10:21 +00:00
}
if ( api_level > = 5 & & api_level < 17 ) {
disable_interface = 0 ;
sock = adb_connect ( adb_server_ip , adb_server_tcp_port ) ;
2015-06-09 12:59:53 +00:00
if ( sock = = INVALID_SOCKET ) continue ;
2015-02-14 18:10:21 +00:00
2016-03-14 07:09:54 +00:00
result = g_snprintf ( ( char * ) helpful_packet , PACKET_LENGTH , adb_transport_serial_templace , 15 + serial_number_length , serial_number ) ;
if ( result < = 0 | | result > PACKET_LENGTH ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while completing adb packet " ) ;
2016-03-14 07:09:54 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_3 ;
2016-03-14 07:09:54 +00:00
}
2015-02-14 18:10:21 +00:00
result = adb_send ( sock , helpful_packet ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport for <%s> " , helpful_packet ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
response = adb_send_and_read ( sock , adb_hcidump_version , helpful_packet , sizeof ( helpful_packet ) , & data_length ) ;
closesocket ( sock ) ;
if ( ! response | | data_length < 1 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while getting hcidump version by <%s> (%p len=% " G_GSSIZE_FORMAT " ) " ,
2016-02-22 15:12:44 +00:00
adb_hcidump_version , ( void * ) response , data_length ) ;
2016-08-02 20:39:28 +00:00
g_debug ( " Android hcidump version for %s is unknown " , serial_number ) ;
2015-02-14 18:10:21 +00:00
disable_interface = 1 ;
} else {
response [ data_length ] = ' \0 ' ;
2015-08-05 15:30:47 +00:00
if ( g_ascii_strtoull ( response , NULL , 10 ) = = 0 ) {
2016-08-02 20:39:28 +00:00
g_debug ( " Android hcidump version for %s is unknown " , serial_number ) ;
2015-02-14 18:10:21 +00:00
disable_interface = 1 ;
} else {
2016-08-02 20:39:28 +00:00
g_debug ( " Android hcidump version for %s is %s " , serial_number , response ) ;
2015-02-14 18:10:21 +00:00
}
}
if ( ! disable_interface ) {
2016-04-08 09:49:36 +00:00
new_interface ( extcap_conf , INTERFACE_ANDROID_BLUETOOTH_HCIDUMP , model_name , serial_number , " Android Bluetooth Hcidump " ) ;
2015-02-14 18:10:21 +00:00
}
}
if ( api_level > = 17 & & api_level < 21 ) {
disable_interface = 0 ;
sock = adb_connect ( adb_server_ip , adb_server_tcp_port ) ;
2015-06-09 12:59:53 +00:00
if ( sock = = INVALID_SOCKET ) continue ;
2015-02-14 18:10:21 +00:00
2016-03-14 07:09:54 +00:00
result = g_snprintf ( ( char * ) helpful_packet , PACKET_LENGTH , adb_transport_serial_templace , 15 + serial_number_length , serial_number ) ;
if ( result < = 0 | | result > PACKET_LENGTH ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while completing adb packet " ) ;
2016-03-14 07:09:54 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_4 ;
2016-03-14 07:09:54 +00:00
}
2015-02-14 18:10:21 +00:00
result = adb_send ( sock , helpful_packet ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport for <%s> " , helpful_packet ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
response = adb_send_and_read ( sock , adb_ps_droid_bluetooth , helpful_packet , sizeof ( helpful_packet ) , & data_length ) ;
closesocket ( sock ) ;
if ( ! response | | data_length < 1 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while getting Bluetooth application process id by <%s> "
" (%p len=% " G_GSSIZE_FORMAT " ) " , adb_hcidump_version , ( void * ) response , data_length ) ;
g_debug ( " Android Bluetooth application PID for %s is unknown " , serial_number ) ;
2015-02-14 18:10:21 +00:00
disable_interface = 1 ;
} else {
char * data_str ;
char pid [ 16 ] ;
2016-01-21 08:23:42 +00:00
memset ( pid , 0 , sizeof ( pid ) ) ;
2015-02-14 18:10:21 +00:00
response [ data_length ] = ' \0 ' ;
data_str = strchr ( response , ' \n ' ) ;
if ( data_str & & sscanf ( data_str , " %*s %s " , pid ) = = 1 ) {
2016-08-02 20:39:28 +00:00
g_debug ( " Android Bluetooth application PID for %s is %s " , serial_number , pid ) ;
2015-02-14 18:10:21 +00:00
sock = adb_connect ( adb_server_ip , adb_server_tcp_port ) ;
2015-11-29 16:45:12 +00:00
if ( sock = = INVALID_SOCKET )
2016-03-12 18:24:56 +00:00
return EXIT_CODE_INVALID_SOCKET_1 ;
2015-02-14 18:10:21 +00:00
2016-03-14 07:09:54 +00:00
result = g_snprintf ( ( char * ) helpful_packet , PACKET_LENGTH , adb_transport_serial_templace , 15 + serial_number_length , serial_number ) ;
if ( result < = 0 | | result > PACKET_LENGTH ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while completing adb packet " ) ;
2016-03-14 07:09:54 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_5 ;
2016-03-14 07:09:54 +00:00
}
2015-02-14 18:10:21 +00:00
result = adb_send ( sock , helpful_packet ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport for <%s> " , helpful_packet ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
2016-03-14 07:09:54 +00:00
result = g_snprintf ( ( char * ) helpful_packet , PACKET_LENGTH , adb_check_port_templace , strlen ( adb_check_port_templace ) - 6 + strlen ( pid ) , pid ) ;
if ( result < = 0 | | result > PACKET_LENGTH ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while completing adb packet " ) ;
2016-03-14 07:09:54 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_6 ;
2016-03-14 07:09:54 +00:00
}
2015-02-14 18:10:21 +00:00
response = adb_send_and_read ( sock , helpful_packet , helpful_packet , sizeof ( helpful_packet ) , & data_length ) ;
closesocket ( sock ) ;
2016-02-06 18:14:20 +00:00
if ( ! response ) {
2015-02-14 18:10:21 +00:00
disable_interface = 1 ;
2016-02-06 18:14:20 +00:00
} else {
response [ data_length ] = ' \0 ' ;
data_str = strchr ( response , ' \n ' ) ;
if ( data_str & & sscanf ( data_str , " %*s %s " , pid ) = = 1 & & strcmp ( pid + 9 , " 10EA " ) = = 0 ) {
2016-08-02 20:39:28 +00:00
g_debug ( " Bluedroid External Parser Port for %s is %s " , serial_number , pid + 9 ) ;
2016-02-06 18:14:20 +00:00
} else {
disable_interface = 1 ;
2016-08-02 20:39:28 +00:00
g_debug ( " Bluedroid External Parser Port for %s is unknown " , serial_number ) ;
2016-02-06 18:14:20 +00:00
}
2015-02-14 18:10:21 +00:00
}
} else {
disable_interface = 1 ;
2016-08-02 20:39:28 +00:00
g_debug ( " Android Bluetooth application PID for %s is unknown " , serial_number ) ;
2015-02-14 18:10:21 +00:00
}
}
if ( ! disable_interface ) {
2016-04-08 09:49:36 +00:00
new_interface ( extcap_conf , INTERFACE_ANDROID_BLUETOOTH_EXTERNAL_PARSER , model_name , serial_number , " Android Bluetooth External Parser " ) ;
2015-02-14 18:10:21 +00:00
}
}
if ( api_level > = 21 ) {
disable_interface = 0 ;
sock = adb_connect ( adb_server_ip , adb_server_tcp_port ) ;
2015-06-09 12:59:53 +00:00
if ( sock = = INVALID_SOCKET ) continue ;
2015-02-14 18:10:21 +00:00
2016-03-14 07:09:54 +00:00
result = g_snprintf ( ( char * ) helpful_packet , PACKET_LENGTH , adb_transport_serial_templace , 15 + serial_number_length , serial_number ) ;
if ( result < = 0 | | result > PACKET_LENGTH ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while completing adb packet " ) ;
2016-03-14 07:09:54 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_7 ;
2016-03-14 07:09:54 +00:00
}
2015-02-14 18:10:21 +00:00
result = adb_send ( sock , helpful_packet ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport for <%s> " , helpful_packet ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
2016-11-03 09:46:25 +00:00
if ( api_level > = 24 ) {
response = adb_send_and_read ( sock , adb_ps_with_grep , helpful_packet , sizeof ( helpful_packet ) , & data_length ) ;
} else if ( api_level > = 23 ) {
2015-10-19 12:03:43 +00:00
response = adb_send_and_read ( sock , adb_ps_bluetooth_app , helpful_packet , sizeof ( helpful_packet ) , & data_length ) ;
} else
response = adb_send_and_read ( sock , adb_ps_droid_bluetooth , helpful_packet , sizeof ( helpful_packet ) , & data_length ) ;
2015-02-14 18:10:21 +00:00
closesocket ( sock ) ;
if ( ! response | | data_length < 1 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while getting Bluetooth application process id by <%s> "
" (%p len=% " G_GSSIZE_FORMAT " ) " , adb_hcidump_version , ( void * ) response , data_length ) ;
g_debug ( " Android Bluetooth application PID for %s is unknown " , serial_number ) ;
2015-02-14 18:10:21 +00:00
disable_interface = 1 ;
} else {
char * data_str ;
char pid [ 16 ] ;
2016-01-21 08:23:42 +00:00
memset ( pid , 0 , sizeof ( pid ) ) ;
2015-02-14 18:10:21 +00:00
response [ data_length ] = ' \0 ' ;
2016-11-03 09:46:25 +00:00
if ( api_level > = 24 )
data_str = response ;
else
data_str = strchr ( response , ' \n ' ) ;
2015-02-14 18:10:21 +00:00
if ( data_str & & sscanf ( data_str , " %*s %s " , pid ) = = 1 ) {
2016-08-02 20:39:28 +00:00
g_debug ( " Android Bluetooth application PID for %s is %s " , serial_number , pid ) ;
2015-02-14 18:10:21 +00:00
sock = adb_connect ( adb_server_ip , adb_server_tcp_port ) ;
2015-11-29 16:45:12 +00:00
if ( sock = = INVALID_SOCKET )
2016-03-12 18:24:56 +00:00
return EXIT_CODE_INVALID_SOCKET_2 ;
2015-02-14 18:10:21 +00:00
2016-03-14 07:09:54 +00:00
result = g_snprintf ( ( char * ) helpful_packet , PACKET_LENGTH , adb_transport_serial_templace , 15 + serial_number_length , serial_number ) ;
if ( result < = 0 | | result > PACKET_LENGTH ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while completing adb packet " ) ;
2016-03-14 07:09:54 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_8 ;
2016-03-14 07:09:54 +00:00
}
2015-02-14 18:10:21 +00:00
result = adb_send ( sock , helpful_packet ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport for <%s> " , helpful_packet ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
2016-03-14 07:09:54 +00:00
result = g_snprintf ( ( char * ) helpful_packet , PACKET_LENGTH , adb_check_port_templace , strlen ( adb_check_port_templace ) - 6 + strlen ( pid ) , pid ) ;
if ( result < = 0 | | result > PACKET_LENGTH ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while completing adb packet " ) ;
2016-03-14 07:09:54 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_9 ;
2016-03-14 07:09:54 +00:00
}
2015-02-14 18:10:21 +00:00
response = adb_send_and_read ( sock , helpful_packet , helpful_packet , sizeof ( helpful_packet ) , & data_length ) ;
closesocket ( sock ) ;
2016-02-06 18:14:20 +00:00
if ( ! response ) {
2015-02-14 18:10:21 +00:00
disable_interface = 1 ;
2016-02-06 18:14:20 +00:00
} else {
response [ data_length ] = ' \0 ' ;
data_str = strchr ( response , ' \n ' ) ;
if ( data_str & & sscanf ( data_str , " %*s %s " , pid ) = = 1 & & strcmp ( pid + 9 , " 22A8 " ) = = 0 ) {
2016-08-02 20:39:28 +00:00
g_debug ( " Btsnoop Net Port for %s is %s " , serial_number , pid + 9 ) ;
2016-02-06 18:14:20 +00:00
} else {
disable_interface = 1 ;
2016-08-02 20:39:28 +00:00
g_debug ( " Btsnoop Net Port for %s is unknown " , serial_number ) ;
2016-02-06 18:14:20 +00:00
}
2015-02-14 18:10:21 +00:00
}
} else {
disable_interface = 1 ;
2016-08-02 20:39:28 +00:00
g_debug ( " Android Bluetooth application PID for %s is unknown " , serial_number ) ;
2015-02-14 18:10:21 +00:00
}
}
if ( ! disable_interface ) {
2016-04-08 09:49:36 +00:00
new_interface ( extcap_conf , INTERFACE_ANDROID_BLUETOOTH_BTSNOOP_NET , model_name , serial_number , " Android Bluetooth Btsnoop Net " ) ;
2015-02-14 18:10:21 +00:00
}
}
}
2016-03-12 18:24:56 +00:00
return EXIT_CODE_SUCCESS ;
2015-02-14 18:10:21 +00:00
}
static int list_config ( char * interface ) {
if ( ! interface ) {
2016-08-02 20:39:28 +00:00
g_warning ( " No interface specified. " ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_NO_INTERFACE_SPECIFIED ;
2015-02-14 18:10:21 +00:00
}
if ( is_specified_interface ( interface , INTERFACE_ANDROID_BLUETOOTH_EXTERNAL_PARSER ) ) {
2015-12-05 09:16:46 +00:00
printf ( " arg {number=0}{call=--adb-server-ip}{display=ADB Server IP Address}{type=string}{default=127.0.0.1} \n "
2015-02-14 18:10:21 +00:00
" arg {number=1}{call=--adb-server-tcp-port}{display=ADB Server TCP Port}{type=integer}{range=0,65535}{default=5037} \n "
" arg {number=2}{call=--bt-server-tcp-port}{display=Bluetooth Server TCP Port}{type=integer}{range=0,65535}{default=4330} \n "
" arg {number=3}{call=--bt-forward-socket}{display=Forward Bluetooth Socket}{type=boolean}{default=false} \n "
" arg {number=4}{call=--bt-local-ip}{display=Bluetooth Local IP Address}{type=string}{default=127.0.0.1} \n "
2015-05-03 15:24:10 +00:00
" arg {number=5}{call=--bt-local-tcp-port}{display=Bluetooth Local TCP Port}{type=integer}{range=0,65535}{default=4330}{tooltip=Used to do \" adb forward tcp:LOCAL_TCP_PORT tcp:SERVER_TCP_PORT \" } \n "
" arg {number=6}{call=--verbose}{display=Verbose/Debug output on console}{type=boolean}{default=false} \n " ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_SUCCESS ;
2015-02-14 18:10:21 +00:00
} else if ( is_specified_interface ( interface , INTERFACE_ANDROID_BLUETOOTH_HCIDUMP ) | |
2015-09-07 09:37:20 +00:00
is_specified_interface ( interface , INTERFACE_ANDROID_BLUETOOTH_BTSNOOP_NET ) | |
is_specified_interface ( interface , INTERFACE_ANDROID_WIFI_TCPDUMP ) ) {
2015-12-05 09:16:46 +00:00
printf ( " arg {number=0}{call=--adb-server-ip}{display=ADB Server IP Address}{type=string}{default=127.0.0.1} \n "
2015-05-03 15:24:10 +00:00
" arg {number=1}{call=--adb-server-tcp-port}{display=ADB Server TCP Port}{type=integer}{range=0,65535}{default=5037} \n "
" arg {number=2}{call=--verbose}{display=Verbose/Debug output on console}{type=boolean}{default=false} \n " ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_SUCCESS ;
2015-02-14 18:10:21 +00:00
} else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_MAIN ) | |
is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_SYSTEM ) | |
is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_RADIO ) | |
is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_EVENTS ) ) {
2015-12-05 09:16:46 +00:00
printf ( " arg {number=0}{call=--adb-server-ip}{display=ADB Server IP Address}{type=string}{default=127.0.0.1} \n "
2015-02-14 18:10:21 +00:00
" arg {number=1}{call=--adb-server-tcp-port}{display=ADB Server TCP Port}{type=integer}{range=0,65535}{default=5037} \n "
2015-05-03 15:24:10 +00:00
" arg {number=2}{call=--logcat-text}{display=Use text logcat}{type=boolean}{default=false} \n "
2017-01-28 18:16:15 +00:00
" arg {number=3}{call=--logcat-ignore-log-buffer}{display=Ignore log buffer}{type=boolean}{default=false} \n "
" arg {number=4}{call=--logcat-custom-options}{display=Custom logcat parameters}{type=string} \n "
" arg {number=5}{call=--verbose}{display=Verbose/Debug output on console}{type=boolean}{default=false} \n " ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_SUCCESS ;
2015-02-14 18:10:21 +00:00
} else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_TEXT_MAIN ) | |
is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_TEXT_SYSTEM ) | |
is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_TEXT_RADIO ) | |
is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_TEXT_EVENTS ) | |
is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_TEXT_CRASH ) ) {
2015-12-05 09:16:46 +00:00
printf ( " arg {number=0}{call=--adb-server-ip}{display=ADB Server IP Address}{type=string}{default=127.0.0.1} \n "
2015-05-03 15:24:10 +00:00
" arg {number=1}{call=--adb-server-tcp-port}{display=ADB Server TCP Port}{type=integer}{range=0,65535}{default=5037} \n "
2017-01-28 18:16:15 +00:00
" arg {number=2}{call=--logcat-ignore-log-buffer}{display=Ignore log buffer}{type=boolean}{default=false} \n "
" arg {number=3}{call=--logcat-custom-options}{display=Custom logcat parameters}{type=string} \n "
" arg {number=4}{call=--verbose}{display=Verbose/Debug output on console}{type=boolean}{default=false} \n " ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_SUCCESS ;
2015-02-14 18:10:21 +00:00
}
2016-08-02 20:39:28 +00:00
g_warning ( " Invalid interface: <%s> " , interface ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_INVALID_INTERFACE ;
2015-02-14 18:10:21 +00:00
}
/*----------------------------------------------------------------------------*/
/* Android Bluetooth Hcidump */
/*----------------------------------------------------------------------------*/
static int capture_android_bluetooth_hcidump ( char * interface , char * fifo ,
const char * adb_server_ip , unsigned short * adb_server_tcp_port ) {
struct extcap_dumper extcap_dumper ;
static char data [ PACKET_LENGTH ] ;
static char packet [ PACKET_LENGTH ] ;
static char helpful_packet [ PACKET_LENGTH ] ;
2015-08-05 15:30:47 +00:00
gssize length ;
gssize used_buffer_length = 0 ;
2016-08-07 17:09:17 +00:00
socket_handle_t sock = INVALID_SOCKET ;
2015-02-14 18:10:21 +00:00
const char * adb_transport = " 0012 " " host:transport-any " ;
const char * adb_transport_serial_templace = " %04x " " host:transport:%s " ;
const char * adb_shell_hcidump = " 0013 " " shell:hcidump -R -t " ;
const char * adb_shell_su_hcidump = " 0019 " " shell:su -c hcidump -R -t " ;
int result ;
char * serial_number = NULL ;
2015-12-01 18:02:04 +00:00
size_t serial_number_length = 0 ;
2015-02-14 18:10:21 +00:00
time_t ts = 0 ;
unsigned int captured_length ;
2015-08-05 15:30:47 +00:00
gint64 hex ;
2015-02-14 18:10:21 +00:00
char * hex_data ;
char * new_hex_data ;
own_pcap_bluetooth_h4_header * h4_header ;
2015-08-05 15:30:47 +00:00
gint64 raw_length = 0 ;
gint64 frame_length ;
2015-02-14 18:10:21 +00:00
int ms = 0 ;
struct tm date ;
char direction_character ;
SET_DATA ( h4_header , value_own_pcap_bluetooth_h4_header , packet ) ;
extcap_dumper = extcap_dumper_open ( fifo , EXTCAP_ENCAP_BLUETOOTH_H4_WITH_PHDR ) ;
sock = adb_connect ( adb_server_ip , adb_server_tcp_port ) ;
2015-04-08 14:09:03 +00:00
if ( sock = = INVALID_SOCKET )
2016-03-12 18:24:56 +00:00
return EXIT_CODE_INVALID_SOCKET_3 ;
2015-02-14 18:10:21 +00:00
if ( is_specified_interface ( interface , INTERFACE_ANDROID_BLUETOOTH_HCIDUMP ) & &
strlen ( interface ) > strlen ( INTERFACE_ANDROID_BLUETOOTH_HCIDUMP ) + 1 ) {
serial_number = interface + strlen ( INTERFACE_ANDROID_BLUETOOTH_HCIDUMP ) + 1 ;
2015-12-01 18:02:04 +00:00
serial_number_length = strlen ( serial_number ) ;
2015-02-14 18:10:21 +00:00
}
if ( ! serial_number ) {
result = adb_send ( sock , adb_transport ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport for <%s> " , adb_transport ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
} else {
2016-03-14 07:09:54 +00:00
result = g_snprintf ( ( char * ) helpful_packet , PACKET_LENGTH , adb_transport_serial_templace , 15 + serial_number_length , serial_number ) ;
if ( result < = 0 | | result > PACKET_LENGTH ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while completing adb packet " ) ;
2016-03-14 07:09:54 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_10 ;
2016-03-14 07:09:54 +00:00
}
2015-02-14 18:10:21 +00:00
result = adb_send ( sock , helpful_packet ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport for <%s> " , helpful_packet ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
}
result = adb_send ( sock , adb_shell_hcidump ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while starting capture by sending command: %s " , adb_shell_hcidump ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
while ( endless_loop ) {
char * i_position ;
errno = 0 ;
2015-08-05 15:30:47 +00:00
length = recv ( sock , data + used_buffer_length , ( int ) ( PACKET_LENGTH - used_buffer_length ) , 0 ) ;
2016-07-13 22:18:03 +00:00
if ( errno = = EAGAIN
# if EWOULDBLOCK != EAGAIN
| | errno = = EWOULDBLOCK
# endif
) {
continue ;
}
2015-02-14 18:10:21 +00:00
else if ( errno ! = 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " ERROR capture: %s " , strerror ( errno ) ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
2016-02-06 18:14:20 +00:00
if ( length < = 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Broken socket connection. " ) ;
2016-02-06 18:14:20 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2016-02-06 18:14:20 +00:00
}
2015-02-14 18:10:21 +00:00
used_buffer_length + = length ;
i_position = ( char * ) memchr ( data , ' \n ' , used_buffer_length ) ;
if ( i_position & & i_position < data + used_buffer_length ) {
char * state_line_position = i_position + 1 ;
if ( ! strncmp ( data , " /system/bin/sh: hcidump: not found " , 34 ) ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Command not found for <%s> " , adb_shell_hcidump ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
i_position = ( char * ) memchr ( i_position + 1 , ' \n ' , used_buffer_length ) ;
if ( i_position ) {
i_position + = 1 ;
if ( ! strncmp ( state_line_position , " Can't access device: Permission denied " , 38 ) ) {
2016-08-02 20:39:28 +00:00
g_warning ( " No permission for command <%s> " , adb_shell_hcidump ) ;
2015-02-14 18:10:21 +00:00
used_buffer_length = 0 ;
2016-08-07 17:09:17 +00:00
closesocket ( sock ) ;
sock = INVALID_SOCKET ;
2015-02-14 18:10:21 +00:00
break ;
}
memmove ( data , i_position , used_buffer_length - ( i_position - data ) ) ;
2015-08-05 15:30:47 +00:00
used_buffer_length = used_buffer_length - ( gssize ) ( i_position - data ) ;
2015-02-14 18:10:21 +00:00
break ;
}
}
}
2016-08-07 17:09:17 +00:00
if ( sock = = INVALID_SOCKET ) {
2015-02-14 18:10:21 +00:00
sock = adb_connect ( adb_server_ip , adb_server_tcp_port ) ;
2015-04-08 14:09:03 +00:00
if ( sock = = INVALID_SOCKET )
2016-03-12 18:24:56 +00:00
return EXIT_CODE_INVALID_SOCKET_4 ;
2015-02-14 18:10:21 +00:00
2016-03-14 07:09:54 +00:00
result = g_snprintf ( ( char * ) helpful_packet , PACKET_LENGTH , adb_transport_serial_templace , 15 + serial_number_length , serial_number ) ;
if ( result < = 0 | | result > PACKET_LENGTH ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while completing adb packet " ) ;
2016-03-14 07:09:54 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_11 ;
2016-03-14 07:09:54 +00:00
}
2015-02-14 18:10:21 +00:00
result = adb_send ( sock , helpful_packet ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport for <%s> " , helpful_packet ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
result = adb_send ( sock , adb_shell_su_hcidump ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while starting capture by sending command: <%s> " , adb_shell_su_hcidump ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
used_buffer_length = 0 ;
while ( endless_loop ) {
char * i_position ;
errno = 0 ;
2015-08-05 15:30:47 +00:00
length = recv ( sock , data + used_buffer_length , ( int ) ( PACKET_LENGTH - used_buffer_length ) , 0 ) ;
2016-07-13 22:18:03 +00:00
if ( errno = = EAGAIN
# if EWOULDBLOCK != EAGAIN
| | errno = = EWOULDBLOCK
# endif
) {
continue ;
}
2015-02-14 18:10:21 +00:00
else if ( errno ! = 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " ERROR capture: %s " , strerror ( errno ) ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
2016-02-06 18:14:20 +00:00
if ( length < = 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Broken socket connection. " ) ;
2016-02-06 18:14:20 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2016-02-06 18:14:20 +00:00
}
2015-02-14 18:10:21 +00:00
used_buffer_length + = length ;
i_position = ( char * ) memchr ( data , ' \n ' , used_buffer_length ) ;
if ( i_position & & i_position < data + used_buffer_length ) {
if ( ! strncmp ( data , " /system/bin/sh: su: not found " , 29 ) ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Command 'su' not found for <%s> " , adb_shell_su_hcidump ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
i_position = ( char * ) memchr ( i_position + 1 , ' \n ' , used_buffer_length ) ;
if ( i_position ) {
i_position + = 1 ;
memmove ( data , i_position , used_buffer_length - ( i_position - data ) ) ;
2015-08-05 15:30:47 +00:00
used_buffer_length = used_buffer_length - ( gssize ) ( i_position - data ) ;
2015-02-14 18:10:21 +00:00
break ;
}
}
}
}
while ( endless_loop ) {
errno = 0 ;
2015-08-05 15:30:47 +00:00
length = recv ( sock , data + used_buffer_length , ( int ) ( PACKET_LENGTH - used_buffer_length ) , 0 ) ;
2016-07-13 22:18:03 +00:00
if ( errno = = EAGAIN
# if EWOULDBLOCK != EAGAIN
| | errno = = EWOULDBLOCK
# endif
) {
continue ;
}
2015-02-14 18:10:21 +00:00
else if ( errno ! = 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " ERROR capture: %s " , strerror ( errno ) ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
2016-02-06 18:14:20 +00:00
if ( length < = 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Broken socket connection. " ) ;
2016-02-06 18:14:20 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2016-02-06 18:14:20 +00:00
}
2015-02-14 18:10:21 +00:00
while ( endless_loop ) {
if ( used_buffer_length + length > = 1 ) {
hex_data = data + 29 ;
2015-08-05 15:30:47 +00:00
hex = g_ascii_strtoll ( hex_data , & new_hex_data , 16 ) ;
2015-02-14 18:10:21 +00:00
if ( ( hex = = 0x01 & & used_buffer_length + length > = 4 ) | |
( hex = = 0x02 & & used_buffer_length + length > = 5 ) | |
( hex = = 0x04 & & used_buffer_length + length > = 3 ) ) {
if ( hex = = 0x01 ) {
hex_data = new_hex_data ;
2015-08-05 15:30:47 +00:00
hex = g_ascii_strtoll ( hex_data , & new_hex_data , 16 ) ;
2015-04-23 06:58:21 +00:00
if ( hex < 0 | | hex > = 256 | | hex_data = = new_hex_data ) {
2016-08-02 20:39:28 +00:00
g_warning ( " data format %s " , strerror ( errno ) ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-04-23 06:58:21 +00:00
}
2015-02-14 18:10:21 +00:00
hex_data = new_hex_data ;
2015-08-05 15:30:47 +00:00
hex = g_ascii_strtoll ( hex_data , & new_hex_data , 16 ) ;
2015-04-23 06:58:21 +00:00
if ( hex < 0 | | hex > = 256 | | hex_data = = new_hex_data ) {
2016-08-02 20:39:28 +00:00
g_warning ( " data format %s " , strerror ( errno ) ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-04-23 06:58:21 +00:00
}
2015-02-14 18:10:21 +00:00
hex_data = new_hex_data ;
2015-08-05 15:30:47 +00:00
hex = g_ascii_strtoll ( hex_data , & new_hex_data , 16 ) ;
2015-02-14 18:10:21 +00:00
raw_length = hex + 4 ;
} else if ( hex = = 0x04 ) {
hex_data = new_hex_data ;
2015-08-05 15:30:47 +00:00
hex = g_ascii_strtoll ( hex_data , & new_hex_data , 16 ) ;
2015-04-23 06:58:21 +00:00
if ( hex < 0 | | hex > = 256 | | hex_data = = new_hex_data ) {
2016-08-02 20:39:28 +00:00
g_warning ( " data format %s " , strerror ( errno ) ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-04-23 06:58:21 +00:00
}
2015-02-14 18:10:21 +00:00
hex_data = new_hex_data ;
2015-08-05 15:30:47 +00:00
hex = g_ascii_strtoll ( hex_data , & new_hex_data , 16 ) ;
2015-02-14 18:10:21 +00:00
2015-04-23 06:58:21 +00:00
raw_length = hex + 3 ;
2015-02-14 18:10:21 +00:00
} else if ( hex = = 0x02 ) {
hex_data = new_hex_data ;
2015-08-05 15:30:47 +00:00
hex = g_ascii_strtoll ( hex_data , & new_hex_data , 16 ) ;
2015-04-23 06:58:21 +00:00
if ( hex < 0 | | hex > = 256 | | hex_data = = new_hex_data ) {
2016-08-02 20:39:28 +00:00
g_warning ( " data format %s " , strerror ( errno ) ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-04-23 06:58:21 +00:00
}
2015-02-14 18:10:21 +00:00
hex_data = new_hex_data ;
2015-08-05 15:30:47 +00:00
hex = g_ascii_strtoll ( hex_data , & new_hex_data , 16 ) ;
2015-04-23 06:58:21 +00:00
if ( hex < 0 | | hex > = 256 | | hex_data = = new_hex_data ) {
2016-08-02 20:39:28 +00:00
g_warning ( " data format %s " , strerror ( errno ) ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-04-23 06:58:21 +00:00
}
2015-02-14 18:10:21 +00:00
hex_data = new_hex_data ;
2015-08-05 15:30:47 +00:00
hex = g_ascii_strtoll ( hex_data , & new_hex_data , 16 ) ;
2015-02-14 18:10:21 +00:00
raw_length = hex + 5 ;
hex_data = new_hex_data ;
2015-08-05 15:30:47 +00:00
hex = g_ascii_strtoll ( hex_data , & new_hex_data , 16 ) ;
2015-02-14 18:10:21 +00:00
raw_length + = hex < < 8 ;
}
} else {
2016-08-02 20:39:28 +00:00
g_warning ( " bad raw stream " ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
} else {
used_buffer_length + = length ;
break ;
}
frame_length = raw_length * 3 + ( raw_length / 20 ) * 4 + ( ( raw_length % 20 ) ? 2 : - 2 ) + 29 ;
if ( used_buffer_length + length < frame_length ) {
used_buffer_length + = length ;
break ;
}
if ( 8 = = sscanf ( data , " %04d-%02d-%02d %02d:%02d:%02d.%06d %c " ,
& date . tm_year , & date . tm_mon , & date . tm_mday , & date . tm_hour ,
& date . tm_min , & date . tm_sec , & ms , & direction_character ) ) {
2016-08-02 20:39:28 +00:00
g_debug ( " time %04d-%02d-%02d %02d:%02d:%02d.%06d %c " ,
2015-02-14 18:10:21 +00:00
date . tm_year , date . tm_mon , date . tm_mday , date . tm_hour ,
date . tm_min , date . tm_sec , ms , direction_character ) ;
date . tm_mon - = 1 ;
date . tm_year - = 1900 ;
ts = mktime ( & date ) ;
2015-04-08 19:08:54 +00:00
new_hex_data = data + 29 ;
2015-02-14 18:10:21 +00:00
}
captured_length = 0 ;
while ( ( long ) ( new_hex_data - data + sizeof ( own_pcap_bluetooth_h4_header ) ) < frame_length ) {
hex_data = new_hex_data ;
2015-08-05 15:30:47 +00:00
hex = g_ascii_strtoll ( hex_data , & new_hex_data , 16 ) ;
2015-02-14 18:10:21 +00:00
packet [ sizeof ( own_pcap_bluetooth_h4_header ) + captured_length ] = ( char ) hex ;
captured_length + = 1 ;
}
h4_header - > direction = GINT32_TO_BE ( direction_character = = ' > ' ) ;
2015-11-29 16:45:12 +00:00
endless_loop = extcap_dumper_dump ( extcap_dumper , packet ,
2015-02-14 18:10:21 +00:00
captured_length + sizeof ( own_pcap_bluetooth_h4_header ) ,
captured_length + sizeof ( own_pcap_bluetooth_h4_header ) ,
ts ,
ms * 1000 ) ;
if ( used_buffer_length + length > = frame_length ) {
2015-08-05 15:30:47 +00:00
memmove ( data , data + frame_length , ( size_t ) ( used_buffer_length + length - frame_length ) ) ;
used_buffer_length = ( gssize ) ( used_buffer_length + length - frame_length ) ;
2015-02-14 18:10:21 +00:00
length = 0 ;
continue ;
}
length = 0 ;
}
}
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_SUCCESS ;
2015-02-14 18:10:21 +00:00
}
/*----------------------------------------------------------------------------*/
/* Android Bluetooth External Parser */
/*----------------------------------------------------------------------------*/
# define BLUEDROID_H4_PACKET_TYPE 0
# define BLUEDROID_TIMESTAMP_SIZE 8
# define BLUEDROID_H4_SIZE 1
2015-04-11 20:17:11 +00:00
static const uint64_t BLUEDROID_TIMESTAMP_BASE = G_GUINT64_CONSTANT ( 0x00dcddb30f2f8000 ) ;
2015-02-14 18:10:21 +00:00
# define BLUEDROID_H4_PACKET_TYPE_HCI_CMD 0x01
# define BLUEDROID_H4_PACKET_TYPE_ACL 0x02
# define BLUEDROID_H4_PACKET_TYPE_SCO 0x03
# define BLUEDROID_H4_PACKET_TYPE_HCI_EVT 0x04
# define BLUEDROID_DIRECTION_SENT 0
# define BLUEDROID_DIRECTION_RECV 1
static int adb_forward ( char * serial_number , const char * adb_server_ip , unsigned short * adb_server_tcp_port ,
unsigned short local_tcp_port , unsigned short server_tcp_port ) {
2015-04-08 14:09:03 +00:00
socket_handle_t sock ;
2015-02-14 18:10:21 +00:00
int result ;
static char helpful_packet [ PACKET_LENGTH ] ;
static const char * adb_forward_template = " %04x " " %s%s:forward:tcp:%05u;tcp:%05u " ;
sock = adb_connect ( adb_server_ip , adb_server_tcp_port ) ;
2015-04-08 14:09:03 +00:00
if ( sock = = INVALID_SOCKET )
2016-03-12 18:24:56 +00:00
return EXIT_CODE_INVALID_SOCKET_5 ;
2015-02-14 18:10:21 +00:00
2016-03-14 07:09:54 +00:00
result = g_snprintf ( helpful_packet , PACKET_LENGTH , adb_forward_template , ( serial_number ) ? 5 + 7 + strlen ( serial_number ) + 28 : 4 + 28 , ( serial_number ) ? " host-serial: " : " host " , ( serial_number ) ? serial_number : " " , local_tcp_port , server_tcp_port ) ;
if ( result < = 0 | | result > PACKET_LENGTH ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while completing adb packet " ) ;
2016-03-14 07:09:54 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_12 ;
2016-03-14 07:09:54 +00:00
}
2015-02-14 18:10:21 +00:00
result = adb_send ( sock , helpful_packet ) ;
closesocket ( sock ) ;
return result ;
}
static int capture_android_bluetooth_external_parser ( char * interface ,
char * fifo , const char * adb_server_ip , unsigned short * adb_server_tcp_port ,
unsigned short * bt_server_tcp_port , unsigned int bt_forward_socket , const char * bt_local_ip ,
unsigned short * bt_local_tcp_port ) {
struct extcap_dumper extcap_dumper ;
2016-07-16 16:26:15 +00:00
static char buffer [ PACKET_LENGTH ] ;
2015-02-14 18:10:21 +00:00
uint64_t * timestamp ;
char * packet = buffer + BLUEDROID_TIMESTAMP_SIZE - sizeof ( own_pcap_bluetooth_h4_header ) ; /* skip timestamp (8 bytes) and reuse its space for header */
own_pcap_bluetooth_h4_header * h4_header ;
2015-06-09 09:25:37 +00:00
guint8 * payload = packet + sizeof ( own_pcap_bluetooth_h4_header ) ;
2015-02-14 18:10:21 +00:00
const char * adb_transport = " 0012 " " host:transport-any " ;
const char * adb_transport_serial_templace = " %04x " " host:transport:%s " ;
const char * adb_tcp_bluedroid_external_parser_template = " %04x " " tcp:%05u " ;
2016-08-09 13:40:58 +00:00
socklen_t slen ;
2015-08-05 15:30:47 +00:00
gssize length ;
gssize used_buffer_length = 0 ;
2015-02-14 18:10:21 +00:00
uint64_t ts ;
2015-04-08 14:09:03 +00:00
socket_handle_t sock ;
2015-02-14 18:10:21 +00:00
struct sockaddr_in server ;
int captured_length ;
char * serial_number = NULL ;
2015-12-17 19:33:15 +00:00
size_t serial_number_length = 0 ;
2016-08-02 20:39:28 +00:00
static unsigned int id = 1 ;
struct sockaddr_in client ;
2015-02-14 18:10:21 +00:00
SET_DATA ( timestamp , value_u64 , buffer ) ;
SET_DATA ( h4_header , value_own_pcap_bluetooth_h4_header , packet ) ;
extcap_dumper = extcap_dumper_open ( fifo , EXTCAP_ENCAP_BLUETOOTH_H4_WITH_PHDR ) ;
if ( is_specified_interface ( interface , INTERFACE_ANDROID_BLUETOOTH_EXTERNAL_PARSER ) & &
strlen ( interface ) > strlen ( INTERFACE_ANDROID_BLUETOOTH_EXTERNAL_PARSER ) + 1 ) {
serial_number = interface + strlen ( INTERFACE_ANDROID_BLUETOOTH_EXTERNAL_PARSER ) + 1 ;
2015-12-01 18:02:04 +00:00
serial_number_length = strlen ( serial_number ) ;
2015-02-14 18:10:21 +00:00
}
if ( bt_forward_socket ) {
2015-04-08 14:09:03 +00:00
if ( ( sock = socket ( AF_INET , SOCK_STREAM , IPPROTO_TCP ) ) = = INVALID_SOCKET ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Cannot open system TCP socket: %s " , strerror ( errno ) ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
2016-08-02 20:39:28 +00:00
g_debug ( " Using config: Server TCP Port=%u, Local IP=%s, Local TCP Port=%u " ,
2015-02-14 18:10:21 +00:00
* bt_server_tcp_port , bt_local_ip , * bt_local_tcp_port ) ;
if ( * bt_local_tcp_port ! = 0 ) {
int result ;
result = adb_forward ( serial_number , adb_server_ip , adb_server_tcp_port , * bt_local_tcp_port , * bt_server_tcp_port ) ;
2016-08-02 20:39:28 +00:00
g_debug ( " DO: adb forward tcp:%u (local) tcp:%u (remote) result=%i " ,
2015-05-03 15:24:10 +00:00
* bt_local_tcp_port , * bt_server_tcp_port , result ) ;
2015-02-14 18:10:21 +00:00
}
2015-06-18 07:10:55 +00:00
memset ( & server , 0 , sizeof ( server ) ) ;
2015-02-14 18:10:21 +00:00
server . sin_family = AF_INET ;
server . sin_port = GINT16_TO_BE ( * bt_local_tcp_port ) ;
server . sin_addr . s_addr = inet_addr ( bt_local_ip ) ;
2016-11-10 08:10:44 +00:00
useSndTimeout ( sock ) ;
2015-04-12 17:25:31 +00:00
if ( connect ( sock , ( struct sockaddr * ) & server , sizeof ( server ) ) = = SOCKET_ERROR ) {
2016-08-02 20:39:28 +00:00
g_warning ( " <%s> Please check that adb daemon is running. " , strerror ( errno ) ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
2016-08-09 13:40:58 +00:00
slen = ( socklen_t ) sizeof ( client ) ;
if ( getsockname ( sock , ( struct sockaddr * ) & client , & slen ) ) {
2016-08-02 20:39:28 +00:00
g_warning ( " getsockname: %s " , strerror ( errno ) ) ;
closesocket ( sock ) ;
return EXIT_CODE_GENERIC ;
}
2015-02-14 18:10:21 +00:00
2016-08-09 13:40:58 +00:00
if ( slen ! = sizeof ( client ) ) {
2016-08-02 20:39:28 +00:00
g_warning ( " incorrect length " ) ;
closesocket ( sock ) ;
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
2016-08-02 20:39:28 +00:00
g_debug ( " Client port %u " , GUINT16_FROM_BE ( client . sin_port ) ) ;
2015-02-14 18:10:21 +00:00
} else {
int result ;
sock = adb_connect ( adb_server_ip , adb_server_tcp_port ) ;
2015-04-08 14:09:03 +00:00
if ( sock = = INVALID_SOCKET )
2016-03-12 18:24:56 +00:00
return EXIT_CODE_INVALID_SOCKET_6 ;
2015-02-14 18:10:21 +00:00
if ( ! serial_number ) {
result = adb_send ( sock , adb_transport ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport " ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
} else {
2016-03-14 07:09:54 +00:00
result = g_snprintf ( ( char * ) buffer , PACKET_LENGTH , adb_transport_serial_templace , 15 + serial_number_length , serial_number ) ;
if ( result < = 0 | | result > PACKET_LENGTH ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while completing adb packet " ) ;
2016-03-14 07:09:54 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_13 ;
2016-03-14 07:09:54 +00:00
}
2015-02-14 18:10:21 +00:00
result = adb_send ( sock , buffer ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport " ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
}
2016-03-14 07:09:54 +00:00
result = g_snprintf ( ( char * ) buffer , PACKET_LENGTH , adb_tcp_bluedroid_external_parser_template , 4 + 5 , * bt_server_tcp_port ) ;
if ( result < = 0 | | result > PACKET_LENGTH ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while completing adb packet " ) ;
2016-03-14 07:09:54 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_14 ;
2016-03-14 07:09:54 +00:00
}
2015-02-14 18:10:21 +00:00
result = adb_send ( sock , buffer ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while forwarding adb port " ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
}
while ( endless_loop ) {
errno = 0 ;
2015-08-05 15:30:47 +00:00
length = recv ( sock , buffer + used_buffer_length , ( int ) ( PACKET_LENGTH - used_buffer_length ) , 0 ) ;
2016-07-13 22:18:03 +00:00
if ( errno = = EAGAIN
# if EWOULDBLOCK != EAGAIN
| | errno = = EWOULDBLOCK
# endif
) {
continue ;
}
2015-02-14 18:10:21 +00:00
else if ( errno ! = 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " ERROR capture: %s " , strerror ( errno ) ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
if ( length < = 0 ) {
if ( bt_forward_socket ) {
/* NOTE: Workaround... It seems that Bluedroid is slower and we can connect to socket that are not really ready... */
2016-08-02 20:39:28 +00:00
g_warning ( " Broken socket connection. Try reconnect. " ) ;
2015-02-14 18:10:21 +00:00
closesocket ( sock ) ;
2015-04-08 14:09:03 +00:00
if ( ( sock = socket ( AF_INET , SOCK_STREAM , IPPROTO_TCP ) ) = = INVALID_SOCKET ) {
2016-08-02 20:39:28 +00:00
g_warning ( " %s " , strerror ( errno ) ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
server . sin_family = AF_INET ;
server . sin_port = GINT16_TO_BE ( * bt_local_tcp_port ) ;
server . sin_addr . s_addr = inet_addr ( bt_local_ip ) ;
2016-11-10 08:10:44 +00:00
useSndTimeout ( sock ) ;
2015-04-12 17:25:31 +00:00
if ( connect ( sock , ( struct sockaddr * ) & server , sizeof ( server ) ) = = SOCKET_ERROR ) {
2016-08-02 20:39:28 +00:00
g_warning ( " ERROR reconnect: <%s> Please check that adb daemon is running. " , strerror ( errno ) ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
} else {
2016-08-02 20:39:28 +00:00
g_warning ( " Broken socket connection. " ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
continue ;
}
used_buffer_length + = length ;
2016-08-02 20:39:28 +00:00
g_debug ( " Received: length=% " G_GSSIZE_FORMAT " " , length ) ;
2015-02-14 18:10:21 +00:00
while ( ( ( payload [ BLUEDROID_H4_PACKET_TYPE ] = = BLUEDROID_H4_PACKET_TYPE_HCI_CMD | | payload [ BLUEDROID_H4_PACKET_TYPE ] = = BLUEDROID_H4_PACKET_TYPE_SCO ) & &
used_buffer_length > = BLUEDROID_TIMESTAMP_SIZE + BLUEDROID_H4_SIZE + 2 + 1 & &
BLUEDROID_TIMESTAMP_SIZE + BLUEDROID_H4_SIZE + 2 + payload [ BLUEDROID_H4_SIZE + 2 ] + 1 < = used_buffer_length ) | |
( payload [ BLUEDROID_H4_PACKET_TYPE ] = = BLUEDROID_H4_PACKET_TYPE_ACL & &
used_buffer_length > = BLUEDROID_TIMESTAMP_SIZE + BLUEDROID_H4_SIZE + 2 + 2 & &
BLUEDROID_TIMESTAMP_SIZE + BLUEDROID_H4_SIZE + 2 + payload [ BLUEDROID_H4_SIZE + 2 ] + ( payload [ BLUEDROID_H4_SIZE + 2 + 1 ] < < 8 ) + 2 < = used_buffer_length ) | |
2015-06-09 09:25:37 +00:00
( payload [ BLUEDROID_H4_PACKET_TYPE ] = = BLUEDROID_H4_PACKET_TYPE_SCO & &
used_buffer_length > = BLUEDROID_TIMESTAMP_SIZE + BLUEDROID_H4_SIZE + 2 + 1 & &
BLUEDROID_TIMESTAMP_SIZE + BLUEDROID_H4_SIZE + 2 + payload [ BLUEDROID_H4_SIZE + 2 ] + 1 < = used_buffer_length ) | |
2015-02-14 18:10:21 +00:00
( payload [ BLUEDROID_H4_PACKET_TYPE ] = = BLUEDROID_H4_PACKET_TYPE_HCI_EVT & &
used_buffer_length > = BLUEDROID_TIMESTAMP_SIZE + BLUEDROID_H4_SIZE + 1 + 1 & &
BLUEDROID_TIMESTAMP_SIZE + BLUEDROID_H4_SIZE + 1 + payload [ BLUEDROID_H4_SIZE + 1 ] + 1 < = used_buffer_length ) ) {
ts = GINT64_FROM_BE ( * timestamp ) ;
switch ( payload [ BLUEDROID_H4_PACKET_TYPE ] ) {
case BLUEDROID_H4_PACKET_TYPE_HCI_CMD :
h4_header - > direction = GINT32_TO_BE ( BLUEDROID_DIRECTION_SENT ) ;
2015-04-11 20:13:09 +00:00
captured_length = ( unsigned int ) sizeof ( own_pcap_bluetooth_h4_header ) + payload [ 3 ] + 4 ;
2015-02-14 18:10:21 +00:00
length = sizeof ( own_pcap_bluetooth_h4_header ) + BLUEDROID_H4_SIZE + 2 + 1 + payload [ 3 ] ;
break ;
case BLUEDROID_H4_PACKET_TYPE_ACL :
h4_header - > direction = ( payload [ 2 ] & 0x80 ) ? GINT32_TO_BE ( BLUEDROID_DIRECTION_RECV ) : GINT32_TO_BE ( BLUEDROID_DIRECTION_SENT ) ;
2015-04-11 20:13:09 +00:00
captured_length = ( unsigned int ) sizeof ( own_pcap_bluetooth_h4_header ) + payload [ 3 ] + ( payload [ 3 + 1 ] < < 8 ) + 5 ;
2015-02-14 18:10:21 +00:00
2016-07-16 16:26:15 +00:00
length = sizeof ( own_pcap_bluetooth_h4_header ) + BLUEDROID_H4_SIZE + 2 + 2 + payload [ 3 ] + ( gssize ) ( payload [ 3 + 1 ] < < 8 ) ;
2015-02-14 18:10:21 +00:00
break ;
case BLUEDROID_H4_PACKET_TYPE_SCO :
h4_header - > direction = ( payload [ 2 ] & 0x80 ) ? GINT32_TO_BE ( BLUEDROID_DIRECTION_RECV ) : GINT32_TO_BE ( BLUEDROID_DIRECTION_SENT ) ;
2015-04-11 20:13:09 +00:00
captured_length = ( unsigned int ) sizeof ( own_pcap_bluetooth_h4_header ) + payload [ 3 ] + 4 ;
2015-02-14 18:10:21 +00:00
length = sizeof ( own_pcap_bluetooth_h4_header ) + BLUEDROID_H4_SIZE + 2 + 1 + payload [ 3 ] ;
break ;
case BLUEDROID_H4_PACKET_TYPE_HCI_EVT :
h4_header - > direction = GINT32_TO_BE ( BLUEDROID_DIRECTION_RECV ) ;
2015-04-11 20:13:09 +00:00
captured_length = ( unsigned int ) sizeof ( own_pcap_bluetooth_h4_header ) + payload [ 2 ] + 3 ;
2015-02-14 18:10:21 +00:00
length = sizeof ( own_pcap_bluetooth_h4_header ) + BLUEDROID_H4_SIZE + 1 + 1 + payload [ 2 ] ;
break ;
default :
2016-08-02 20:39:28 +00:00
g_warning ( " Invalid stream " ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
2016-08-02 20:39:28 +00:00
g_debug ( " \t Packet %u: used_buffer_length=% " G_GSSIZE_FORMAT " length=% " G_GSSIZE_FORMAT " captured_length=%i type=0x%02x " , id , used_buffer_length , length , captured_length , payload [ BLUEDROID_H4_PACKET_TYPE ] ) ;
if ( payload [ BLUEDROID_H4_PACKET_TYPE ] = = BLUEDROID_H4_PACKET_TYPE_HCI_EVT )
g_debug ( " \t Packet: %02x %02x %02x " , ( unsigned int ) payload [ 0 ] , ( unsigned int ) payload [ 1 ] , ( unsigned int ) payload [ 2 ] ) ;
id + = 1 ;
2015-06-09 09:25:37 +00:00
2015-02-14 18:10:21 +00:00
ts - = BLUEDROID_TIMESTAMP_BASE ;
2015-11-29 16:45:12 +00:00
endless_loop = extcap_dumper_dump ( extcap_dumper , packet ,
2015-02-14 18:10:21 +00:00
captured_length ,
captured_length ,
( uint32_t ) ( ts / 1000000 ) ,
( ( uint32_t ) ( ts % 1000000 ) ) * 1000 ) ;
used_buffer_length - = length - sizeof ( own_pcap_bluetooth_h4_header ) + BLUEDROID_TIMESTAMP_SIZE ;
if ( used_buffer_length < 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Internal Negative used buffer length. " ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
memmove ( buffer , packet + length , used_buffer_length ) ;
}
}
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_SUCCESS ;
2015-02-14 18:10:21 +00:00
}
/*----------------------------------------------------------------------------*/
/* Android Btsnoop Net */
/*----------------------------------------------------------------------------*/
static int capture_android_bluetooth_btsnoop_net ( char * interface , char * fifo ,
const char * adb_server_ip , unsigned short * adb_server_tcp_port ) {
struct extcap_dumper extcap_dumper ;
static char packet [ PACKET_LENGTH ] ;
2015-08-05 15:30:47 +00:00
gssize length ;
gssize used_buffer_length = 0 ;
2015-04-08 14:09:03 +00:00
socket_handle_t sock ;
2015-02-14 18:10:21 +00:00
const char * adb_transport = " 0012 " " host:transport-any " ;
const char * adb_transport_serial_templace = " %04x " " host:transport:%s " ;
const char * adb_tcp_btsnoop_net = " 0008 " " tcp:8872 " ;
int result ;
char * serial_number = NULL ;
2015-12-01 18:02:04 +00:00
size_t serial_number_length ;
2015-02-14 18:10:21 +00:00
uint64_t ts ;
2015-04-11 20:17:11 +00:00
static const uint64_t BTSNOOP_TIMESTAMP_BASE = G_GUINT64_CONSTANT ( 0x00dcddb30f2f8000 ) ;
2015-02-14 18:10:21 +00:00
uint32_t * reported_length ;
uint32_t * captured_length ;
uint32_t * flags ;
2016-01-06 00:58:42 +00:00
/* uint32_t *cumulative_dropped_packets; */
2015-02-14 18:10:21 +00:00
uint64_t * timestamp ;
char * payload = packet + sizeof ( own_pcap_bluetooth_h4_header ) + 24 ;
own_pcap_bluetooth_h4_header * h4_header ;
SET_DATA ( reported_length , value_u32 , packet + sizeof ( own_pcap_bluetooth_h4_header ) + 0 ) ;
SET_DATA ( captured_length , value_u32 , packet + sizeof ( own_pcap_bluetooth_h4_header ) + 4 ) ;
SET_DATA ( flags , value_u32 , packet + sizeof ( own_pcap_bluetooth_h4_header ) + 8 ) ;
2016-01-06 00:58:42 +00:00
/* SET_DATA(cumulative_dropped_packets, value_u32, packet + sizeof(own_pcap_bluetooth_h4_header) + 12); */
2015-02-14 18:10:21 +00:00
SET_DATA ( timestamp , value_u64 , packet + sizeof ( own_pcap_bluetooth_h4_header ) + 16 ) ;
SET_DATA ( h4_header , value_own_pcap_bluetooth_h4_header , payload - sizeof ( own_pcap_bluetooth_h4_header ) ) ;
extcap_dumper = extcap_dumper_open ( fifo , EXTCAP_ENCAP_BLUETOOTH_H4_WITH_PHDR ) ;
sock = adb_connect ( adb_server_ip , adb_server_tcp_port ) ;
2015-04-08 14:09:03 +00:00
if ( sock = = INVALID_SOCKET )
2016-03-12 18:24:56 +00:00
return EXIT_CODE_INVALID_SOCKET_7 ;
2015-02-14 18:10:21 +00:00
if ( is_specified_interface ( interface , INTERFACE_ANDROID_BLUETOOTH_BTSNOOP_NET ) & &
strlen ( interface ) > strlen ( INTERFACE_ANDROID_BLUETOOTH_BTSNOOP_NET ) + 1 ) {
serial_number = interface + strlen ( INTERFACE_ANDROID_BLUETOOTH_BTSNOOP_NET ) + 1 ;
2015-12-01 18:02:04 +00:00
serial_number_length = strlen ( serial_number ) ;
2015-02-14 18:10:21 +00:00
}
if ( ! serial_number ) {
result = adb_send ( sock , adb_transport ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport for <%s> " , adb_transport ) ;
2016-07-03 20:04:38 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
} else {
2016-03-14 07:09:54 +00:00
result = g_snprintf ( ( char * ) packet , PACKET_LENGTH , adb_transport_serial_templace , 15 + serial_number_length , serial_number ) ;
if ( result < = 0 | | result > PACKET_LENGTH ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while completing adb packet " ) ;
2016-03-14 07:09:54 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_15 ;
2016-03-14 07:09:54 +00:00
}
2015-02-14 18:10:21 +00:00
result = adb_send ( sock , packet ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport for <%s> " , packet ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
}
result = adb_send ( sock , adb_tcp_btsnoop_net ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while sending command <%s> " , adb_tcp_btsnoop_net ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_ERROR_WHILE_SENDING_ADB_PACKET_2 ;
2015-02-14 18:10:21 +00:00
}
/* Read "btsnoop" header - 16 bytes */
while ( used_buffer_length < 16 ) {
2015-08-05 15:30:47 +00:00
length = recv ( sock , packet + used_buffer_length , ( int ) ( PACKET_LENGTH - used_buffer_length ) , 0 ) ;
2016-02-06 18:14:20 +00:00
if ( length < = 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Broken socket connection. " ) ;
2016-02-06 18:14:20 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2016-02-06 18:14:20 +00:00
}
2015-02-14 18:10:21 +00:00
used_buffer_length + = length ;
}
if ( used_buffer_length > 16 )
memmove ( packet , packet + 16 , used_buffer_length - 16 ) ;
used_buffer_length = 0 ;
while ( endless_loop ) {
errno = 0 ;
length = recv ( sock , packet + used_buffer_length + sizeof ( own_pcap_bluetooth_h4_header ) ,
2015-08-05 15:30:47 +00:00
( int ) ( PACKET_LENGTH - sizeof ( own_pcap_bluetooth_h4_header ) - used_buffer_length ) , 0 ) ;
2016-07-13 22:18:03 +00:00
if ( errno = = EAGAIN
# if EWOULDBLOCK != EAGAIN
| | errno = = EWOULDBLOCK
# endif
) {
continue ;
}
2015-02-14 18:10:21 +00:00
else if ( errno ! = 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " ERROR capture: %s " , strerror ( errno ) ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
if ( length < = 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Broken socket connection. " ) ;
2015-02-14 18:10:21 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
used_buffer_length + = length ;
while ( used_buffer_length > = 24 & &
used_buffer_length > = ( int ) ( 24 + GINT32_FROM_BE ( * captured_length ) ) ) {
2015-04-11 19:45:40 +00:00
gint32 direction ;
2015-02-14 18:10:21 +00:00
ts = GINT64_FROM_BE ( * timestamp ) ;
ts - = BTSNOOP_TIMESTAMP_BASE ;
2015-04-11 19:45:40 +00:00
direction = GINT32_FROM_BE ( * flags ) & 0x01 ;
h4_header - > direction = GINT32_TO_BE ( direction ) ;
2015-02-14 18:10:21 +00:00
2015-11-29 16:45:12 +00:00
endless_loop = extcap_dumper_dump ( extcap_dumper , payload - sizeof ( own_pcap_bluetooth_h4_header ) ,
2015-02-14 18:10:21 +00:00
GINT32_FROM_BE ( * captured_length ) + sizeof ( own_pcap_bluetooth_h4_header ) ,
GINT32_FROM_BE ( * reported_length ) + sizeof ( own_pcap_bluetooth_h4_header ) ,
( uint32_t ) ( ts / 1000000 ) ,
( ( uint32_t ) ( ts % 1000000 ) ) * 1000 ) ;
used_buffer_length - = 24 + GINT32_FROM_BE ( * captured_length ) ;
if ( used_buffer_length < 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Internal Negative used buffer length. " ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
if ( used_buffer_length > 0 )
memmove ( packet + sizeof ( own_pcap_bluetooth_h4_header ) , payload + GINT32_FROM_BE ( * captured_length ) , used_buffer_length ) ;
}
}
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_SUCCESS ;
2015-02-14 18:10:21 +00:00
}
/*----------------------------------------------------------------------------*/
/* Android Logcat Text*/
/*----------------------------------------------------------------------------*/
static int capture_android_logcat_text ( char * interface , char * fifo ,
2017-01-28 18:16:15 +00:00
const char * adb_server_ip , unsigned short * adb_server_tcp_port ,
int logcat_ignore_log_buffer , const char * logcat_custom_parameter ) {
2015-02-14 18:10:21 +00:00
struct extcap_dumper extcap_dumper ;
static char packet [ PACKET_LENGTH ] ;
2015-08-05 15:30:47 +00:00
gssize length ;
2015-04-08 14:09:03 +00:00
size_t used_buffer_length = 0 ;
socket_handle_t sock ;
2015-02-14 18:10:21 +00:00
const char * protocol_name ;
2015-04-11 20:13:09 +00:00
size_t exported_pdu_headers_size = 0 ;
2015-02-14 18:10:21 +00:00
struct exported_pdu_header exported_pdu_header_protocol_normal ;
struct exported_pdu_header * exported_pdu_header_protocol ;
struct exported_pdu_header exported_pdu_header_end = { 0 , 0 } ;
static const char * wireshark_protocol_logcat_text = " logcat_text_threadtime " ;
const char * adb_transport = " 0012 " " host:transport-any " ;
2017-01-28 18:16:15 +00:00
const char * adb_logcat_template = " %04x " " shell:export ANDROID_LOG_TAGS= \" \" ; exec logcat -v threadtime%s%s%s%s " ;
2015-02-14 18:10:21 +00:00
const char * adb_transport_serial_templace = " %04x " " host:transport:%s " ;
char * serial_number = NULL ;
2015-12-01 18:02:04 +00:00
size_t serial_number_length = 0 ;
2015-02-14 18:10:21 +00:00
int result ;
char * pos ;
const char * logcat_buffer ;
2017-01-28 18:16:15 +00:00
const char * logcat_log_buffer ;
int command_length ;
2015-02-14 18:10:21 +00:00
extcap_dumper = extcap_dumper_open ( fifo , EXTCAP_ENCAP_WIRESHARK_UPPER_PDU ) ;
2015-12-01 18:02:04 +00:00
exported_pdu_header_protocol_normal . tag = GUINT16_TO_BE ( WIRESHARK_UPPER_PDU_TAG_DISSECTOR_NAME ) ;
exported_pdu_header_protocol_normal . length = GUINT16_TO_BE ( strlen ( wireshark_protocol_logcat_text ) + 2 ) ;
2015-02-14 18:10:21 +00:00
sock = adb_connect ( adb_server_ip , adb_server_tcp_port ) ;
2015-04-08 14:09:03 +00:00
if ( sock = = INVALID_SOCKET )
2016-03-12 18:24:56 +00:00
return EXIT_CODE_INVALID_SOCKET_8 ;
2015-02-14 18:10:21 +00:00
if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_MAIN ) & & strlen ( interface ) > strlen ( INTERFACE_ANDROID_LOGCAT_MAIN ) + 1 ) {
serial_number = interface + strlen ( INTERFACE_ANDROID_LOGCAT_MAIN ) + 1 ;
} else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_SYSTEM ) & & strlen ( interface ) > strlen ( INTERFACE_ANDROID_LOGCAT_SYSTEM ) + 1 ) {
serial_number = interface + strlen ( INTERFACE_ANDROID_LOGCAT_SYSTEM ) + 1 ;
} else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_RADIO ) & & strlen ( interface ) > strlen ( INTERFACE_ANDROID_LOGCAT_RADIO ) + 1 ) {
serial_number = interface + strlen ( INTERFACE_ANDROID_LOGCAT_RADIO ) + 1 ;
} else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_EVENTS ) & & strlen ( interface ) > strlen ( INTERFACE_ANDROID_LOGCAT_EVENTS ) + 1 ) {
serial_number = interface + strlen ( INTERFACE_ANDROID_LOGCAT_EVENTS ) + 1 ;
} else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_TEXT_MAIN ) & & strlen ( interface ) > strlen ( INTERFACE_ANDROID_LOGCAT_TEXT_MAIN ) + 1 ) {
serial_number = interface + strlen ( INTERFACE_ANDROID_LOGCAT_TEXT_MAIN ) + 1 ;
} else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_TEXT_SYSTEM ) & & strlen ( interface ) > strlen ( INTERFACE_ANDROID_LOGCAT_TEXT_SYSTEM ) + 1 ) {
serial_number = interface + strlen ( INTERFACE_ANDROID_LOGCAT_TEXT_SYSTEM ) + 1 ;
} else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_TEXT_RADIO ) & & strlen ( interface ) > strlen ( INTERFACE_ANDROID_LOGCAT_TEXT_RADIO ) + 1 ) {
serial_number = interface + strlen ( INTERFACE_ANDROID_LOGCAT_TEXT_RADIO ) + 1 ;
} else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_TEXT_EVENTS ) & & strlen ( interface ) > strlen ( INTERFACE_ANDROID_LOGCAT_TEXT_EVENTS ) + 1 ) {
serial_number = interface + strlen ( INTERFACE_ANDROID_LOGCAT_TEXT_EVENTS ) + 1 ;
} else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_TEXT_CRASH ) & & strlen ( interface ) > strlen ( INTERFACE_ANDROID_LOGCAT_TEXT_CRASH ) + 1 ) {
serial_number = interface + strlen ( INTERFACE_ANDROID_LOGCAT_TEXT_CRASH ) + 1 ;
}
if ( ! serial_number ) {
result = adb_send ( sock , adb_transport ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport for <%s> " , adb_transport ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
} else {
2015-12-01 18:02:04 +00:00
serial_number_length = strlen ( serial_number ) ;
2016-03-14 07:09:54 +00:00
result = g_snprintf ( ( char * ) packet , PACKET_LENGTH , adb_transport_serial_templace , 15 + serial_number_length , serial_number ) ;
if ( result < = 0 | | result > PACKET_LENGTH ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while completing adb packet " ) ;
2016-03-14 07:09:54 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_16 ;
2016-03-14 07:09:54 +00:00
}
2015-02-14 18:10:21 +00:00
result = adb_send ( sock , packet ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport for <%s> " , packet ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
}
if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_MAIN ) | | is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_TEXT_MAIN ) )
logcat_buffer = " -b main " ;
else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_SYSTEM ) | | is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_TEXT_SYSTEM ) )
logcat_buffer = " -b system " ;
else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_RADIO ) | | is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_TEXT_RADIO ) )
logcat_buffer = " -b radio " ;
else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_EVENTS ) | | is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_TEXT_EVENTS ) )
logcat_buffer = " -b events " ;
else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_TEXT_CRASH ) )
logcat_buffer = " -b crash " ;
else {
2016-08-02 20:39:28 +00:00
g_warning ( " Unknown interface: <%s> " , interface ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
2017-01-28 18:16:15 +00:00
command_length = strlen ( adb_logcat_template ) - 4 - 8 + strlen ( logcat_buffer ) ;
if ( logcat_ignore_log_buffer )
logcat_log_buffer = " -T 1 " ;
else
logcat_log_buffer = " " ;
command_length + = strlen ( logcat_log_buffer ) ;
2015-02-14 18:10:21 +00:00
2017-01-28 18:16:15 +00:00
if ( logcat_custom_parameter ) {
command_length + = 1 ; /* additional command "space" */
command_length + = strlen ( logcat_custom_parameter ) ;
}
result = g_snprintf ( ( char * ) packet , PACKET_LENGTH , adb_logcat_template , command_length , logcat_buffer , logcat_log_buffer , ( logcat_custom_parameter ? " " : " " ) , logcat_custom_parameter ) ;
2016-03-14 07:09:54 +00:00
if ( result < = 0 | | result > PACKET_LENGTH ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while completing adb packet " ) ;
2016-03-14 07:09:54 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_17 ;
2016-03-14 07:09:54 +00:00
}
2015-02-14 18:10:21 +00:00
result = adb_send ( sock , packet ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while sending command <%s> " , packet ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_ERROR_WHILE_SENDING_ADB_PACKET_3 ;
2015-02-14 18:10:21 +00:00
}
protocol_name = wireshark_protocol_logcat_text ;
exported_pdu_header_protocol = & exported_pdu_header_protocol_normal ;
2015-12-01 18:02:04 +00:00
memcpy ( packet , exported_pdu_header_protocol , sizeof ( struct exported_pdu_header ) ) ;
2015-02-14 18:10:21 +00:00
exported_pdu_headers_size + = sizeof ( struct exported_pdu_header ) ;
2015-12-01 18:02:04 +00:00
memcpy ( packet + exported_pdu_headers_size , protocol_name , GUINT16_FROM_BE ( exported_pdu_header_protocol - > length ) - 2 ) ;
exported_pdu_headers_size + = GUINT16_FROM_BE ( exported_pdu_header_protocol - > length ) ;
2015-02-14 18:10:21 +00:00
packet [ exported_pdu_headers_size - 1 ] = 0 ;
packet [ exported_pdu_headers_size - 2 ] = 0 ;
memcpy ( packet + exported_pdu_headers_size , & exported_pdu_header_end , sizeof ( struct exported_pdu_header ) ) ;
2015-12-01 18:02:04 +00:00
exported_pdu_headers_size + = sizeof ( struct exported_pdu_header ) + GUINT16_FROM_BE ( exported_pdu_header_end . length ) ;
2015-02-14 18:10:21 +00:00
used_buffer_length = 0 ;
while ( endless_loop ) {
errno = 0 ;
2015-04-08 14:09:03 +00:00
length = recv ( sock , packet + exported_pdu_headers_size + used_buffer_length , ( int ) ( PACKET_LENGTH - exported_pdu_headers_size - used_buffer_length ) , 0 ) ;
2016-07-13 22:18:03 +00:00
if ( errno = = EAGAIN
# if EWOULDBLOCK != EAGAIN
| | errno = = EWOULDBLOCK
# endif
) {
continue ;
}
2015-02-14 18:10:21 +00:00
else if ( errno ! = 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " ERROR capture: %s " , strerror ( errno ) ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
if ( length < = 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Broken socket connection. Try reconnect. " ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
used_buffer_length + = length ;
while ( used_buffer_length > 0 & & ( pos = ( char * ) memchr ( packet + exported_pdu_headers_size , ' \n ' , used_buffer_length ) ) ) {
int ms ;
struct tm date ;
time_t seconds ;
time_t secs = 0 ;
int nsecs = 0 ;
2017-01-17 20:21:56 +00:00
time_t t ;
2015-02-14 18:10:21 +00:00
2015-08-05 15:30:47 +00:00
length = ( gssize ) ( pos - packet ) + 1 ;
2015-02-14 18:10:21 +00:00
2017-01-17 20:21:56 +00:00
t = time ( NULL ) ;
date = * localtime ( & t ) ;
2015-02-14 18:10:21 +00:00
if ( 6 = = sscanf ( packet + exported_pdu_headers_size , " %d-%d %d:%d:%d.%d " , & date . tm_mon , & date . tm_mday , & date . tm_hour ,
& date . tm_min , & date . tm_sec , & ms ) ) {
date . tm_mon - = 1 ;
seconds = mktime ( & date ) ;
secs = ( time_t ) seconds ;
nsecs = ( int ) ( ms * 1e6 ) ;
}
2015-11-29 16:45:12 +00:00
endless_loop = extcap_dumper_dump ( extcap_dumper , packet ,
2015-02-14 18:10:21 +00:00
length ,
length ,
secs , nsecs ) ;
memmove ( packet + exported_pdu_headers_size , packet + length , used_buffer_length + exported_pdu_headers_size - length ) ;
used_buffer_length - = length - exported_pdu_headers_size ;
}
}
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_SUCCESS ;
2015-02-14 18:10:21 +00:00
}
/*----------------------------------------------------------------------------*/
/* Android Logger / Logcat */
/*----------------------------------------------------------------------------*/
static int capture_android_logcat ( char * interface , char * fifo ,
const char * adb_server_ip , unsigned short * adb_server_tcp_port ) {
struct extcap_dumper extcap_dumper ;
static char packet [ PACKET_LENGTH ] ;
static char helper_packet [ PACKET_LENGTH ] ;
2015-08-05 15:30:47 +00:00
gssize length ;
2015-04-11 20:40:40 +00:00
size_t used_buffer_length = 0 ;
2015-04-08 14:09:03 +00:00
socket_handle_t sock ;
2015-02-14 18:10:21 +00:00
const char * protocol_name ;
2015-04-11 20:40:40 +00:00
size_t exported_pdu_headers_size = 0 ;
2015-02-14 18:10:21 +00:00
struct exported_pdu_header exported_pdu_header_protocol_events ;
struct exported_pdu_header exported_pdu_header_protocol_normal ;
struct exported_pdu_header * exported_pdu_header_protocol ;
struct exported_pdu_header exported_pdu_header_end = { 0 , 0 } ;
static const char * wireshark_protocol_logcat = " logcat " ;
static const char * wireshark_protocol_logcat_events = " logcat_events " ;
const char * adb_transport = " 0012 " " host:transport-any " ;
const char * adb_log_main = " 0008 " " log:main " ;
const char * adb_log_system = " 000A " " log:system " ;
const char * adb_log_radio = " 0009 " " log:radio " ;
const char * adb_log_events = " 000A " " log:events " ;
const char * adb_transport_serial_templace = " %04x " " host:transport:%s " ;
const char * adb_command ;
uint16_t * payload_length ;
uint16_t * try_header_size ;
uint32_t * timestamp_secs ;
uint32_t * timestamp_nsecs ;
uint16_t header_size ;
int result ;
char * serial_number = NULL ;
2015-12-01 18:02:04 +00:00
size_t serial_number_length = 0 ;
2015-02-14 18:10:21 +00:00
extcap_dumper = extcap_dumper_open ( fifo , EXTCAP_ENCAP_WIRESHARK_UPPER_PDU ) ;
2015-12-01 18:02:04 +00:00
exported_pdu_header_protocol_events . tag = GUINT16_TO_BE ( WIRESHARK_UPPER_PDU_TAG_DISSECTOR_NAME ) ;
exported_pdu_header_protocol_events . length = GUINT16_TO_BE ( strlen ( wireshark_protocol_logcat_events ) + 2 ) ;
2015-02-14 18:10:21 +00:00
2015-12-01 18:02:04 +00:00
exported_pdu_header_protocol_normal . tag = GUINT16_TO_BE ( WIRESHARK_UPPER_PDU_TAG_DISSECTOR_NAME ) ;
exported_pdu_header_protocol_normal . length = GUINT16_TO_BE ( strlen ( wireshark_protocol_logcat ) + 2 ) ;
2015-02-14 18:10:21 +00:00
sock = adb_connect ( adb_server_ip , adb_server_tcp_port ) ;
2015-04-08 14:09:03 +00:00
if ( sock = = INVALID_SOCKET )
2016-03-12 18:24:56 +00:00
return EXIT_CODE_INVALID_SOCKET_9 ;
2015-02-14 18:10:21 +00:00
if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_MAIN ) & & strlen ( interface ) > strlen ( INTERFACE_ANDROID_LOGCAT_MAIN ) + 1 ) {
serial_number = interface + strlen ( INTERFACE_ANDROID_LOGCAT_MAIN ) + 1 ;
} else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_SYSTEM ) & & strlen ( interface ) > strlen ( INTERFACE_ANDROID_LOGCAT_SYSTEM ) + 1 ) {
serial_number = interface + strlen ( INTERFACE_ANDROID_LOGCAT_SYSTEM ) + 1 ;
} else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_RADIO ) & & strlen ( interface ) > strlen ( INTERFACE_ANDROID_LOGCAT_RADIO ) + 1 ) {
serial_number = interface + strlen ( INTERFACE_ANDROID_LOGCAT_RADIO ) + 1 ;
} else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_EVENTS ) & & strlen ( interface ) > strlen ( INTERFACE_ANDROID_LOGCAT_EVENTS ) + 1 ) {
serial_number = interface + strlen ( INTERFACE_ANDROID_LOGCAT_EVENTS ) + 1 ;
}
if ( ! serial_number ) {
result = adb_send ( sock , adb_transport ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport " ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
} else {
2015-12-01 18:02:04 +00:00
serial_number_length = strlen ( serial_number ) ;
2016-03-14 07:09:54 +00:00
result = g_snprintf ( packet , PACKET_LENGTH , adb_transport_serial_templace , 15 + serial_number_length , serial_number ) ;
if ( result < = 0 | | result > PACKET_LENGTH ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while completing adb packet " ) ;
2016-03-14 07:09:54 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_18 ;
2016-03-14 07:09:54 +00:00
}
2015-02-14 18:10:21 +00:00
result = adb_send ( sock , packet ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport " ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
}
if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_MAIN ) )
adb_command = adb_log_main ;
else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_SYSTEM ) )
adb_command = adb_log_system ;
else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_RADIO ) )
adb_command = adb_log_radio ;
else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_EVENTS ) )
adb_command = adb_log_events ;
else {
2016-08-02 20:39:28 +00:00
g_warning ( " Unknown interface: <%s> " , interface ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
result = adb_send ( sock , adb_command ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while sending command <%s> " , adb_command ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_ERROR_WHILE_SENDING_ADB_PACKET_4 ;
2015-02-14 18:10:21 +00:00
}
if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_EVENTS ) )
{
protocol_name = wireshark_protocol_logcat_events ;
exported_pdu_header_protocol = & exported_pdu_header_protocol_events ;
} else {
protocol_name = wireshark_protocol_logcat ;
exported_pdu_header_protocol = & exported_pdu_header_protocol_normal ;
}
2015-12-01 18:02:04 +00:00
memcpy ( packet , exported_pdu_header_protocol , sizeof ( struct exported_pdu_header ) ) ;
2015-02-14 18:10:21 +00:00
exported_pdu_headers_size + = sizeof ( struct exported_pdu_header ) ;
2015-12-01 18:02:04 +00:00
memcpy ( packet + exported_pdu_headers_size , protocol_name , GUINT16_FROM_BE ( exported_pdu_header_protocol - > length ) - 2 ) ;
exported_pdu_headers_size + = GUINT16_FROM_BE ( exported_pdu_header_protocol - > length ) ;
2015-02-14 18:10:21 +00:00
packet [ exported_pdu_headers_size - 1 ] = 0 ;
packet [ exported_pdu_headers_size - 2 ] = 0 ;
memcpy ( packet + exported_pdu_headers_size , & exported_pdu_header_end , sizeof ( struct exported_pdu_header ) ) ;
2015-12-01 18:02:04 +00:00
exported_pdu_headers_size + = sizeof ( struct exported_pdu_header ) + GUINT16_FROM_BE ( exported_pdu_header_end . length ) ;
2015-02-14 18:10:21 +00:00
SET_DATA ( payload_length , value_u16 , packet + exported_pdu_headers_size + 0 ) ;
SET_DATA ( try_header_size , value_u16 , packet + exported_pdu_headers_size + 2 ) ;
SET_DATA ( timestamp_secs , value_u32 , packet + exported_pdu_headers_size + 12 ) ;
SET_DATA ( timestamp_nsecs , value_u32 , packet + exported_pdu_headers_size + 16 ) ;
while ( endless_loop ) {
errno = 0 ;
2015-04-08 14:09:03 +00:00
length = recv ( sock , packet + exported_pdu_headers_size + used_buffer_length , ( int ) ( PACKET_LENGTH - exported_pdu_headers_size - used_buffer_length ) , 0 ) ;
2016-07-13 22:18:03 +00:00
if ( errno = = EAGAIN
# if EWOULDBLOCK != EAGAIN
| | errno = = EWOULDBLOCK
# endif
) {
continue ;
}
2015-02-14 18:10:21 +00:00
else if ( errno ! = 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " ERROR capture: %s " , strerror ( errno ) ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
if ( length < = 0 ) {
while ( endless_loop ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Broken socket connection. Try reconnect. " ) ;
2015-02-14 18:10:21 +00:00
used_buffer_length = 0 ;
closesocket ( sock ) ;
sock = adb_connect ( adb_server_ip , adb_server_tcp_port ) ;
2015-04-08 14:09:03 +00:00
if ( sock = = INVALID_SOCKET )
2016-03-12 18:24:56 +00:00
return EXIT_CODE_INVALID_SOCKET_10 ;
2015-02-14 18:10:21 +00:00
if ( ! serial_number ) {
result = adb_send ( sock , adb_transport ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport for <%s> " , adb_transport ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
} else {
2016-03-14 07:09:54 +00:00
result = g_snprintf ( ( char * ) helper_packet , PACKET_LENGTH , adb_transport_serial_templace , 15 + serial_number_length , serial_number ) ;
if ( result < = 0 | | result > PACKET_LENGTH ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while completing adb packet " ) ;
2016-03-14 07:09:54 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_19 ;
2016-03-14 07:09:54 +00:00
}
2015-02-14 18:10:21 +00:00
result = adb_send ( sock , helper_packet ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport for <%s> " , helper_packet ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
}
if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_MAIN ) )
adb_command = adb_log_main ;
else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_SYSTEM ) )
adb_command = adb_log_system ;
else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_RADIO ) )
adb_command = adb_log_radio ;
else if ( is_specified_interface ( interface , INTERFACE_ANDROID_LOGCAT_EVENTS ) )
adb_command = adb_log_events ;
else {
2016-08-02 20:39:28 +00:00
g_warning ( " Unknown interface: <%s> " , interface ) ;
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
}
result = adb_send ( sock , adb_command ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " WARNIG: Error while sending command <%s> " , adb_command ) ;
2015-02-14 18:10:21 +00:00
continue ;
}
break ;
}
}
used_buffer_length + = length + exported_pdu_headers_size ;
2015-12-01 18:02:04 +00:00
if ( * try_header_size ! = 24 )
2015-02-14 18:10:21 +00:00
header_size = 20 ;
else
header_size = * try_header_size ;
2015-08-05 15:30:47 +00:00
length = ( * payload_length ) + header_size + ( gssize ) exported_pdu_headers_size ;
2015-02-14 18:10:21 +00:00
2015-04-11 20:40:40 +00:00
while ( used_buffer_length > = exported_pdu_headers_size + header_size & & ( size_t ) length < = used_buffer_length ) {
2015-11-29 16:45:12 +00:00
endless_loop = extcap_dumper_dump ( extcap_dumper , packet ,
2015-02-14 18:10:21 +00:00
length ,
length ,
* timestamp_secs , * timestamp_nsecs ) ;
memmove ( packet + exported_pdu_headers_size , packet + length , used_buffer_length - length ) ;
used_buffer_length - = length ;
used_buffer_length + = exported_pdu_headers_size ;
2015-08-05 15:30:47 +00:00
length = ( * payload_length ) + header_size + ( gssize ) exported_pdu_headers_size ;
2015-02-14 18:10:21 +00:00
2015-12-01 18:02:04 +00:00
if ( * try_header_size ! = 24 )
2015-02-14 18:10:21 +00:00
header_size = 20 ;
else
header_size = * try_header_size ;
}
used_buffer_length - = exported_pdu_headers_size ;
}
2015-06-09 12:59:53 +00:00
closesocket ( sock ) ;
2016-02-23 10:12:17 +00:00
2016-03-12 18:24:56 +00:00
return EXIT_CODE_SUCCESS ;
2015-02-14 18:10:21 +00:00
}
2015-09-07 09:37:20 +00:00
/*----------------------------------------------------------------------------*/
/* Android Wifi Tcpdump */
/* The Tcpdump sends data in pcap format. So for using the extcap_dumper we */
/* need to unpack the pcap and then send the packet data to the dumper. */
/*----------------------------------------------------------------------------*/
static int capture_android_wifi_tcpdump ( char * interface , char * fifo ,
const char * adb_server_ip , unsigned short * adb_server_tcp_port ) {
struct extcap_dumper extcap_dumper ;
static char data [ PACKET_LENGTH ] ;
static char helpful_packet [ PACKET_LENGTH ] ;
gssize length ;
gssize used_buffer_length = 0 ;
gssize filter_buffer_length = 0 ;
gssize frame_length = 0 ;
socket_handle_t sock ;
const char * adb_transport = " 0012 " " host:transport-any " ;
const char * adb_transport_serial_templace = " %04x " " host:transport:%s " ;
const char * adb_shell_tcpdump = " 001D " " shell:tcpdump -n -s 0 -u -w - " ;
gint result ;
char * serial_number = NULL ;
2016-07-16 16:26:15 +00:00
static char filter_buffer [ PACKET_LENGTH ] ;
2015-12-01 18:02:04 +00:00
gint device_endiness = G_LITTLE_ENDIAN ;
2015-09-07 09:37:20 +00:00
gboolean global_header_skipped = FALSE ;
pcaprec_hdr_t p_header ;
/* First check for the device if it is connected or not */
sock = adb_connect ( adb_server_ip , adb_server_tcp_port ) ;
if ( sock = = INVALID_SOCKET )
2016-03-12 18:24:56 +00:00
return EXIT_CODE_INVALID_SOCKET_11 ;
2015-09-07 09:37:20 +00:00
if ( is_specified_interface ( interface , INTERFACE_ANDROID_WIFI_TCPDUMP )
& & strlen ( interface ) > strlen ( INTERFACE_ANDROID_WIFI_TCPDUMP ) + 1 ) {
serial_number = interface + strlen ( INTERFACE_ANDROID_WIFI_TCPDUMP ) + 1 ;
}
if ( ! serial_number ) {
result = adb_send ( sock , adb_transport ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport " ) ;
2015-09-07 09:37:20 +00:00
fflush ( stdout ) ;
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport for <%s> " ,
2015-09-07 09:37:20 +00:00
adb_transport ) ;
2015-09-13 08:37:47 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-09-07 09:37:20 +00:00
}
} else {
2016-03-14 07:09:54 +00:00
result = g_snprintf ( ( char * ) helpful_packet , PACKET_LENGTH , adb_transport_serial_templace ,
2015-09-07 09:37:20 +00:00
15 + strlen ( serial_number ) , serial_number ) ;
2016-03-14 07:09:54 +00:00
if ( result < = 0 | | result > PACKET_LENGTH ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while completing adb packet " ) ;
2016-03-14 07:09:54 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_BAD_SIZE_OF_ASSEMBLED_ADB_PACKET_20 ;
2016-03-14 07:09:54 +00:00
}
2015-09-07 09:37:20 +00:00
result = adb_send ( sock , helpful_packet ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport " ) ;
2015-09-13 08:37:47 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-09-07 09:37:20 +00:00
}
}
result = adb_send ( sock , adb_shell_tcpdump ) ;
if ( result ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Error while setting adb transport " ) ;
2015-09-13 08:37:47 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-09-07 09:37:20 +00:00
}
extcap_dumper = extcap_dumper_open ( fifo , EXTCAP_ENCAP_ETHERNET ) ;
while ( endless_loop ) {
char * i_position ;
errno = 0 ;
2015-09-11 17:31:14 +00:00
length = recv ( sock , data + used_buffer_length , ( int ) ( PACKET_LENGTH - used_buffer_length ) , 0 ) ;
2016-07-13 22:18:03 +00:00
if ( errno = = EAGAIN
# if EWOULDBLOCK != EAGAIN
| | errno = = EWOULDBLOCK
# endif
) {
2015-09-07 09:37:20 +00:00
continue ;
2016-07-13 22:18:03 +00:00
}
2015-09-07 09:37:20 +00:00
else if ( errno ! = 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " ERROR capture: %s " , strerror ( errno ) ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-09-07 09:37:20 +00:00
}
2016-02-06 18:14:20 +00:00
if ( length < = 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Broken socket connection. " ) ;
2016-02-06 18:14:20 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2016-02-06 18:14:20 +00:00
}
2015-09-07 09:37:20 +00:00
used_buffer_length + = length ;
/*
* Checking for the starting for the pcap global header using the magic number
*/
if ( used_buffer_length > 4 ) {
guint * magic_number ;
magic_number = ( guint * ) data ;
2015-12-01 18:02:04 +00:00
if ( * magic_number = = 0xd4c3b2a1 | | * magic_number = = 0xa1b2c3d4 ) {
if ( data [ 0 ] = = ( char ) 0xd4 ) {
device_endiness = G_LITTLE_ENDIAN ;
2015-09-07 09:37:20 +00:00
}
else {
2015-12-01 18:02:04 +00:00
device_endiness = G_BIG_ENDIAN ;
2015-09-07 09:37:20 +00:00
}
break ;
}
}
i_position = ( char * ) memchr ( data , ' \n ' , used_buffer_length ) ;
if ( i_position & & i_position < data + used_buffer_length ) {
memmove ( data , i_position + 1 , used_buffer_length - ( i_position + 1 - data ) ) ;
used_buffer_length = used_buffer_length - ( gssize ) ( i_position + 1 - data ) ;
}
}
/*
* The data we are getting from the tcpdump stdoutput stream as the stdout is the text stream it is
* convertinng the 0 A = 0 D0A ; So we need to remove these extra character .
*/
filter_buffer_length = 0 ;
while ( endless_loop ) {
2015-09-11 17:31:14 +00:00
gssize i = 0 , read_offset , j = 0 ;
2015-09-07 09:37:20 +00:00
/*Filter the received data to get rid of unwanted 0DOA*/
for ( i = 0 ; i < ( used_buffer_length - 1 ) ; i + + ) {
if ( data [ i ] = = 0x0d & & data [ i + 1 ] = = 0x0a ) {
i + + ;
}
filter_buffer [ filter_buffer_length + + ] = data [ i ] ;
}
/* Put the last characters in the start if it is still left in buffer.*/
for ( j = 0 ; i < used_buffer_length ; i + + , j + + ) {
data [ j ] = data [ i ] ;
}
used_buffer_length = j ;
if ( global_header_skipped = = FALSE & & filter_buffer_length > = PCAP_GLOBAL_HEADER_LENGTH ) {
/*Skip the Global pcap header*/
filter_buffer_length - = PCAP_GLOBAL_HEADER_LENGTH ;
/*Move the remaining content from start*/
memmove ( filter_buffer , filter_buffer + PCAP_GLOBAL_HEADER_LENGTH , filter_buffer_length ) ;
global_header_skipped = TRUE ;
}
else if ( global_header_skipped & & filter_buffer_length > PCAP_RECORD_HEADER_LENGTH ) {
read_offset = 0 ;
while ( filter_buffer_length > PCAP_RECORD_HEADER_LENGTH ) {
gchar * packet ;
packet = filter_buffer + read_offset ;
/*
* This fills the pcap header info based upon the endianess of the machine and android device .
* If the endianess are different , pcap header bytes received from the android device are swapped
* to be read properly by the machine else pcap header bytes are taken as it is .
*/
if ( device_endiness = = G_BYTE_ORDER ) {
p_header = * ( ( pcaprec_hdr_t * ) packet ) ;
}
else {
p_header . ts_sec = GUINT32_SWAP_LE_BE ( * ( ( guint32 * ) packet ) ) ;
p_header . ts_usec = GUINT32_SWAP_LE_BE ( * ( guint32 * ) ( packet + 4 ) ) ;
p_header . incl_len = GUINT32_SWAP_LE_BE ( * ( guint32 * ) ( packet + 8 ) ) ;
p_header . orig_len = GUINT32_SWAP_LE_BE ( * ( guint32 * ) ( packet + 12 ) ) ;
}
2015-09-11 17:31:14 +00:00
if ( ( gssize ) ( p_header . incl_len + PCAP_RECORD_HEADER_LENGTH ) < = filter_buffer_length ) {
2015-09-07 09:37:20 +00:00
/*
* It was observed that some times tcpdump reports the length of packet as ' 0 ' and that leads to the
2016-08-02 20:39:28 +00:00
* ( Warn Error " Less data was read than was expected " while reading )
2015-09-07 09:37:20 +00:00
* So to avoid this error we are checking for length of packet before passing it to dumper .
*/
if ( p_header . incl_len > 0 ) {
2015-11-29 16:45:12 +00:00
endless_loop = extcap_dumper_dump ( extcap_dumper , filter_buffer + read_offset + PCAP_RECORD_HEADER_LENGTH ,
2015-09-07 09:37:20 +00:00
p_header . incl_len , p_header . orig_len , p_header . ts_sec , p_header . ts_usec ) ;
}
frame_length = p_header . incl_len + PCAP_RECORD_HEADER_LENGTH ;
/*update the offset value for the next packet*/
filter_buffer_length - = frame_length ;
read_offset + = frame_length ;
}
else {
/*The complete packet has not yet received*/
break ;
}
}
if ( read_offset ! = 0 ) {
/*Move the rest of the filter data to the beginning of the filter_buffer */
memmove ( filter_buffer , filter_buffer + read_offset , filter_buffer_length ) ;
}
}
/*Get the data from the tcpdump process running in the android device*/
while ( endless_loop ) {
errno = 0 ;
2015-09-11 17:31:14 +00:00
length = recv ( sock , data + used_buffer_length , ( int ) ( PACKET_LENGTH - ( used_buffer_length + filter_buffer_length ) ) , 0 ) ;
2016-07-13 22:18:03 +00:00
if ( errno = = EAGAIN
# if EWOULDBLOCK != EAGAIN
| | errno = = EWOULDBLOCK
# endif
) {
2015-09-07 09:37:20 +00:00
continue ;
}
else if ( errno ! = 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " ERROR capture: %s " , strerror ( errno ) ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2015-09-07 09:37:20 +00:00
}
2016-02-06 18:14:20 +00:00
if ( length < = 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Broken socket connection. " ) ;
2016-02-06 18:14:20 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_GENERIC ;
2016-02-06 18:14:20 +00:00
}
if ( used_buffer_length + = length > 1 ) {
2015-09-07 09:37:20 +00:00
break ;
}
}
}
2016-01-21 08:23:42 +00:00
closesocket ( sock ) ;
2016-03-12 18:24:56 +00:00
return EXIT_CODE_SUCCESS ;
2015-09-07 09:37:20 +00:00
}
2015-02-14 18:10:21 +00:00
int main ( int argc , char * * argv ) {
2016-09-11 10:00:10 +00:00
int ret = EXIT_CODE_GENERIC ;
2015-02-14 18:10:21 +00:00
int option_idx = 0 ;
int result ;
const char * adb_server_ip = NULL ;
unsigned short * adb_server_tcp_port = NULL ;
unsigned int logcat_text = 0 ;
2017-01-28 18:16:15 +00:00
unsigned int logcat_ignore_log_buffer = 0 ;
const char * logcat_custom_parameter = NULL ;
2015-02-14 18:10:21 +00:00
const char * default_adb_server_ip = " 127.0.0.1 " ;
unsigned short default_adb_server_tcp_port = 5037 ;
2015-04-09 20:38:58 +00:00
unsigned short local_adb_server_tcp_port ;
unsigned short local_bt_server_tcp_port ;
unsigned short local_bt_local_tcp_port ;
2015-02-14 18:10:21 +00:00
unsigned short * bt_server_tcp_port = NULL ;
unsigned int bt_forward_socket = 0 ;
const char * bt_local_ip = NULL ;
unsigned short * bt_local_tcp_port = NULL ;
unsigned short default_bt_server_tcp_port = 4330 ;
const char * default_bt_local_ip = " 127.0.0.1 " ;
unsigned short default_bt_local_tcp_port = 4330 ;
2016-02-23 10:12:17 +00:00
extcap_parameters * extcap_conf = NULL ;
2017-01-06 23:14:23 +00:00
char * help_url ;
2016-08-02 13:13:13 +00:00
char * help_header = NULL ;
2016-02-23 10:12:17 +00:00
2015-02-14 18:10:21 +00:00
# ifdef _WIN32
WSADATA wsaData ;
2015-04-08 14:09:03 +00:00
attach_parent_console ( ) ;
2015-02-14 18:10:21 +00:00
# endif /* _WIN32 */
2016-08-02 13:13:13 +00:00
extcap_conf = g_new0 ( extcap_parameters , 1 ) ;
2017-01-06 23:14:23 +00:00
help_url = data_file_url ( " androiddump.html " ) ;
2016-08-24 13:10:51 +00:00
extcap_base_set_util_info ( extcap_conf , argv [ 0 ] , ANDROIDDUMP_VERSION_MAJOR , ANDROIDDUMP_VERSION_MINOR ,
2017-01-06 23:14:23 +00:00
ANDROIDDUMP_VERSION_RELEASE , help_url ) ;
g_free ( help_url ) ;
2016-08-02 13:13:13 +00:00
help_header = g_strdup_printf (
" %s --extcap-interfaces [--adb-server-ip=<arg>] [--adb-server-tcp-port=<arg>] \n "
" %s --extcap-interface=INTERFACE --extcap-dlts \n "
" %s --extcap-interface=INTERFACE --extcap-config \n "
2016-08-24 10:42:15 +00:00
" %s --extcap-interface=INTERFACE --fifo=PATH_FILENAME --capture \n "
2016-09-12 17:49:50 +00:00
" \n INTERFACE has the form TYPE-DEVICEID: \n "
" \t " " For example: " INTERFACE_ANDROID_BLUETOOTH_BTSNOOP_NET " -W3D7N15C29005648 " " \n "
" \n "
" \t TYPE is one of: \n "
" \t " INTERFACE_ANDROID_LOGCAT_MAIN " \n "
" \t " INTERFACE_ANDROID_LOGCAT_SYSTEM " \n "
" \t " INTERFACE_ANDROID_LOGCAT_RADIO " \n "
" \t " INTERFACE_ANDROID_LOGCAT_EVENTS " \n "
" \t " INTERFACE_ANDROID_LOGCAT_TEXT_MAIN " \n "
" \t " INTERFACE_ANDROID_LOGCAT_TEXT_SYSTEM " \n "
" \t " INTERFACE_ANDROID_LOGCAT_TEXT_RADIO " \n "
" \t " INTERFACE_ANDROID_LOGCAT_TEXT_EVENTS " \n "
" \t " INTERFACE_ANDROID_LOGCAT_TEXT_CRASH " \n "
" \t " INTERFACE_ANDROID_BLUETOOTH_HCIDUMP " \n "
" \t " INTERFACE_ANDROID_BLUETOOTH_EXTERNAL_PARSER " \n "
" \t " INTERFACE_ANDROID_BLUETOOTH_BTSNOOP_NET " \n "
" \t " INTERFACE_ANDROID_WIFI_TCPDUMP " \n "
" \n "
" \t " " DEVICEID is the identifier of the device provided by Android SDK (see \" adb devices \" ) \n "
" \t " " For example: W3D7N15C29005648 " " \n " ,
2016-08-02 13:13:13 +00:00
argv [ 0 ] , argv [ 0 ] , argv [ 0 ] , argv [ 0 ] ) ;
extcap_help_add_header ( extcap_conf , help_header ) ;
g_free ( help_header ) ;
extcap_help_add_option ( extcap_conf , " --help " , " print this help " ) ;
extcap_help_add_option ( extcap_conf , " --adb-server-ip <IP> " , " the IP address of the ADB server " ) ;
extcap_help_add_option ( extcap_conf , " --adb-server-tcp-port <port> " , " the TCP port of the ADB server " ) ;
2017-01-28 18:16:15 +00:00
extcap_help_add_option ( extcap_conf , " --logcat-text " , " use logcat text format " ) ;
extcap_help_add_option ( extcap_conf , " --logcat-ignore-log-buffer " , " ignore log buffer " ) ;
extcap_help_add_option ( extcap_conf , " --logcat-custom-options <text> " , " use custom logcat parameters " ) ;
2016-08-02 13:13:13 +00:00
extcap_help_add_option ( extcap_conf , " --bt-server-tcp-port <port> " , " bluetooth server TCP port " ) ;
extcap_help_add_option ( extcap_conf , " --bt-forward-socket <path> " , " bluetooth forward socket " ) ;
extcap_help_add_option ( extcap_conf , " --bt-local-ip <IP> " , " the bluetooth local IP " ) ;
extcap_help_add_option ( extcap_conf , " --bt-local-tcp-port <port> " , " the bluetooth local TCP port " ) ;
2015-02-14 18:10:21 +00:00
opterr = 0 ;
optind = 0 ;
if ( argc = = 1 ) {
2016-08-02 13:13:13 +00:00
extcap_help_print ( extcap_conf ) ;
2016-09-11 10:00:10 +00:00
ret = EXIT_CODE_SUCCESS ;
goto end ;
2015-02-14 18:10:21 +00:00
}
while ( ( result = getopt_long ( argc , argv , " " , longopts , & option_idx ) ) ! = - 1 ) {
switch ( result ) {
case OPT_VERSION :
2016-08-24 08:43:11 +00:00
printf ( " %s \n " , extcap_conf - > version ) ;
2016-09-11 10:00:10 +00:00
ret = EXIT_CODE_SUCCESS ;
goto end ;
2015-02-14 18:10:21 +00:00
case OPT_HELP :
2016-08-02 13:13:13 +00:00
extcap_help_print ( extcap_conf ) ;
2016-09-11 10:00:10 +00:00
ret = EXIT_CODE_SUCCESS ;
goto end ;
2015-02-14 18:10:21 +00:00
case OPT_CONFIG_ADB_SERVER_IP :
2015-12-22 10:51:17 +00:00
adb_server_ip = optarg ;
2015-02-14 18:10:21 +00:00
break ;
case OPT_CONFIG_ADB_SERVER_TCP_PORT :
2015-04-09 20:38:58 +00:00
adb_server_tcp_port = & local_adb_server_tcp_port ;
2015-05-22 15:35:20 +00:00
if ( ! optarg ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Impossible exception. Parameter required argument, but there is no it right now. " ) ;
2016-09-11 10:00:10 +00:00
goto end ;
2015-05-22 15:35:20 +00:00
}
2016-08-31 08:14:33 +00:00
if ( ! ws_strtou16 ( optarg , NULL , adb_server_tcp_port ) ) {
g_warning ( " Invalid adb server TCP port: %s " , optarg ) ;
goto end ;
}
2015-02-14 18:10:21 +00:00
break ;
case OPT_CONFIG_LOGCAT_TEXT :
2017-01-28 18:16:15 +00:00
if ( optarg & & ! * optarg )
logcat_text = TRUE ;
else
logcat_text = ( g_ascii_strncasecmp ( optarg , " TRUE " , 4 ) = = 0 ) ;
break ;
case OPT_CONFIG_LOGCAT_IGNORE_LOG_BUFFER :
if ( optarg = = NULL | | ( optarg & & ! * optarg ) )
logcat_ignore_log_buffer = TRUE ;
else
logcat_ignore_log_buffer = ( g_ascii_strncasecmp ( optarg , " TRUE " , 4 ) = = 0 ) ;
break ;
case OPT_CONFIG_LOGCAT_CUSTOM_OPTIONS :
if ( optarg = = NULL | | ( optarg & & * optarg = = ' \0 ' ) ) {
logcat_custom_parameter = NULL ;
break ;
}
if ( g_regex_match_simple ( " (^| \\ s)-[bBcDfgLnpPrv] " , optarg , ( GRegexCompileFlags ) 0 , ( GRegexMatchFlags ) 0 ) ) {
g_error ( " Found prohibited option in logcat-custom-options " ) ;
return EXIT_CODE_GENERIC ;
}
logcat_custom_parameter = optarg ;
2015-02-14 18:10:21 +00:00
break ;
case OPT_CONFIG_BT_SERVER_TCP_PORT :
2015-04-09 20:38:58 +00:00
bt_server_tcp_port = & local_bt_server_tcp_port ;
2015-05-22 15:35:20 +00:00
if ( ! optarg ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Impossible exception. Parameter required argument, but there is no it right now. " ) ;
2016-09-11 10:00:10 +00:00
goto end ;
2015-05-22 15:35:20 +00:00
}
2016-08-31 08:14:33 +00:00
if ( ! ws_strtou16 ( optarg , NULL , bt_server_tcp_port ) ) {
g_warning ( " Invalid bluetooth server TCP port: %s " , optarg ) ;
goto end ;
}
2015-02-14 18:10:21 +00:00
break ;
case OPT_CONFIG_BT_FORWARD_SOCKET :
2015-05-03 21:39:23 +00:00
bt_forward_socket = ( g_ascii_strncasecmp ( optarg , " TRUE " , 4 ) = = 0 ) ;
2015-02-14 18:10:21 +00:00
break ;
case OPT_CONFIG_BT_LOCAL_IP :
2015-12-22 10:51:17 +00:00
bt_local_ip = optarg ;
2015-02-14 18:10:21 +00:00
break ;
case OPT_CONFIG_BT_LOCAL_TCP_PORT :
2015-04-09 20:38:58 +00:00
bt_local_tcp_port = & local_bt_local_tcp_port ;
2015-05-22 15:35:20 +00:00
if ( ! optarg ) {
2016-08-02 20:39:28 +00:00
g_warning ( " Impossible exception. Parameter required argument, but there is no it right now. " ) ;
2016-09-11 10:00:10 +00:00
goto end ;
2015-05-22 15:35:20 +00:00
}
2016-08-31 08:14:33 +00:00
if ( ! ws_strtou16 ( optarg , NULL , bt_local_tcp_port ) ) {
g_warning ( " Invalid bluetooth local tcp port: %s " , optarg ) ;
goto end ;
}
2015-02-14 18:10:21 +00:00
break ;
default :
2016-02-23 10:12:17 +00:00
if ( ! extcap_base_parse_options ( extcap_conf , result - EXTCAP_OPT_LIST_INTERFACES , optarg ) )
{
2016-09-11 10:00:10 +00:00
g_warning ( " Invalid argument <%s>. Try --help. \n " , argv [ optind - 1 ] ) ;
goto end ;
2016-02-23 10:12:17 +00:00
}
2015-02-14 18:10:21 +00:00
}
}
if ( ! adb_server_ip )
adb_server_ip = default_adb_server_ip ;
if ( ! adb_server_tcp_port )
adb_server_tcp_port = & default_adb_server_tcp_port ;
if ( ! bt_server_tcp_port )
bt_server_tcp_port = & default_bt_server_tcp_port ;
if ( ! bt_local_ip )
bt_local_ip = default_bt_local_ip ;
if ( ! bt_local_tcp_port )
bt_local_tcp_port = & default_bt_local_tcp_port ;
# ifdef _WIN32
result = WSAStartup ( MAKEWORD ( 1 , 1 ) , & wsaData ) ;
if ( result ! = 0 ) {
2016-08-02 20:39:28 +00:00
g_warning ( " WSAStartup failed with %d " , result ) ;
2016-09-11 10:00:10 +00:00
goto end ;
2015-02-14 18:10:21 +00:00
}
# endif /* _WIN32 */
2016-03-15 18:06:36 +00:00
if ( extcap_conf - > do_list_interfaces )
register_interfaces ( extcap_conf , adb_server_ip , adb_server_tcp_port ) ;
2016-09-11 10:00:10 +00:00
if ( extcap_base_handle_interface ( extcap_conf ) ) {
ret = EXIT_CODE_SUCCESS ;
goto end ;
}
2015-02-14 18:10:21 +00:00
2016-09-11 10:00:10 +00:00
if ( extcap_conf - > show_config ) {
ret = list_config ( extcap_conf - > interface ) ;
goto end ;
}
2015-02-14 18:10:21 +00:00
2016-02-23 10:12:17 +00:00
if ( extcap_conf - > capture ) {
if ( extcap_conf - > interface & & ( is_specified_interface ( extcap_conf - > interface , INTERFACE_ANDROID_LOGCAT_MAIN ) | |
is_specified_interface ( extcap_conf - > interface , INTERFACE_ANDROID_LOGCAT_SYSTEM ) | |
is_specified_interface ( extcap_conf - > interface , INTERFACE_ANDROID_LOGCAT_RADIO ) | |
is_specified_interface ( extcap_conf - > interface , INTERFACE_ANDROID_LOGCAT_EVENTS ) ) )
2015-02-14 18:10:21 +00:00
if ( logcat_text )
2017-01-28 18:16:15 +00:00
ret = capture_android_logcat_text ( extcap_conf - > interface ,
extcap_conf - > fifo , adb_server_ip , adb_server_tcp_port ,
logcat_ignore_log_buffer , logcat_custom_parameter ) ;
2015-02-14 18:10:21 +00:00
else
2017-01-28 18:16:15 +00:00
ret = capture_android_logcat ( extcap_conf - > interface ,
extcap_conf - > fifo , adb_server_ip , adb_server_tcp_port ) ;
2016-02-23 10:12:17 +00:00
else if ( extcap_conf - > interface & & ( is_specified_interface ( extcap_conf - > interface , INTERFACE_ANDROID_LOGCAT_TEXT_MAIN ) | |
is_specified_interface ( extcap_conf - > interface , INTERFACE_ANDROID_LOGCAT_TEXT_SYSTEM ) | |
is_specified_interface ( extcap_conf - > interface , INTERFACE_ANDROID_LOGCAT_TEXT_RADIO ) | |
is_specified_interface ( extcap_conf - > interface , INTERFACE_ANDROID_LOGCAT_TEXT_EVENTS ) | |
( is_specified_interface ( extcap_conf - > interface , INTERFACE_ANDROID_LOGCAT_TEXT_CRASH ) ) ) )
2017-01-28 18:16:15 +00:00
ret = capture_android_logcat_text ( extcap_conf - > interface ,
extcap_conf - > fifo , adb_server_ip , adb_server_tcp_port ,
logcat_ignore_log_buffer , logcat_custom_parameter ) ;
2016-02-23 10:12:17 +00:00
else if ( extcap_conf - > interface & & is_specified_interface ( extcap_conf - > interface , INTERFACE_ANDROID_BLUETOOTH_HCIDUMP ) )
2016-09-11 10:00:10 +00:00
ret = capture_android_bluetooth_hcidump ( extcap_conf - > interface , extcap_conf - > fifo , adb_server_ip , adb_server_tcp_port ) ;
2016-02-23 10:12:17 +00:00
else if ( extcap_conf - > interface & & is_specified_interface ( extcap_conf - > interface , INTERFACE_ANDROID_BLUETOOTH_EXTERNAL_PARSER ) )
2016-09-11 10:00:10 +00:00
ret = capture_android_bluetooth_external_parser ( extcap_conf - > interface , extcap_conf - > fifo , adb_server_ip , adb_server_tcp_port ,
2015-02-14 18:10:21 +00:00
bt_server_tcp_port , bt_forward_socket , bt_local_ip , bt_local_tcp_port ) ;
2016-02-23 10:12:17 +00:00
else if ( extcap_conf - > interface & & ( is_specified_interface ( extcap_conf - > interface , INTERFACE_ANDROID_BLUETOOTH_BTSNOOP_NET ) ) )
2016-09-11 10:00:10 +00:00
ret = capture_android_bluetooth_btsnoop_net ( extcap_conf - > interface , extcap_conf - > fifo , adb_server_ip , adb_server_tcp_port ) ;
2016-02-23 10:12:17 +00:00
else if ( extcap_conf - > interface & & ( is_specified_interface ( extcap_conf - > interface , INTERFACE_ANDROID_WIFI_TCPDUMP ) ) )
2016-09-11 10:00:10 +00:00
ret = capture_android_wifi_tcpdump ( extcap_conf - > interface , extcap_conf - > fifo , adb_server_ip , adb_server_tcp_port ) ;
goto end ;
2015-02-14 18:10:21 +00:00
}
2016-09-11 10:00:10 +00:00
/* no action was given, assume success */
ret = EXIT_CODE_SUCCESS ;
end :
2016-02-23 10:12:17 +00:00
/* clean up stuff */
extcap_base_cleanup ( & extcap_conf ) ;
2017-02-14 17:22:57 +00:00
# ifndef ANDROIDDUMP_USE_LIBPCAP
2017-02-04 15:26:34 +00:00
wtap_cleanup ( ) ;
2017-02-14 17:22:57 +00:00
# endif
2016-09-11 10:00:10 +00:00
return ret ;
2015-02-14 18:10:21 +00:00
}
2015-04-08 14:09:03 +00:00
# ifdef _WIN32
2016-07-16 16:09:27 +00:00
int _stdcall
WinMain ( struct HINSTANCE__ * hInstance ,
struct HINSTANCE__ * hPrevInstance ,
char * lpszCmdLine ,
int nCmdShow )
{
2015-04-08 14:09:03 +00:00
return main ( __argc , __argv ) ;
}
# endif
2015-02-14 18:10:21 +00:00
/*
* Editor modelines - http : //www.wireshark.org/tools/modelines.html
*
* Local variables :
* c - basic - offset : 4
* tab - width : 8
* indent - tabs - mode : nil
* End :
*
* vi : set shiftwidth = 4 tabstop = 8 expandtab :
* : indentSize = 4 : tabSize = 8 : noTabs = true :
*/