From 3e8a964f0f28e0041fc9565824f1e6595a658efe Mon Sep 17 00:00:00 2001 From: wji Date: Tue, 2 Jul 2024 12:06:03 +0800 Subject: [PATCH] Netkvm: use WinDump for capture and Wireshark for analysis Replace tshark.exe with WinDump.exe for capturing network traffic. This resolves the issue where enabling netkvm driver TxLSO results in no packet length >= 1514 after file transfer, identified as a Wireshark problem. Signed-off-by: wji --- qemu/tests/cfg/enable_scatter_windows.cfg | 17 ++-- qemu/tests/enable_scatter_windows.py | 117 ++++++++++++---------- 2 files changed, 77 insertions(+), 57 deletions(-) diff --git a/qemu/tests/cfg/enable_scatter_windows.cfg b/qemu/tests/cfg/enable_scatter_windows.cfg index d14236bde8..140f597d98 100644 --- a/qemu/tests/cfg/enable_scatter_windows.cfg +++ b/qemu/tests/cfg/enable_scatter_windows.cfg @@ -10,13 +10,17 @@ driver_verifier = netkvm Win2016, Win2019, Win8..1, Win2012..r2: driver_verifier += " ndis" - installed_path = "C:\Program Files\Wireshark\tshark.exe" - check_installed_cmd = 'dir "${installed_path}"|findstr /I tshark.exe' + windump_name = "WinDump.exe" + windump_installed_path = "C:\${windump_name}" + check_windump_installed_cmd = 'dir "${windump_installed_path}"' + windump_install_cmd = "xcopy WIN_UTILS:\${windump_name} c:\ /y" x86_64: wireshark_name = "Wireshark-win64-1.10.1.exe" i386, i686: wireshark_name = "Wireshark-win32-1.10.1.exe" - install_wireshark_cmd = "xcopy WIN_UTILS:\${wireshark_name} c:\ /y && c:\${wireshark_name} /S" + tshark_installed_path = "C:\Program Files\Wireshark\tshark.exe" + check_tshark_installed_cmd = 'dir "${tshark_installed_path}" | findstr /I tshark.exe' + tshark_install_cmd = "xcopy WIN_UTILS:\${wireshark_name} c:\ /y && c:\${wireshark_name} /S" autoit_name = "AutoIt3_%PROCESSOR_ARCHITECTURE%.exe" install_winpcap_cmd = "WIN_UTILS:\${autoit_name} WIN_UTILS:\install_winpcap.au3" @@ -27,6 +31,7 @@ query_version_cmd += "where (DeviceName like 'Red Hat VirtIO Ethernet Adapter') " query_version_cmd += "get DriverVersion /format:list" - run_wireshark_temp = 'start "" "${installed_path}" -n -w c:\temp.pcapng tcp and dst %s and src %s' - stop_wireshark_cmd = "taskkill /im tshark.exe /f" - parse_log_temp = '"${installed_path}" -2 -r c:\temp.pcapng -R "%s"' + pcap_file = c:\temp.pcap + run_windump_temp = 'start "" "${windump_installed_path}" -n -w "${pcap_file}" tcp and dst %s and src %s' + stop_windump_cmd = "taskkill /im ${windump_name} /f" + parse_log_temp = '"${tshark_installed_path}" -2 -r "${pcap_file}" -R "%s"' diff --git a/qemu/tests/enable_scatter_windows.py b/qemu/tests/enable_scatter_windows.py index 4794070169..f0726e6929 100644 --- a/qemu/tests/enable_scatter_windows.py +++ b/qemu/tests/enable_scatter_windows.py @@ -13,8 +13,8 @@ def run(test, params, env): 1) start vm 2) check and install wireshark and winpcap 3) enable netkvm driver TxLSO - 4) start file transfer and use wireshark to log traffic, - some packets length should over 1514 + 4) start File Transfer and use WinDump to log traffic and Wireshark + for analysis, some packets should be over 1514 in length. 5) disable TxLSO and set MTU to 1000 6) start file transfer and log file transfer traffic again, no packet length should over 1014 @@ -39,41 +39,45 @@ def _is_process_finished(session, process_name): return False return process_name not in output - def _start_wireshark_session(): + def _start_windump_session(): """ - Start a wireshark session and log network traffic to a file + Start a WinDump session and log network traffic to a file """ - error_context.context("Start wireshark session", test.log.info) + error_context.context("Start WinDump session", test.log.info) session_serial = vm.wait_for_serial_login(timeout=timeout) guest_ip = vm.get_address() try: - run_wireshark_cmd = run_wireshark_temp % (host_ip, guest_ip) + run_windump_cmd = run_windump_temp % (host_ip, guest_ip) status, output = session_serial.cmd_status_output( - run_wireshark_cmd, timeout=timeout + run_windump_cmd, timeout=timeout ) - if status: test.error( - "Failed to start wireshark session, " - "status=%s, output=%s" % (status, output) + "Failed to start WinDump session, status=%s, output=%s" + % (status, output) ) is_started = utils_misc.wait_for( - lambda: not _is_process_finished(session_serial, "tshark.exe"), 20, 5, 1 + lambda: not _is_process_finished( + session_serial, params.get("windump_name") + ), + 20, + 5, + 1, ) if not is_started: - test.error("Timeout when wait for wireshark start") + test.error("Timeout when waiting for WinDump to start") finally: session_serial.close() - def _stop_wireshark_session(): + def _stop_windump_session(): """ - Stop the running wireshark session + Stop the running WinDump session """ - error_context.context("Stop wireshark", test.log.info) - status, output = session.cmd_status_output(stop_wireshark_cmd, timeout=timeout) + error_context.context("Stop WinDump", test.log.info) + status, output = session.cmd_status_output(stop_windump_cmd, timeout=timeout) if status: test.error( - "Failed to stop wireshark: status=%s, output=%s" % (status, output) + "Failed to stop WinDump: status=%s, output=%s" % (status, output) ) def _parse_log_file(packet_filter): @@ -83,29 +87,29 @@ def _parse_log_file(packet_filter): param packet_filter: the filter to apply when dump packets return: the output of the parse result """ - error_context.context("Parse wireshark log file", test.log.info) + error_context.context("Parse captured packets using Wireshark", test.log.info) parse_log_cmd = parse_log_temp % packet_filter status, output = session.cmd_status_output(parse_log_cmd, timeout=timeout) - if status: + if status != 0: test.error( - "Failed to parse session log file," - " status=%s, output=%s" % (status, output) + "Failed to parse session log file, status=%s, output=%s" + % (status, output) ) return output def _get_traffic_log(packet_filter): """ - Use wireshark to log the file transfer network traffic, - and return the packets dump output. + Use WinDump to capture the file transfer network traffic, + and return the packet analysis output. - param packet_filter: the filter to apply when dump packets - return: the output of the parse result + :param packet_filter: The filter to apply when analyzing packets + :return: The output of the parse result """ - _start_wireshark_session() + _start_windump_session() error_context.context("Start file transfer", test.log.info) utils_test.run_file_transfer(test, params, env) time.sleep(30) - _stop_wireshark_session() + _stop_windump_session() return _parse_log_file(packet_filter) def _set_driver_param(index): @@ -129,11 +133,11 @@ def _get_driver_version(session): version = version_str.split(".")[-1][0:3] return int(version) - timeout = params.get("timeout", 360) + timeout = int(params.get("timeout", 360)) driver_verifier = params["driver_verifier"] - wireshark_name = params.get("wireshark_name") - run_wireshark_temp = params.get("run_wireshark_temp") - stop_wireshark_cmd = params.get("stop_wireshark_cmd") + autoit_name = params.get("autoit_name") + run_windump_temp = params.get("run_windump_temp") + stop_windump_cmd = params.get("stop_windump_cmd") check_proc_temp = params.get("check_proc_temp") parse_log_temp = params.get("parse_log_temp") param_names = params.get("param_names").split() @@ -172,28 +176,39 @@ def _get_driver_version(session): lambda: _is_process_finished(session, autoit_name), timeout, 20, 3 ) - error_context.context("Check if wireshark is installed", test.log.info) - check_installed_cmd = params.get("check_installed_cmd") - check_result = session.cmd_output(check_installed_cmd) - if "tshark" not in check_result: - error_context.context("Install wireshark", test.log.info) - install_wireshark_cmd = params.get("install_wireshark_cmd") - install_wireshark_cmd = utils_misc.set_winutils_letter( - session, install_wireshark_cmd + for process_name in ["windump", "tshark"]: + check_cmd = params["check_%s_installed_cmd" % process_name] + install_cmd = utils_misc.set_winutils_letter( + session, params["%s_install_cmd" % process_name] ) - status, output = session.cmd_status_output( - install_wireshark_cmd, timeout=timeout - ) - if status: - test.error( - "Failed to install wireshark, status=%s, output=%s" % (status, output) + + is_installed = process_name in session.cmd_output(check_cmd) + + if not is_installed: + error_context.context("Install %s" % process_name, test.log.info) + status, output = session.cmd_status_output(install_cmd, timeout=timeout) + if status != 0: + test.error( + "Failed to install %s, status=%s, output=%s" + % (process_name, status, output) + ) + + error_context.context( + "Wait for %s installation to complete" % process_name, test.log.info ) - test.log.info("Wait for wireshark installation to complete") - utils_misc.wait_for( - lambda: _is_process_finished(session, wireshark_name), timeout, 20, 3 - ) - else: - test.log.info("Wireshark is already installed") + utils_misc.wait_for( + lambda: _is_process_finished(session, process_name), + timeout, + 20, + 3, + ) + check_result = session.cmd_output(check_cmd).lower() + if process_name not in check_result: + test.error("%s installation failed to verify." % process_name) + test.log.info("%s installed successfully.", process_name) + else: + test.log.info("%s is already installed", process_name) + session.close() virtio_win.prepare_netkvmco(vm)