diff --git a/CMakeLists.txt b/CMakeLists.txt index cc37acdbdf..a40b8c6f87 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -508,6 +508,7 @@ foreach(THIS_FLAG ${WIRESHARK_LD_FLAGS}) endforeach() if(ENABLE_STATIC) + set(BUILD_SHARED_LIBS 0) set(LINK_MODE_LIB STATIC) set(LINK_MODE_MODULE STATIC) else() @@ -1132,6 +1133,7 @@ set(INSTALL_DIRS ) set(INSTALL_FILES + ${CMAKE_BINARY_DIR}/androiddump.html ${CMAKE_BINARY_DIR}/AUTHORS-SHORT ${CMAKE_BINARY_DIR}/capinfos.html ${CMAKE_BINARY_DIR}/captype.html @@ -1141,6 +1143,7 @@ set(INSTALL_FILES ${CMAKE_BINARY_DIR}/dftest.html ${CMAKE_BINARY_DIR}/dumpcap.html ${CMAKE_BINARY_DIR}/editcap.html + ${CMAKE_BINARY_DIR}/extcap.html ${CMAKE_BINARY_DIR}/asn2deb.html ${CMAKE_BINARY_DIR}/idl2deb.html ${CMAKE_BINARY_DIR}/idl2wrs.html @@ -1170,11 +1173,13 @@ else() endif() set(MAN1_FILES + ${CMAKE_BINARY_DIR}/androiddump.1 ${CMAKE_BINARY_DIR}/capinfos.1 ${CMAKE_BINARY_DIR}/captype.1 ${CMAKE_BINARY_DIR}/dftest.1 ${CMAKE_BINARY_DIR}/dumpcap.1 ${CMAKE_BINARY_DIR}/editcap.1 + ${CMAKE_BINARY_DIR}/extcap.4 ${CMAKE_BINARY_DIR}/idl2wrs.1 ${CMAKE_BINARY_DIR}/mergecap.1 ${CMAKE_BINARY_DIR}/randpkt.1 @@ -2124,7 +2129,6 @@ if(BUILD_androiddump) ) endif() set(androiddump_FILES - ${GLIB2_LIBRARIES} extcap/androiddump.c ) @@ -2132,7 +2136,11 @@ if(BUILD_androiddump) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/run/extcap) add_executable(androiddump ${androiddump_FILES}) add_dependencies(androiddump gitversion) - set_target_properties(androiddump PROPERTIES LINK_FLAGS "${WS_LINK_FLAGS}") + if(WIN32) + set_target_properties(androiddump PROPERTIES LINK_FLAGS "${WS_LINK_FLAGS} /SUBSYSTEM:WINDOWS") + else() + set_target_properties(androiddump PROPERTIES LINK_FLAGS "${WS_LINK_FLAGS}") + endif() set_target_properties(androiddump PROPERTIES FOLDER "Executables/Extcaps") target_link_libraries(androiddump ${androiddump_LIBS}) install(TARGETS androiddump RUNTIME DESTINATION ${EXTCAP_DIR}) @@ -2201,11 +2209,13 @@ if(ENABLE_APPLICATION_BUNDLE) add_dependencies(app_bundle ${PROGLIST}) endif() +pod2manhtml( ${CMAKE_SOURCE_DIR}/doc/androiddump 1 ) pod2manhtml( ${CMAKE_SOURCE_DIR}/doc/capinfos 1 ) pod2manhtml( ${CMAKE_SOURCE_DIR}/doc/captype 1 ) pod2manhtml( ${CMAKE_SOURCE_DIR}/doc/dftest 1 ) pod2manhtml( ${CMAKE_SOURCE_DIR}/doc/dumpcap 1 ) pod2manhtml( ${CMAKE_SOURCE_DIR}/doc/editcap 1 ) +pod2manhtml( ${CMAKE_SOURCE_DIR}/doc/extcap 4 ) pod2manhtml( ${CMAKE_SOURCE_DIR}/doc/asn2deb 1 ) pod2manhtml( ${CMAKE_SOURCE_DIR}/doc/idl2deb 1 ) pod2manhtml( ${CMAKE_SOURCE_DIR}/doc/idl2wrs 1 ) @@ -2222,6 +2232,7 @@ add_custom_target( html_docs ALL DEPENDS ${CMAKE_BINARY_DIR}/AUTHORS-SHORT + androiddump.html capinfos.html captype.html dftest.html @@ -2253,6 +2264,7 @@ set(CLEAN_FILES ${captype_FILES} ${editcap_FILES} ${dumpcap_FILES} + ${androiddump_FILES} ) if (WERROR) diff --git a/Makefile.nmake b/Makefile.nmake index 9940e1e5c0..ec82c16dcb 100644 --- a/Makefile.nmake +++ b/Makefile.nmake @@ -68,6 +68,7 @@ dftest_OBJECTS = $(dftest_SOURCES:.c=.obj) dumpcap_OBJECTS = $(dumpcap_SOURCES:.c=.obj) randpkt_OBJECTS = $(randpkt_SOURCES:.c=.obj) reordercap_OBJECTS = $(reordercap_SOURCES:.c=.obj) +androiddump_OBJECTS = $(androiddump_SOURCES:.c=.obj) # # psapi.lib see http://msdn.microsoft.com/en-us/library/windows/desktop/ms683219(v=vs.85).aspx @@ -174,6 +175,11 @@ text2pcap_LIBS= \ wsutil\libwsutil.lib \ $(GLIB_LIBS) +androiddump_LIBS= wiretap\wiretap-$(WTAP_VERSION).lib \ + wsock32.lib user32.lib \ + wsutil\libwsutil.lib \ + $(GLIB_LIBS) + dumpcap_LIBS= \ wsock32.lib user32.lib \ caputils\libcaputils.lib \ @@ -204,7 +210,7 @@ randpkt_LIBS= wiretap\wiretap-$(WTAP_VERSION).lib \ EXECUTABLES=$(PROGRAM_NAME_GTK).exe tshark.exe tfshark.exe rawshark.exe \ capinfos.exe captype.exe editcap.exe mergecap.exe text2pcap.exe \ - randpkt.exe reordercap.exe dumpcap.exe dftest.exe + randpkt.exe reordercap.exe dumpcap.exe androiddump.exe dftest.exe !IFDEF QT5_BASE_DIR EXECUTABLES=$(EXECUTABLES) $(PROGRAM_NAME).exe @@ -422,6 +428,15 @@ randpkt.exe : $(randpkt_OBJECTS) mt.exe -nologo -manifest "randpkt.exe.manifest" -outputresource:randpkt.exe;1 !ENDIF +androiddump.exe : $(LIBS_CHECK) config.h $(androiddump_OBJECTS) wsutil\libwsutil.lib wiretap\wiretap-$(WTAP_VERSION).lib + @echo Linking $@ + $(LINK) @<< + /OUT:androiddump.exe $(conflags) $(conlibsdll) $(LDFLAGS) /SUBSYSTEM:WINDOWS androiddump.obj $(androiddump_LIBS) +<< +!IFDEF MANIFEST_INFO_REQUIRED + mt.exe -nologo -manifest "androiddump.exe.manifest" -outputresource:androiddump.exe;1 +!ENDIF + dumpcap.exe : $(LIBS_CHECK) config.h $(dumpcap_OBJECTS) caputils wsutil\libwsutil.lib image\dumpcap.res @echo Linking $@ $(LINK) @<< @@ -559,6 +574,7 @@ test-programs: clean-local: rm -f $(wireshark_gtk_OBJECTS) $(tshark_OBJECTS) $(tfshark_OBJECTS) $(dumpcap_OBJECTS) $(rawshark_OBJECTS) \ $(EXECUTABLES) *.nativecodeanalysis.xml *.pdb *.sbr *.exe.manifest \ + androiddump.obj \ capinfos.obj capinfos.exp capinfos.lib \ captype.obj captype.exp captype.lib \ editcap.obj editcap.exp editcap.lib \ @@ -1206,6 +1222,20 @@ install-generated-files: doc if exist $(PROGRAM_NAME_GTK).pdb xcopy $(PROGRAM_NAME_GTK).pdb $(INSTALL_DIR) /d if exist $(PROGRAM_NAME_GTK).bsc xcopy $(PROGRAM_NAME_GTK).bsc $(INSTALL_DIR) /d if exist ".\docbook\user-guide.chm" xcopy ".\docbook\user-guide.chm" $(INSTALL_DIR) /d + if not exist $(INSTALL_DIR)\extcap mkdir $(INSTALL_DIR)\extcap + if exist androiddump.exe xcopy androiddump.exe $(INSTALL_DIR)\extcap /d + if exist androiddump.pdb xcopy androiddump.pdb $(INSTALL_DIR)\extcap /d + xcopy ".\wiretap\wiretap-$(WTAP_VERSION).dll" $(INSTALL_DIR)\extcap /d + xcopy ".\wsutil\libwsutil.dll" $(INSTALL_DIR)\extcap /d + xcopy $(GTK_DIR)\bin\libglib-2.0-0.dll $(INSTALL_DIR)\extcap /d + xcopy $(GTK_DIR)\bin\libgmodule-2.0-0.dll $(INSTALL_DIR)\extcap /d + xcopy $(ZLIB_DIR)\zlib1.dll $(INSTALL_DIR)\extcap /d + xcopy $(GTK_DIR)\bin\$(INTL_DLL) $(INSTALL_DIR)\extcap /d +!IFDEF GNUTLS_DIR + xcopy $(GNUTLS_DIR)\bin\$(GCC_DLL) $(INSTALL_DIR)\extcap /d + xcopy $(GNUTLS_DIR)\bin\libgcrypt-20.dll $(INSTALL_DIR)\extcap /d + xcopy $(GNUTLS_DIR)\bin\$(GPGERROR_DLL) $(INSTALL_DIR)\extcap /d +!ENDIF if exist capinfos.exe xcopy capinfos.exe $(INSTALL_DIR) /d if exist capinfos.pdb xcopy capinfos.pdb $(INSTALL_DIR) /d if exist captype.exe xcopy captype.exe $(INSTALL_DIR) /d diff --git a/doc/Makefile.am b/doc/Makefile.am index 4394a6dd31..2a0b7b11e6 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -70,7 +70,8 @@ man1_MANS = \ @dumpcap_man@ \ @rawshark_man@ \ @dftest_man@ \ - @randpkt_man@ + @randpkt_man@ \ + @androiddump_man@ man4_MANS = @wiresharkfilter_man@ man_MANS = @@ -81,8 +82,8 @@ noinst_DATA = asn2deb.1 asn2deb.html idl2deb.1 idl2deb.html idl2wrs.1 idl2wrs.ht pkgdata_DATA = AUTHORS-SHORT $(top_srcdir)/docbook/ws.css wireshark.html \ tshark.html wireshark-filter.html capinfos.html editcap.html \ - mergecap.html reordercap.html text2pcap.html dumpcap.html rawshark.html \ - dftest.html randpkt.html + mergecap.html reordercap.html text2pcap.html dumpcap.html androiddump.html \ + rawshark.html dftest.html randpkt.html # # Build the short version of the authors file for the about dialog @@ -204,6 +205,13 @@ dumpcap.html: dumpcap.pod ../config.h $(top_srcdir)/docbook/ws.css --noindex \ $(srcdir)/dumpcap.pod > dumpcap.html +androiddump.html: androiddump.pod ../config.h $(top_srcdir)/docbook/ws.css + $(AM_V_POD2HTML)$(POD2HTML) \ + --title="androiddump - The Wireshark Network Analyzer $(VERSION)" \ + --css=$(POD_CSS_URL) \ + --noindex \ + $(srcdir)/androiddump.pod > androiddump.html + rawshark.html: rawshark.pod ../config.h $(top_srcdir)/docbook/ws.css $(AM_V_POD2HTML)$(POD2HTML) \ --title="rawshark - The Wireshark Network Analyzer $(VERSION)" \ @@ -262,6 +270,7 @@ EXTRA_DIST = \ README.wmem \ README.wslua \ README.xml-output \ + androiddump.pod \ asn2deb.pod \ capinfos.pod \ captype.pod \ @@ -269,6 +278,7 @@ EXTRA_DIST = \ dftest.pod \ dumpcap.pod \ editcap.pod \ + extcap.pod \ eproto2sgml \ idl2deb.pod \ idl2wrs.pod \ diff --git a/doc/Makefile.nmake b/doc/Makefile.nmake index 9978088d2c..dfe2710cf4 100644 --- a/doc/Makefile.nmake +++ b/doc/Makefile.nmake @@ -26,13 +26,13 @@ include ../config.nmake doc: wireshark.html tshark.html wireshark-filter.html capinfos.html \ editcap.html idl2wrs.html mergecap.html reordercap.html \ - text2pcap.html dumpcap.html rawshark.html dftest.html randpkt.html \ - idl2deb.html asn2deb.html + text2pcap.html dumpcap.html androiddump.html rawshark.html dftest.html randpkt.html \ + idl2deb.html asn2deb.html extcap.html man: wireshark.1 tshark.1 wireshark-filter.4 capinfos.1 \ editcap.1 idl2wrs.1 mergecap.1 reordercap.1 \ - text2pcap.1 dumpcap.1 rawshark.1 dftest.1 randpkt.1 \ - idl2deb.1 asn2deb.1 + text2pcap.1 dumpcap.1 androiddump.1 rawshark.1 dftest.1 randpkt.1 \ + idl2deb.1 asn2deb.1 extcap.4 wireshark.pod: wireshark.pod.template AUTHORS-SHORT-FORMAT copy /B wireshark.pod.template + AUTHORS-SHORT-FORMAT wireshark.pod @@ -209,6 +209,32 @@ dumpcap.html: dumpcap.pod ../config.h ws.css --noindex \ dumpcap.pod > dumpcap.html +extcap.4: extcap.pod ../config.h + $(POD2MAN) \ + --center="The Wireshark Network Analyzer" \ + --release=$(VERSION) \ + extcap.pod > extcap.1 + +extcap.html: extcap.pod ../config.h ws.css + $(POD2HTML) \ + --title="extcap - The Wireshark Network Analyzer $(VERSION)" \ + --css=ws.css \ + --noindex \ + extcap.pod > extcap.html + +androiddump.1: androiddump.pod ../config.h + $(POD2MAN) \ + --center="The Wireshark Network Analyzer" \ + --release=$(VERSION) \ + androiddump.pod > androiddump.1 + +androiddump.html: androiddump.pod ../config.h ws.css + $(POD2HTML) \ + --title="androiddump - The Wireshark Network Analyzer $(VERSION)" \ + --css=ws.css \ + --noindex \ + androiddump.pod > androiddump.html + rawshark.1: rawshark.pod ../config.h $(POD2MAN) \ --center="The Wireshark Network Analyzer" \ diff --git a/doc/androiddump.pod b/doc/androiddump.pod new file mode 100644 index 0000000000..c0788bb465 --- /dev/null +++ b/doc/androiddump.pod @@ -0,0 +1,221 @@ + +=head1 NAME + +androiddump - Provide interfaces to capture from Android devices + +=head1 SYNOPSIS + +B +S<[ B<--help> ]> +S<[ B<--version> ]> +S<[ B<--extcap-interfaces> ]> +S<[ B<--extcap-dlts> ]> +S<[ B<--extcap-interface>=EinterfaceE ]> +S<[ B<--extcap-config> ]> +S<[ B<--capture> ]> +S<[ B<--fifo>=Epath to file or pipeE ]> +S<[ B<--adb-server-ip>=EIP addressE ]> +S<[ B<--adb-server-tcp-port>=ETCP portE ]> +S<[ B<--logcat-text>=ETRUE or FALSEE ]> +S<[ B<--bt-server-tcp-port>=ETCP portE ]> +S<[ B<--bt-forward-socket>=ETRUE or FALSEE ]> +S<[ B<--bt-local-ip>=EIP addressE ]> +S<[ B<--bt-local-tcp-port>=ETCP portE ]> + +B +S< B<--extcap-interfaces> > +S<[ B<--adb-server-ip>=EIP addressE ]> +S<[ B<--adb-server-tcp-port>=ETCP portE ]> + +B +S< B<--extcap-interface>=EinterfaceE > +S<[ B<--extcap-dlts> ]> + +B +S< B<--extcap-interface>=EinterfaceE > +S<[ B<--extcap-config> ]> + +B +S< B<--extcap-interface>=EinterfaceE > +S< B<--fifo>=Epath to file or pipeE > +S< B<--capture> > + +=head1 DESCRIPTION + +B is a extcap tool that provide interfaces to capture from +Android device. There is only two requirements: + +1. You must have Android SDK and add it PATH environment variable. +PATH should contain directory with tools like "adb" and "android". +Android SDK for various platform are available on: +https://developer.android.com/sdk/index.html#Other + +2. You must have permission to Android devices. + + +Supported interfaces: + +=over 4 + +=item 1. Logcat Main (binary or text) + +=item 2. Logcat System (binary or text) + +=item 3. Logcat Events (binary or text) + +=item 4. Logcat Radio (binary or text) + +=item 5. Logcat Crash (text; Lollipop) + +=item 6. Bluetooth Hcidump (interfaceE + +Use specified interfaces. + +=item --extcap-dlts + +List DLTs of specified interface. + +=item --extcap-config + +List configuration options of specified interface. + +=item --capture + +Start capturing from specified interface save saved it in place specified by --fifo. + +=item --fifo=Epath to file or pipeE + +Save captured packet to file or send it through pipe. + +=item --adb-server-ip=EIP addressE + +Use other then default (127.0.0.1) ADB daemon's IP address. + +=item --adb-server-tcp-port=ETCP portE + +Use other then default (5037) ADB daemon's TCP port. + +=item --logcat-text=ETRUE or FALSEE + +If TRUE then use text logcat rather then binary. This option has effect only on +Logcat interfaces. This have no effect from Lollipop where is no binary Logcat +available. + +Defaults to FALSE. + +=item --bt-server-tcp-port=ETCP portE + +Use other then default Bluetooth server TCP port on Android side. +On Lollipop defaults is 8872, earlier 4330. + +=item --bt-forward-socket=ETRUE or FALSEE + +If TRUE then socket from Android side is forwarded to host side. + +Defaults to FALSE. + +=item --bt-local-ip=EIP addressE + +Use other then default (127.0.0.1) IP address on host side for forwarded socket. + +=item --bt-local-tcp-port=ETCP portE + +Specify port to be used on host side for forwarded socket. + +=back + +=head1 EXAMPLES + +To see program arguments: + + androiddump --help + +To see program version: + + androiddump --version + +To see interfaces: + + androiddump --extcap-interfaces + + Example output: + interface {display=Android Logcat Main}{value=android-logcat-main-MSM7627A} + interface {display=Android Logcat System}{value=android-logcat-system-MSM7627A} + interface {display=Android Logcat Radio}{value=android-logcat-radio-MSM7627A} + interface {display=Android Logcat Events}{value=android-logcat-events-MSM7627A} + interface {display=Android Bluetooth Hcidump}{value=android-bluetooth-hcidump-MSM7627A} + +To see interface DLTs: + + androiddump --extcap-interface=android-bluetooth-hcidump-MSM7627A --extcap-dlts + + Example output: + dlt {number=99}{name=BluetoothH4}{display=Bluetooth HCI UART transport layer plus pseudo-header} + + +To see interface configuration options: + + androiddump --extcap-interface=android-bluetooth-hcidump-MSM7627A --extcap-dlts + + Example output: + arg {number=0}{call=--adb-server-ip}{display=ADB Server IP Address}{type=string}{default=127.0.0.1} + arg {number=1}{call=--adb-server-tcp-port}{display=ADB Server TCP Port}{type=integer}{range=0,65535}{default=5037} + + +To capture: + + androiddump --extcap-interface=android-bluetooth-hcidump-MSM7627A --fifo=/tmp/bluetooth.pcapng --capture + +NOTE: To stop capturing CTRL+C/kill/terminate application. + +=head1 SEE ALSO + +wireshark(1), tshark(1), dumpcap(1), extcap(4) + +=head1 NOTES + +B is part of the B distribution. The latest version +of B can be found at L. + +HTML versions of the Wireshark project man pages are available at: +L. + +=head1 AUTHORS + + Original Author + -------- ------ + Michal Labedzki + + + Contributors + ------------ + Roland Knall diff --git a/doc/extcap.pod b/doc/extcap.pod index c6cc9bb1bc..d450088165 100644 --- a/doc/extcap.pod +++ b/doc/extcap.pod @@ -3,76 +3,103 @@ extcap - Extcap grammar elements -=head1 SYNOPSIS +=head1 DESCRIPTION -Suggested config grammar elements: -arg (options) argument for CLI calling -number Reference # of argument for other values, display order -call Literal argument to call (--call=...) -display Displayed name -default Default value, in proper form for type -range Range of valid values for UI checking (min,max) in proper form -type Argument type for UI filtering for raw, or UI type for selector: - integer - unsigned - long (may include scientific / special notation) -float -menu (display popup menu in UI) -selector (display selector table, all values as strings) -boolean (display checkbox) -radio (display group of radio buttons with provided values, all values as strings) +Grammar elements: -value (options) Values for argument selection +=over 4 + +=item arg (options) + +argument for CLI calling + +=item number + +Reference # of argument for other values, display order + +=item call + +Literal argument to call (--call=...) + +=item display + +Displayed name + +=item default + +Default value, in proper form for type + +=item range + +Range of valid values for UI checking (min,max) in proper form + +=item type + +Argument type for UI filtering for raw, or UI type for selector: + + integer + unsigned + long (may include scientific / special notation) + float + selector (display selector table, all values as strings) + boolean (display checkbox) + radio (display group of radio buttons with provided values, all values as strings) + +=item value (options) + + Values for argument selection arg Argument # this value applies to -value Passed value -display Displayed value -default Boolean (true if default, all others ignored, ie default=true) -flag (options) external-capture level flags - dedicated Bypass dumpcap & mux for high speed - failure Failure message +=back +=head1 EXAMPLES -Possible grammar example: +Exampl 1: -arg {number=0}{call=channel}{display=Wi-Fi Channel}{type=integer} -arg {number=1}{call=chanflags}{display=Channel Flags}{type=radio} -arg {number=2}{call=interface}{display=Interface}{type=selector} -value {arg=0}{range=1,11} -value {arg=1}{value=ht40p}{display=HT40+} -value {arg=1}{value=ht40m}{display=HT40-} -value {arg=1}{value=ht20}{display=HT20} -value {arg=2}{value=wlan0}{display=wlan0} + arg {number=0}{call=channel}{display=Wi-Fi Channel}{type=integer} + arg {number=1}{call=chanflags}{display=Channel Flags}{type=radio} + arg {number=2}{call=interface}{display=Interface}{type=selector} + value {arg=0}{range=1,11} + value {arg=1}{value=ht40p}{display=HT40+} + value {arg=1}{value=ht40m}{display=HT40-} + value {arg=1}{value=ht20}{display=HT20} + value {arg=2}{value=wlan0}{display=wlan0} -Example 2 -arg {number=0}{call=usbdevice}{USB Device}{type=selector} -value {arg=0}{call=/dev/sysfs/usb/foo/123}{display=Ubertooth One sn 1234} -value {arg=0}{call=”/dev/sysfs/usb/foo/456}{display=Ubertooth One sn 8901} +Example 2: -Example 3 -arg {number=0}{call=usbdevice}{USB Device}{type=selector} -flag {failure=Permission denied opening Ubertooth device} + arg {number=0}{call=usbdevice}{USB Device}{type=selector} + value {arg=0}{call=/dev/sysfs/usb/foo/123}{display=Ubertooth One sn 1234} + value {arg=0}{call=/dev/sysfs/usb/foo/456}{display=Ubertooth One sn 8901} +Example 3: -Security awareness: + arg {number=0}{call=usbdevice}{USB Device}{type=selector} + flag {failure=Permission denied opening Ubertooth device} -- Users running wireshark as root, we can’t save you -- Dumpcap retains suid/setgid and group+x permissions to allow users in wireshark group only -- Third-party capture programs run w/ whatever privs they’re installed with -- If an attacker can write to a system binary directory, we’re game over anyhow -- Don’t let wireshark be told to look for capture binaries somewhere else? +=head1 Security awareness -Notes: -- daemonized dumpcap? -- multiuser? -- sync_pipe.h commands -- expand pipe commands to have status notifications, etc? -- Wireshark->dumpcap options for channel control, etc? +=over 4 -TODO -define grammar -write grammar to HTML mockup -sketch interface with dumpcap -launch external-pcap from wireshark, bypass dumpcap -launch external-pcap from wireshark, hand fd to dumpcap -extract netif capture as first cap source \ No newline at end of file +=item - Users running wireshark as root, we can't save you + +=item - Dumpcap retains suid/setgid and group+x permissions to allow users in wireshark group only + +=item - Third-party capture programs run w/ whatever privs they're installed with + +=item - If an attacker can write to a system binary directory, we're game over anyhow + +=item - Don't let wireshark be told to look for capture binaries somewhere else? + +=back + +=head1 SEE ALSO + +wireshark(1), tshark(1), dumpcap(1), androiddump(1) + +=head1 NOTES + +B is feature of B. The latest version +of B can be found at L. + +HTML versions of the Wireshark project man pages are available at: +L. \ No newline at end of file diff --git a/docbook/release-notes.asciidoc b/docbook/release-notes.asciidoc index 9f257ac139..1baadf664e 100644 --- a/docbook/release-notes.asciidoc +++ b/docbook/release-notes.asciidoc @@ -171,6 +171,12 @@ Wireshark now supports nanosecond timestamp resolution in PCAP-NG files. Colasoft Capsa files --sort-and-group-- +=== New and Updated Capture Interfaces support + +--sort-and-group-- +Androiddump - provide interfaces to capture (Logcat and Bluetooth) from connected Android devices +--sort-and-group-- + === Major API Changes The libwireshark API has undergone some major changes: diff --git a/extcap/androiddump.c b/extcap/androiddump.c index 4922853e58..e2396b4920 100644 --- a/extcap/androiddump.c +++ b/extcap/androiddump.c @@ -62,11 +62,17 @@ #ifdef HAVE_WINSOCK2_H #include #endif + + #include + + #define socket_handle_t SOCKET #else /* * UN*X, or Windows pretending to be UN*X with the aid of Cygwin. */ #define closesocket(socket) close(socket) + #define socket_handle_t int + #define INVALID_SOCKET (-1) #endif /* Configuration options */ @@ -313,8 +319,8 @@ static void extcap_dumper_dump(struct extcap_dumper extcap_dumper, char *buffer, } -static int adb_connect(const char *server_ip, unsigned short *server_tcp_port) { - int sock; +static socket_handle_t adb_connect(const char *server_ip, unsigned short *server_tcp_port) { + socket_handle_t sock; socklen_t length; struct sockaddr_in server; @@ -322,20 +328,25 @@ static int adb_connect(const char *server_ip, unsigned short *server_tcp_port) { server.sin_port = GINT16_TO_BE(*server_tcp_port); server.sin_addr.s_addr = inet_addr(server_ip); - if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) { fprintf(stderr, "ERROR: Cannot open system TCP socket: %s\n", strerror(errno)); - return -1; + return INVALID_SOCKET; } if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) { - if (system("adb start-server") == -1) { +#ifdef _WIN32 + if (_execlp("adb", "adb", "start-server", NULL)) { +#else + if (execlp("adb", "adb", "start-server", NULL)) { +#endif fprintf(stderr, "WARNING: Cannot execute system command to start adb: %s\n", strerror(errno)); + return INVALID_SOCKET; }; if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) { fprintf(stderr, "ERROR: Cannot connect to ADB: %s\n", strerror(errno)); fprintf(stderr, "INFO: Please check that adb daemon is running.\n"); - return -2; + return INVALID_SOCKET; } } @@ -345,12 +356,12 @@ static int adb_connect(const char *server_ip, unsigned short *server_tcp_port) { length = sizeof(client); if (getsockname(sock, (struct sockaddr *) &client, &length)) { fprintf(stderr, "ERROR getsockname: %s\n", strerror(errno)); - return -3; + return INVALID_SOCKET; } if (length != sizeof(client)) { fprintf(stderr, "ERROR: incorrect length\n"); - return -4; + return INVALID_SOCKET; } fprintf(stderr, "VERBOSE: Client port %u\n", GINT16_FROM_BE(client.sin_port)); @@ -360,14 +371,14 @@ static int adb_connect(const char *server_ip, unsigned short *server_tcp_port) { } -static char *adb_send_and_receive(int sock, const char *adb_service, +static char *adb_send_and_receive(socket_handle_t sock, const char *adb_service, char *buffer, int buffer_length, ssize_t *data_length) { ssize_t used_buffer_length; ssize_t length; ssize_t result; char status[4]; - result = send(sock, adb_service, strlen(adb_service), 0); + result = send(sock, adb_service, (int)strlen(adb_service), 0); if (result != (ssize_t) strlen(adb_service)) { fprintf(stderr, "ERROR: Error while sending <%s> to ADB\n", adb_service); if (data_length) @@ -404,13 +415,13 @@ static char *adb_send_and_receive(int sock, const char *adb_service, } -static char *adb_send_and_read(int sock, const char *adb_service, char *buffer, +static char *adb_send_and_read(socket_handle_t sock, const char *adb_service, char *buffer, int buffer_length, ssize_t *data_length) { ssize_t used_buffer_length; ssize_t result; char status[4]; - result = send(sock, adb_service, strlen(adb_service), 0); + result = send(sock, adb_service, (int)strlen(adb_service), 0); if (result != (ssize_t) strlen(adb_service)) { fprintf(stderr, "ERROR: Error while sending <%s> to ADB\n", adb_service); if (data_length) @@ -445,12 +456,12 @@ static char *adb_send_and_read(int sock, const char *adb_service, char *buffer, } -static int adb_send(int sock, const char *adb_service) { +static int adb_send(socket_handle_t sock, const char *adb_service) { char buffer[4]; ssize_t used_buffer_length; ssize_t result; - result = send(sock, adb_service, strlen(adb_service), 0); + result = send(sock, adb_service, (int)strlen(adb_service), 0); if (result != (ssize_t) strlen(adb_service)) { fprintf(stderr, "ERROR: Error while sending <%s> to ADB\n", adb_service); return 1; @@ -479,7 +490,7 @@ static int add_android_interfaces(struct interface_t **interface_list, char *device_list; ssize_t data_length; ssize_t device_length; - int sock; + socket_handle_t sock; const char *adb_transport_serial_templace = "%04x""host:transport:%s"; const char *adb_check_port_templace = "%04x""shell:cat /proc/%s/net/tcp"; const char *adb_devices = "000C""host:devices"; @@ -501,7 +512,7 @@ static int add_android_interfaces(struct interface_t **interface_list, i_interface_list = *interface_list; sock = adb_connect(adb_server_ip, adb_server_tcp_port); - if (sock < 0) + if (sock == INVALID_SOCKET) return -1; device_list = adb_send_and_receive(sock, adb_devices, packet, sizeof(packet), &device_length); @@ -928,7 +939,7 @@ static void help(void) { printf("Help\n"); printf(" Usage:\n" - " androiddump --extcap-interfaces [--server-ip=] [--server-tcp-port=]\n" + " androiddump --extcap-interfaces [--adb-server-ip=] [--adb-server-tcp-port=]\n" " androiddump --extcap-interface=INTERFACE --extcap-dlts\n" " androiddump --extcap-interface=INTERFACE --extcap-config\n" " androiddump --extcap-interface=INTERFACE --fifo=PATH_FILENAME --capture \n"); @@ -955,7 +966,7 @@ static int capture_android_bluetooth_hcidump(char *interface, char *fifo, static char helpful_packet[PACKET_LENGTH]; ssize_t length; ssize_t used_buffer_length = 0; - int sock; + 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_hcidump = "0013""shell:hcidump -R -t"; @@ -980,7 +991,7 @@ static int capture_android_bluetooth_hcidump(char *interface, char *fifo, extcap_dumper = extcap_dumper_open(fifo, EXTCAP_ENCAP_BLUETOOTH_H4_WITH_PHDR); sock = adb_connect(adb_server_ip, adb_server_tcp_port); - if (sock < 0) + if (sock == INVALID_SOCKET) return -1; if (is_specified_interface(interface, INTERFACE_ANDROID_BLUETOOTH_HCIDUMP) && @@ -1040,7 +1051,7 @@ static int capture_android_bluetooth_hcidump(char *interface, char *fifo, break; } memmove(data, i_position, used_buffer_length - (i_position - data)); - used_buffer_length = used_buffer_length - (i_position - data); + used_buffer_length = used_buffer_length - (ssize_t)(i_position - data); break; } } @@ -1048,7 +1059,7 @@ static int capture_android_bluetooth_hcidump(char *interface, char *fifo, if (try_next == 1) { sock = adb_connect(adb_server_ip, adb_server_tcp_port); - if (sock < 0) + if (sock == INVALID_SOCKET) return -1; sprintf((char *) helpful_packet, adb_transport_serial_templace, 15 + strlen(serial_number), serial_number); @@ -1088,7 +1099,7 @@ static int capture_android_bluetooth_hcidump(char *interface, char *fifo, if (i_position) { i_position += 1; memmove(data, i_position, used_buffer_length - (i_position - data)); - used_buffer_length = used_buffer_length - (i_position - data); + used_buffer_length = used_buffer_length - (ssize_t)(i_position - data); break; } } @@ -1231,13 +1242,13 @@ static const uint64_t BLUEDROID_TIMESTAMP_BASE = G_GUINT64_CONSTANT(0x00dcddb30f 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) { - int sock; + socket_handle_t sock; 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); - if (sock < 0) + if (sock == INVALID_SOCKET) return -1; 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); @@ -1263,7 +1274,7 @@ static int capture_android_bluetooth_external_parser(char *interface, ssize_t length; ssize_t used_buffer_length = 0; uint64_t ts; - int sock; + socket_handle_t sock; struct sockaddr_in server; int captured_length; char *serial_number = NULL; @@ -1279,7 +1290,7 @@ static int capture_android_bluetooth_external_parser(char *interface, } if (bt_forward_socket) { - if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) { printf("ERROR: Cannot open system TCP socket: %s\n", strerror(errno)); return 1; } @@ -1327,7 +1338,7 @@ static int capture_android_bluetooth_external_parser(char *interface, int result; sock = adb_connect(adb_server_ip, adb_server_tcp_port); - if (sock < 0) + if (sock == INVALID_SOCKET) return -1; if (!serial_number) { @@ -1368,7 +1379,7 @@ static int capture_android_bluetooth_external_parser(char *interface, printf("WARNING: Broken socket connection. Try reconnect.\n"); closesocket(sock); - if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) { printf("ERROR1: %s\n", strerror(errno)); return 1; } @@ -1474,7 +1485,7 @@ static int capture_android_bluetooth_btsnoop_net(char *interface, char *fifo, static char packet[PACKET_LENGTH]; ssize_t length; ssize_t used_buffer_length = 0; - int sock; + 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_tcp_btsnoop_net = "0008""tcp:8872"; @@ -1500,7 +1511,7 @@ static int capture_android_bluetooth_btsnoop_net(char *interface, char *fifo, extcap_dumper = extcap_dumper_open(fifo, EXTCAP_ENCAP_BLUETOOTH_H4_WITH_PHDR); sock = adb_connect(adb_server_ip, adb_server_tcp_port); - if (sock < 0) + if (sock == INVALID_SOCKET) return -1; if (is_specified_interface(interface, INTERFACE_ANDROID_BLUETOOTH_BTSNOOP_NET) && @@ -1596,8 +1607,8 @@ static int capture_android_logcat_text(char *interface, char *fifo, struct extcap_dumper extcap_dumper; static char packet[PACKET_LENGTH]; ssize_t length; - ssize_t used_buffer_length = 0; - int sock; + size_t used_buffer_length = 0; + socket_handle_t sock; const char *protocol_name; size_t exported_pdu_headers_size = 0; struct exported_pdu_header exported_pdu_header_protocol_normal; @@ -1618,7 +1629,7 @@ static int capture_android_logcat_text(char *interface, char *fifo, exported_pdu_header_protocol_normal.length = GINT16_TO_BE(strlen(wireshark_protocol_logcat_text) + 2); sock = adb_connect(adb_server_ip, adb_server_tcp_port); - if (sock < 0) + if (sock == INVALID_SOCKET) return -1; if (is_specified_interface(interface, INTERFACE_ANDROID_LOGCAT_MAIN) && strlen(interface) > strlen(INTERFACE_ANDROID_LOGCAT_MAIN) + 1) { @@ -1697,7 +1708,7 @@ static int capture_android_logcat_text(char *interface, char *fifo, used_buffer_length = 0; while (endless_loop) { errno = 0; - length = recv(sock, packet + exported_pdu_headers_size + used_buffer_length, PACKET_LENGTH - exported_pdu_headers_size - used_buffer_length , 0); + length = recv(sock, packet + exported_pdu_headers_size + used_buffer_length, (int)(PACKET_LENGTH - exported_pdu_headers_size - used_buffer_length), 0); if (errno == EAGAIN || errno == EWOULDBLOCK) continue; else if (errno != 0) { printf("ERROR capture: %s\n", strerror(errno)); @@ -1718,7 +1729,7 @@ static int capture_android_logcat_text(char *interface, char *fifo, time_t secs = 0; int nsecs = 0; - length = (pos - packet) + 1; + length = (ssize_t)(pos - packet) + 1; 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)) { @@ -1753,7 +1764,7 @@ static int capture_android_logcat(char *interface, char *fifo, static char helper_packet[PACKET_LENGTH]; ssize_t length; size_t used_buffer_length = 0; - int sock; + socket_handle_t sock; const char *protocol_name; size_t exported_pdu_headers_size = 0; struct exported_pdu_header exported_pdu_header_protocol_events; @@ -1786,7 +1797,7 @@ static int capture_android_logcat(char *interface, char *fifo, exported_pdu_header_protocol_normal.length = GINT16_TO_BE(strlen(wireshark_protocol_logcat) + 2); sock = adb_connect(adb_server_ip, adb_server_tcp_port); - if (sock < 0) + if (sock == INVALID_SOCKET) return -1; if (is_specified_interface(interface, INTERFACE_ANDROID_LOGCAT_MAIN) && strlen(interface) > strlen(INTERFACE_ANDROID_LOGCAT_MAIN) + 1) { @@ -1861,7 +1872,7 @@ static int capture_android_logcat(char *interface, char *fifo, while (endless_loop) { errno = 0; - length = recv(sock, packet + exported_pdu_headers_size + used_buffer_length, PACKET_LENGTH - exported_pdu_headers_size - used_buffer_length , 0); + length = recv(sock, packet + exported_pdu_headers_size + used_buffer_length, (int)(PACKET_LENGTH - exported_pdu_headers_size - used_buffer_length), 0); if (errno == EAGAIN || errno == EWOULDBLOCK) continue; else if (errno != 0) { printf("ERROR capture: %s\n", strerror(errno)); @@ -1875,7 +1886,7 @@ static int capture_android_logcat(char *interface, char *fifo, closesocket(sock); sock = adb_connect(adb_server_ip, adb_server_tcp_port); - if (sock < 0) + if (sock == INVALID_SOCKET) return -1; if (!serial_number) { @@ -1923,7 +1934,7 @@ static int capture_android_logcat(char *interface, char *fifo, else header_size = *try_header_size; - length = (*payload_length) + header_size + exported_pdu_headers_size; + length = (*payload_length) + header_size + (ssize_t)exported_pdu_headers_size; while (used_buffer_length >= exported_pdu_headers_size + header_size && (size_t)length <= used_buffer_length) { extcap_dumper_dump(extcap_dumper, packet, @@ -1936,7 +1947,7 @@ static int capture_android_logcat(char *interface, char *fifo, used_buffer_length += exported_pdu_headers_size; - length = (*payload_length) + header_size + exported_pdu_headers_size; + length = (*payload_length) + header_size + (ssize_t)exported_pdu_headers_size; if (*try_header_size == 0 || *try_header_size != 24) header_size = 20; @@ -1951,6 +1962,49 @@ static int capture_android_logcat(char *interface, char *fifo, /*============================================================================*/ +#ifdef _WIN32 +BOOLEAN IsHandleRedirected(DWORD handle) +{ + HANDLE h = GetStdHandle(handle); + if (h) { + BY_HANDLE_FILE_INFORMATION fi; + if (GetFileInformationByHandle(h, &fi)) { + return TRUE; + } + } + return FALSE; +} + +static void attach_parent_console() +{ + BOOL outRedirected, errRedirected; + + outRedirected = IsHandleRedirected(STD_OUTPUT_HANDLE); + errRedirected = IsHandleRedirected(STD_ERROR_HANDLE); + + if (outRedirected && errRedirected) { + /* Both standard output and error handles are redirected. + * There is no point in attaching to parent process console. + */ + return; + } + + if (AttachConsole(ATTACH_PARENT_PROCESS) == 0) { + /* Console attach failed. */ + return; + } + + /* Console attach succeeded */ + if (outRedirected == FALSE) { + freopen("CONOUT$", "w", stdout); + } + + if (errRedirected == FALSE) { + freopen("CONOUT$", "w", stderr); + } +} +#endif + int main(int argc, char **argv) { int option_idx = 0; int do_capture = 0; @@ -1977,6 +2031,8 @@ int main(int argc, char **argv) { unsigned short default_bt_local_tcp_port = 4330; #ifdef _WIN32 WSADATA wsaData; + + attach_parent_console(); #endif /* _WIN32 */ opterr = 0; @@ -2119,6 +2175,13 @@ int main(int argc, char **argv) { return 0; } +#ifdef _WIN32 +int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + LPSTR lpCmdLine, int nCmdShow) { + return main(__argc, __argv); +} +#endif + /* * Editor modelines - http://www.wireshark.org/tools/modelines.html * diff --git a/packaging/macosx/osx-app.sh b/packaging/macosx/osx-app.sh index d8f6975d0d..7636e351af 100755 --- a/packaging/macosx/osx-app.sh +++ b/packaging/macosx/osx-app.sh @@ -50,6 +50,7 @@ ui_toolkit="qt" wireshark_bin_name="wireshark" binary_list=" + extcap/androiddump capinfos dftest dumpcap diff --git a/packaging/nsis/Makefile.nmake b/packaging/nsis/Makefile.nmake index 26443ed74f..ae0f66c7e4 100644 --- a/packaging/nsis/Makefile.nmake +++ b/packaging/nsis/Makefile.nmake @@ -20,9 +20,11 @@ EXE=../../tshark.exe ../../editcap.exe \ ../../text2pcap.exe ../../mergecap.exe ../../capinfos.exe $(WIRESHARK_LIB_DIR)\WinPcap_$(WINPCAP_VERSION).exe DLL=../../wiretap/wiretap-$(WTAP_VERSION).dll ../../wsutil/libwsutil.dll DOC=../../doc/ws.css \ + ../../doc/androiddump.html \ ../../doc/capinfos.html \ ../../doc/dumpcap.html \ ../../doc/editcap.html \ + ../../doc/extcap.html \ ../../doc/mergecap.html \ ../../doc/rawshark.html \ ../../doc/text2pcap.html \ diff --git a/packaging/nsis/uninstall.nsi b/packaging/nsis/uninstall.nsi index 7bb78f42f1..1af6aaa495 100755 --- a/packaging/nsis/uninstall.nsi +++ b/packaging/nsis/uninstall.nsi @@ -97,6 +97,7 @@ SetShellVarContext all !insertmacro IsWiresharkRunning Push "${EXECUTABLE_MARKER}" +Push "androiddump" Push "dumpcap" Push "${PROGRAM_NAME}" Push "tshark" @@ -145,6 +146,8 @@ Delete "$INSTDIR\diameter\*.*" Delete "$INSTDIR\etc\gtk-2.0\*.*" Delete "$INSTDIR\etc\gtk-3.0\*.*" Delete "$INSTDIR\etc\pango\*.*" +Delete "$INSTDIR\extcap\androiddump.*" +Delete "$INSTDIR\extcap\*.dll" Delete "$INSTDIR\help\*.*" Delete "$INSTDIR\iconengines\*.*" Delete "$INSTDIR\imageformats\*.*" @@ -202,6 +205,7 @@ RMDir "$INSTDIR\accessible" RMDir "$INSTDIR\etc\gtk-2.0" RMDir "$INSTDIR\etc\pango" RMDir "$INSTDIR\etc" +RMDir "$INSTDIR\extcap" RMDir "$INSTDIR\iconengines" RMDir "$INSTDIR\imageformats" RMDir "$INSTDIR\lib\gtk-2.0\2.2.0\engines" diff --git a/packaging/nsis/wireshark.nsi b/packaging/nsis/wireshark.nsi index 69d67af095..a0071b01af 100644 --- a/packaging/nsis/wireshark.nsi +++ b/packaging/nsis/wireshark.nsi @@ -341,6 +341,7 @@ File "${STAGING_DIR}\wireshark.html" File "${STAGING_DIR}\wireshark-filter.html" File "${STAGING_DIR}\dumpcap.exe" File "${STAGING_DIR}\dumpcap.html" +File "${STAGING_DIR}\extcap.html" File "${STAGING_DIR}\ipmap.html" ; C-runtime redistributable @@ -977,6 +978,14 @@ File "${STAGING_DIR}\capinfos.exe" File "${STAGING_DIR}\capinfos.html" SectionEnd +Section "Androiddump" SecAndroiddumpinfos +;------------------------------------------- +SetOutPath $INSTDIR\extcap +File "${STAGING_DIR}\androiddump.html" +File "${STAGING_DIR}\extcap\androiddump.exe" +File "${STAGING_DIR}\extcap\*.dll" +SectionEnd + Section "Rawshark" SecRawshark ;------------------------------------------- SetOutPath $INSTDIR @@ -1029,6 +1038,7 @@ SectionEnd !endif !insertmacro MUI_DESCRIPTION_TEXT ${SecToolsGroup} "Additional command line based tools." + !insertmacro MUI_DESCRIPTION_TEXT ${SecAndroiddumpinfos} "Provide capture interfaces from Android devices" !insertmacro MUI_DESCRIPTION_TEXT ${SecEditCap} "Copy packets to a new file, optionally trimmming packets, omitting them, or saving to a different format." !insertmacro MUI_DESCRIPTION_TEXT ${SecText2Pcap} "Read an ASCII hex dump and write the data into a libpcap-style capture file." !insertmacro MUI_DESCRIPTION_TEXT ${SecMergecap} "Combine multiple saved capture files into a single output file" diff --git a/packaging/portableapps/Makefile.nmake b/packaging/portableapps/Makefile.nmake index 24afbbdb76..f5add0b0d3 100644 --- a/packaging/portableapps/Makefile.nmake +++ b/packaging/portableapps/Makefile.nmake @@ -98,6 +98,7 @@ applauncher: appinfo appbinaries: applauncher xcopy $(TOPDIR)\wireshark-qt-release $(WIRESHARK_DIR) /D /I /E /Y + xcopy $(TOPDIR)\extcap\androiddump.exe $(WIRESHARK_DIR)\extcap /d xcopy $(TOPDIR)\capinfos.exe $(WIRESHARK_DIR) /d xcopy $(TOPDIR)\captype.exe $(WIRESHARK_DIR) /d xcopy $(TOPDIR)\dumpcap.exe $(WIRESHARK_DIR) /d