clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name wireshark_main_window_slots.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-17/lib/clang/17 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/build/ui/qt -isystem /builds/wireshark/wireshark/ui/qt -isystem /usr/include/x86_64-linux-gnu/qt6/QtWidgets -isystem /usr/include/x86_64-linux-gnu/qt6 -isystem /usr/include/x86_64-linux-gnu/qt6/QtCore -isystem /usr/lib/x86_64-linux-gnu/qt6/mkspecs/linux-g++ -isystem /usr/include/x86_64-linux-gnu/qt6/QtGui -isystem /usr/include/x86_64-linux-gnu/qt6/QtCore5Compat -isystem /usr/include/x86_64-linux-gnu/qt6/QtConcurrent -isystem /usr/include/x86_64-linux-gnu/qt6/QtPrintSupport -isystem /usr/include/x86_64-linux-gnu/qt6/QtMultimedia -isystem /usr/include/x86_64-linux-gnu/qt6/QtNetwork -isystem /usr/include/x86_64-linux-gnu/qt6/QtDBus -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D QT_CONCURRENT_LIB -D QT_CORE5COMPAT_LIB -D QT_CORE_LIB -D QT_DBUS_LIB -D QT_GUI_LIB -D QT_MULTIMEDIA_LIB -D QT_NETWORK_LIB -D QT_PRINTSUPPORT_LIB -D QT_WIDGETS_LIB -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build/ui/qt/qtui_autogen/include -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/11/../../../../include/x86_64-linux-gnu/c++/11 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/backward -internal-isystem /usr/lib/llvm-17/lib/clang/17/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/11/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-error=stringop-overflow= -Wno-error=deprecated-declarations -Wno-format-truncation -std=c++17 -fdeprecated-macro -fdebug-compilation-dir=/builds/wireshark/wireshark/build -ferror-limit 19 -fwrapv -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2024-06-29-100233-3154-1 -x c++ /builds/wireshark/wireshark/ui/qt/wireshark_main_window_slots.cpp
1 | /* main_window_slots.cpp |
2 | * |
3 | * Wireshark - Network traffic analyzer |
4 | * By Gerald Combs <[emailprotected]> |
5 | * Copyright 1998 Gerald Combs |
6 | * |
7 | * SPDX-License-Identifier: GPL-2.0-or-later |
8 | */ |
9 | |
10 | #include <config.h> |
11 | |
12 | // Qt 5.5.0 + Visual C++ 2013 |
13 | #ifdef _MSC_VER |
14 | #pragma warning(push) |
15 | #pragma warning(disable:4996) |
16 | #endif |
17 | |
18 | #include "wireshark_main_window.h" |
19 | |
20 | /* |
21 | * The generated Ui_WiresharkMainWindow::setupUi() can grow larger than our configured limit, |
22 | * so turn off -Wframe-larger-than= for ui_main_window.h. |
23 | */ |
24 | DIAG_OFF(frame-larger-than=)clang diagnostic push clang diagnostic ignored "-Wframe-larger-than="
|
25 | #include <ui_wireshark_main_window.h> |
26 | DIAG_ON(frame-larger-than=)clang diagnostic pop |
27 | |
28 | #ifdef _WIN32 |
29 | #include <windows.h> |
30 | #endif |
31 | |
32 | #include "ui/dissect_opts.h" |
33 | |
34 | #ifdef HAVE_LIBPCAP1 |
35 | #include "ui/capture.h" |
36 | #endif |
37 | |
38 | #include "ui/commandline.h" |
39 | |
40 | #include "ui/urls.h" |
41 | |
42 | #include "epan/color_filters.h" |
43 | #include "epan/export_object.h" |
44 | |
45 | #include "wsutil/file_util.h" |
46 | #include "wsutil/filesystem.h" |
47 | #include <wsutil/wslog.h> |
48 | #include <wsutil/ws_assert.h> |
49 | |
50 | #include "epan/addr_resolv.h" |
51 | #include "epan/column.h" |
52 | #include "epan/dfilter/dfilter-macro.h" |
53 | #include "epan/conversation_filter.h" |
54 | #include "epan/epan_dissect.h" |
55 | #include "epan/filter_expressions.h" |
56 | #include "epan/prefs.h" |
57 | #include "epan/plugin_if.h" |
58 | #include "epan/uat.h" |
59 | #include "epan/uat-int.h" |
60 | #include "epan/value_string.h" |
61 | |
62 | #ifdef HAVE_LUA1 |
63 | #include <epan/wslua/init_wslua.h> |
64 | #endif |
65 | |
66 | #include "ui/alert_box.h" |
67 | #ifdef HAVE_LIBPCAP1 |
68 | #include "ui/capture_ui_utils.h" |
69 | #endif |
70 | |
71 | #include "ui/capture_globals.h" |
72 | #include "ui/help_url.h" |
73 | #include "ui/main_statusbar.h" |
74 | #include "ui/preference_utils.h" |
75 | #include "ui/recent.h" |
76 | #include "ui/recent_utils.h" |
77 | #include "ui/ssl_key_export.h" |
78 | #include "ui/ws_ui_util.h" |
79 | #include "ui/all_files_wildcard.h" |
80 | #include "ui/qt/simple_dialog.h" |
81 | |
82 | #include <ui/qt/utils/variant_pointer.h> |
83 | #include <ui/qt/widgets/drag_drop_toolbar.h> |
84 | #include "ui/qt/widgets/wireshark_file_dialog.h" |
85 | |
86 | #ifdef HAVE_SOFTWARE_UPDATE |
87 | #include "ui/software_update.h" |
88 | #endif |
89 | |
90 | #include "about_dialog.h" |
91 | #include "bluetooth_att_server_attributes_dialog.h" |
92 | #include "bluetooth_devices_dialog.h" |
93 | #include "bluetooth_hci_summary_dialog.h" |
94 | #include "capture_file_dialog.h" |
95 | #include "capture_file_properties_dialog.h" |
96 | #ifdef HAVE_LIBPCAP1 |
97 | #include "capture_options_dialog.h" |
98 | #endif |
99 | #include <ui/qt/utils/color_utils.h> |
100 | #include "coloring_rules_dialog.h" |
101 | #include "conversation_dialog.h" |
102 | #include "conversation_colorize_action.h" |
103 | #include "conversation_hash_tables_dialog.h" |
104 | #include "enabled_protocols_dialog.h" |
105 | #include "decode_as_dialog.h" |
106 | #include <ui/qt/widgets/display_filter_edit.h> |
107 | #include "display_filter_expression_dialog.h" |
108 | #include "dissector_tables_dialog.h" |
109 | #include "endpoint_dialog.h" |
110 | #include "expert_info_dialog.h" |
111 | #include "export_object_action.h" |
112 | #include "export_object_dialog.h" |
113 | #include "export_pdu_dialog.h" |
114 | #include "extcap_options_dialog.h" |
115 | #include "file_set_dialog.h" |
116 | #include "filter_action.h" |
117 | #include "filter_dialog.h" |
118 | #include "firewall_rules_dialog.h" |
119 | #include "follow_stream_action.h" |
120 | #include "follow_stream_dialog.h" |
121 | #include "funnel_statistics.h" |
122 | #include "gsm_map_summary_dialog.h" |
123 | #include "iax2_analysis_dialog.h" |
124 | #include "interface_toolbar.h" |
125 | #include "io_graph_dialog.h" |
126 | #include <ui/qt/widgets/additional_toolbar.h> |
127 | #include "lbm_stream_dialog.h" |
128 | #include "lbm_lbtrm_transport_dialog.h" |
129 | #include "lbm_lbtru_transport_dialog.h" |
130 | #include "lte_mac_statistics_dialog.h" |
131 | #include "lte_rlc_statistics_dialog.h" |
132 | #include "lte_rlc_graph_dialog.h" |
133 | #include "main_application.h" |
134 | #include "manuf_dialog.h" |
135 | #include "mtp3_summary_dialog.h" |
136 | #include "multicast_statistics_dialog.h" |
137 | #include "packet_comment_dialog.h" |
138 | #include "packet_diagram.h" |
139 | #include "packet_dialog.h" |
140 | #include "packet_list.h" |
141 | #include "credentials_dialog.h" |
142 | #include "preferences_dialog.h" |
143 | #include "print_dialog.h" |
144 | #include "profile_dialog.h" |
145 | #include "protocol_hierarchy_dialog.h" |
146 | #include <ui/qt/utils/qt_ui_utils.h> |
147 | #include "resolved_addresses_dialog.h" |
148 | #include "rpc_service_response_time_dialog.h" |
149 | #include "rtp_stream_dialog.h" |
150 | #include "rtp_analysis_dialog.h" |
151 | #include "sctp_all_assocs_dialog.h" |
152 | #include "sctp_assoc_analyse_dialog.h" |
153 | #include "sctp_graph_dialog.h" |
154 | #include "sequence_dialog.h" |
155 | #include "show_packet_bytes_dialog.h" |
156 | #include "tlskeylog_launcher_dialog.h" |
157 | #include "stats_tree_dialog.h" |
158 | #include "strip_headers_dialog.h" |
159 | #include <ui/qt/utils/stock_icon.h> |
160 | #include "supported_protocols_dialog.h" |
161 | #include "tap_parameter_dialog.h" |
162 | #include "tcp_stream_dialog.h" |
163 | #include "time_shift_dialog.h" |
164 | #include "uat_dialog.h" |
165 | #include "voip_calls_dialog.h" |
166 | #include "wlan_statistics_dialog.h" |
167 | #include <ui/qt/widgets/wireless_timeline.h> |
168 | |
169 | #include <functional> |
170 | #include <QClipboard> |
171 | #include <QFileInfo> |
172 | #include <QMessageBox> |
173 | #include <QMetaObject> |
174 | #include <QToolBar> |
175 | #include <QDesktopServices> |
176 | #include <QUrl> |
177 | #include <QMutex> |
178 | |
179 | // XXX You must uncomment QT_WINEXTRAS_LIB lines in CMakeList.txt and |
180 | // cmakeconfig.h.in. |
181 | // #if defined(QT_WINEXTRAS_LIB) |
182 | // #include <QWinJumpList> |
183 | // #include <QWinJumpListCategory> |
184 | // #include <QWinJumpListItem> |
185 | // #endif |
186 | |
187 | // |
188 | // Public slots |
189 | // |
190 | |
191 | bool WiresharkMainWindow::openCaptureFile(QString cf_path, QString read_filter, unsigned int type, bool is_tempfile) |
192 | { |
193 | QString file_name = ""; |
194 | dfilter_t *rfcode = NULL__null; |
195 | df_error_t *df_err = NULL__null; |
196 | int err; |
197 | bool name_param; |
198 | bool ret = true; |
199 | |
200 | // was a file name given as function parameter? |
201 | name_param = !cf_path.isEmpty(); |
202 | |
203 | for (;;) { |
204 | |
205 | if (cf_path.isEmpty()) { |
206 | CaptureFileDialog open_dlg(this, capture_file_.capFile()); |
207 | |
208 | if (open_dlg.open(file_name, type, read_filter)) { |
209 | cf_path = file_name; |
210 | } else { |
211 | ret = false; |
212 | goto finish; |
213 | } |
214 | } else { |
215 | this->welcome_page_->getInterfaceFrame()->showRunOnFile(); |
216 | } |
217 | |
218 | // TODO detect call from "cf_read" -> "update_progress_dlg" |
219 | // ("capture_file_.capFile()->read_lock"), possibly queue opening the |
220 | // file and return early to avoid the warning in testCaptureFileClose. |
221 | |
222 | QString before_what(tr(" before opening another file")); |
223 | if (!testCaptureFileClose(before_what)) { |
224 | ret = false; |
225 | goto finish; |
226 | } |
227 | |
228 | if (dfilter_compile(qUtf8Printable(read_filter), &rfcode, &df_err)dfilter_compile_full(QtPrivate::asString(read_filter).toUtf8( ).constData(), &rfcode, &df_err, (1U << 1)|(1U << 2), __func__)) { |
229 | cf_set_rfcode(CaptureFile::globalCapFile(), rfcode); |
230 | } else { |
231 | /* Not valid. Tell the user, and go back and run the file |
232 | selection box again once they dismiss the alert. */ |
233 | //bad_dfilter_alert_box(top_level, read_filter->str); |
234 | QMessageBox::warning(this, tr("Invalid Display Filter"), |
235 | QString("The filter expression ") + |
236 | read_filter + |
237 | QString(" isn't a valid display filter. (") + |
238 | df_err->msg + QString(")."), |
239 | QMessageBox::Ok); |
240 | df_error_free(&df_err); |
241 | if (!name_param) { |
242 | // go back to the selection dialogue only if the file |
243 | // was selected from this dialogue |
244 | cf_path.clear(); |
245 | continue; |
246 | } |
247 | } |
248 | |
249 | /* Make the file name available via MainWindow */ |
250 | setMwFileName(cf_path); |
251 | |
252 | /* Try to open the capture file. This closes the current file if it succeeds. */ |
253 | CaptureFile::globalCapFile()->window = this; |
254 | if (cf_open(CaptureFile::globalCapFile(), qUtf8Printable(cf_path)QtPrivate::asString(cf_path).toUtf8().constData(), type, is_tempfile, &err) != CF_OK) { |
255 | /* We couldn't open it; don't dismiss the open dialog box, |
256 | just leave it around so that the user can, after they |
257 | dismiss the alert box popped up for the open error, |
258 | try again. */ |
259 | CaptureFile::globalCapFile()->window = NULL__null; |
260 | dfilter_free(rfcode); |
261 | cf_path.clear(); |
262 | continue; |
263 | } |
264 | |
265 | switch (cf_read(CaptureFile::globalCapFile(), /*reloading=*/false)) { |
266 | case CF_READ_OK: |
267 | case CF_READ_ERROR: |
268 | /* Just because we got an error, that doesn't mean we were unable |
269 | to read any of the file; we handle what we could get from the |
270 | file. */ |
271 | break; |
272 | |
273 | case CF_READ_ABORTED: |
274 | /* The user bailed out of re-reading the capture file; the |
275 | capture file has been closed - just free the capture file name |
276 | string and return (without changing the last containing |
277 | directory). */ |
278 | capture_file_.setCapFile(NULL__null); |
279 | ret = false; |
280 | goto finish; |
281 | } |
282 | break; |
283 | } |
284 | |
285 | if (!is_tempfile) { |
286 | mainApp->setLastOpenDirFromFilename(cf_path); |
287 | } |
288 | |
289 | main_ui_->statusBar->showExpert(); |
290 | |
291 | finish: |
292 | #ifdef HAVE_LIBPCAP1 |
293 | if (global_commandline_info.quit_after_cap) |
294 | exit(0); |
295 | #endif |
296 | return ret; |
297 | } |
298 | |
299 | void WiresharkMainWindow::filterPackets(QString new_filter, bool force) |
300 | { |
301 | cf_status_t cf_status; |
302 | |
303 | cf_status = cf_filter_packets(CaptureFile::globalCapFile(), new_filter.toUtf8().data(), force); |
304 | |
305 | if (cf_status == CF_OK) { |
306 | if (new_filter.length() > 0) { |
307 | int index = df_combo_box_->findText(new_filter); |
308 | if (index == -1) { |
309 | df_combo_box_->insertItem(0, new_filter); |
310 | df_combo_box_->setCurrentIndex(0); |
311 | } else { |
312 | df_combo_box_->setCurrentIndex(index); |
313 | } |
314 | } else { |
315 | df_combo_box_->lineEdit()->clear(); |
316 | } |
317 | // Only after the display filter has been updated, |
318 | // disable the arrow button |
319 | emit displayFilterSuccess(true); |
320 | } else { |
321 | emit displayFilterSuccess(false); |
322 | } |
323 | } |
324 | |
325 | void WiresharkMainWindow::layoutToolbars() |
326 | { |
327 | Qt::ToolButtonStyle tbstyle = Qt::ToolButtonIconOnly; |
328 | switch (prefs.gui_toolbar_main_style) { |
329 | case TB_STYLE_TEXT1: |
330 | tbstyle = Qt::ToolButtonTextOnly; |
331 | break; |
332 | case TB_STYLE_BOTH2: |
333 | tbstyle = Qt::ToolButtonTextUnderIcon; |
334 | break; |
335 | } |
336 | |
337 | main_ui_->mainToolBar->setToolButtonStyle(tbstyle); |
338 | |
339 | main_ui_->mainToolBar->setVisible(recent.main_toolbar_show); |
340 | main_ui_->displayFilterToolBar->setVisible(recent.filter_toolbar_show); |
341 | #if defined(HAVE_LIBNL1) && defined(HAVE_NL802111) |
342 | main_ui_->wirelessToolBar->setVisible(recent.wireless_toolbar_show); |
343 | #endif |
344 | main_ui_->statusBar->setVisible(recent.statusbar_show); |
345 | |
346 | foreach(QAction *action, main_ui_->menuInterfaceToolbars->actions())for (auto _container_346 = QtPrivate::qMakeForeachContainer(main_ui_ ->menuInterfaceToolbars->actions()); _container_346.i != _container_346.e; ++_container_346.i) if (QAction *action = * _container_346.i; false) {} else { |
347 | QToolBar *toolbar = action->data().value<QToolBar *>(); |
348 | if (g_list_find_custom(recent.interface_toolbars, action->text().toUtf8(), (GCompareFunc)strcmp)) { |
349 | toolbar->setVisible(true); |
350 | } else { |
351 | toolbar->setVisible(false); |
352 | } |
353 | } |
354 | |
355 | QList<QToolBar *> toolbars = findChildren<QToolBar *>(); |
356 | foreach(QToolBar *bar, toolbars)for (auto _container_356 = QtPrivate::qMakeForeachContainer(toolbars ); _container_356.i != _container_356.e; ++_container_356.i) if (QToolBar *bar = *_container_356.i; false) {} else { |
357 | AdditionalToolBar *iftoolbar = dynamic_cast<AdditionalToolBar *>(bar); |
358 | if (iftoolbar) { |
359 | bool visible = false; |
360 | if (g_list_find_custom(recent.gui_additional_toolbars, qUtf8Printable(iftoolbar->menuName())QtPrivate::asString(iftoolbar->menuName()).toUtf8().constData (), (GCompareFunc)strcmp)) |
361 | visible = true; |
362 | |
363 | iftoolbar->setVisible(visible); |
364 | |
365 | } |
366 | } |
367 | } |
368 | |
369 | void WiresharkMainWindow::updatePreferenceActions() |
370 | { |
371 | main_ui_->actionViewPacketList->setEnabled(prefs_has_layout_pane_content(layout_pane_content_plist)); |
372 | main_ui_->actionViewPacketDetails->setEnabled(prefs_has_layout_pane_content(layout_pane_content_pdetails)); |
373 | main_ui_->actionViewPacketBytes->setEnabled(prefs_has_layout_pane_content(layout_pane_content_pbytes)); |
374 | main_ui_->actionViewPacketDiagram->setEnabled(prefs_has_layout_pane_content(layout_pane_content_pdiagram)); |
375 | |
376 | main_ui_->actionViewNameResolutionPhysical->setChecked(gbl_resolv_flags.mac_name); |
377 | main_ui_->actionViewNameResolutionNetwork->setChecked(gbl_resolv_flags.network_name); |
378 | main_ui_->actionViewNameResolutionTransport->setChecked(gbl_resolv_flags.transport_name); |
379 | } |
380 | |
381 | void WiresharkMainWindow::updateRecentActions() |
382 | { |
383 | main_ui_->actionViewMainToolbar->setChecked(recent.main_toolbar_show); |
384 | main_ui_->actionViewFilterToolbar->setChecked(recent.filter_toolbar_show); |
385 | main_ui_->actionViewWirelessToolbar->setChecked(recent.wireless_toolbar_show); |
386 | main_ui_->actionViewStatusBar->setChecked(recent.statusbar_show); |
387 | main_ui_->actionViewPacketList->setChecked(recent.packet_list_show && prefs_has_layout_pane_content(layout_pane_content_plist)); |
388 | main_ui_->actionViewPacketDetails->setChecked(recent.tree_view_show && prefs_has_layout_pane_content(layout_pane_content_pdetails)); |
389 | main_ui_->actionViewPacketBytes->setChecked(recent.byte_view_show && prefs_has_layout_pane_content(layout_pane_content_pbytes)); |
390 | main_ui_->actionViewPacketDiagram->setChecked(recent.packet_diagram_show && prefs_has_layout_pane_content(layout_pane_content_pdiagram)); |
391 | |
392 | foreach(QAction *action, main_ui_->menuInterfaceToolbars->actions())for (auto _container_392 = QtPrivate::qMakeForeachContainer(main_ui_ ->menuInterfaceToolbars->actions()); _container_392.i != _container_392.e; ++_container_392.i) if (QAction *action = * _container_392.i; false) {} else { |
393 | if (g_list_find_custom(recent.interface_toolbars, action->text().toUtf8(), (GCompareFunc)strcmp)) { |
394 | action->setChecked(true); |
395 | } else { |
396 | action->setChecked(false); |
397 | } |
398 | } |
399 | |
400 | foreach(QAction * action, main_ui_->menuAdditionalToolbars->actions())for (auto _container_400 = QtPrivate::qMakeForeachContainer(main_ui_ ->menuAdditionalToolbars->actions()); _container_400.i != _container_400.e; ++_container_400.i) if (QAction * action = *_container_400.i; false) {} else { |
401 | ext_toolbar_t * toolbar = VariantPointer<ext_toolbar_t>::asPtr(action->data()); |
402 | bool checked = false; |
403 | if (toolbar && g_list_find_custom(recent.gui_additional_toolbars, toolbar->name, (GCompareFunc)strcmp)) |
404 | checked = true; |
405 | |
406 | action->setChecked(checked); |
407 | } |
408 | |
409 | foreach(QAction* tda, td_actions.keys())for (auto _container_409 = QtPrivate::qMakeForeachContainer(td_actions .keys()); _container_409.i != _container_409.e; ++_container_409 .i) if (QAction* tda = *_container_409.i; false) {} else { |
410 | if (recent.gui_time_format == td_actions[tda]) { |
411 | tda->setChecked(true); |
412 | } |
413 | } |
414 | foreach(QAction* tpa, tp_actions.keys())for (auto _container_414 = QtPrivate::qMakeForeachContainer(tp_actions .keys()); _container_414.i != _container_414.e; ++_container_414 .i) if (QAction* tpa = *_container_414.i; false) {} else { |
415 | if (recent.gui_time_precision == tp_actions[tpa]) { |
416 | tpa->setChecked(true); |
417 | break; |
418 | } |
419 | } |
420 | main_ui_->actionViewTimeDisplaySecondsWithHoursAndMinutes->setChecked(recent.gui_seconds_format == TS_SECONDS_HOUR_MIN_SEC); |
421 | |
422 | main_ui_->actionViewColorizePacketList->setChecked(recent.packet_list_colorize); |
423 | |
424 | main_ui_->actionGoAutoScroll->setChecked(recent.capture_auto_scroll); |
425 | } |
426 | |
427 | // Don't connect to this directly. Connect to or emit filterAction(...) instead. |
428 | void WiresharkMainWindow::queuedFilterAction(QString action_filter, FilterAction::Action action, FilterAction::ActionType type) |
429 | { |
430 | QString cur_filter, new_filter; |
431 | |
432 | if (!df_combo_box_) return; |
433 | cur_filter = df_combo_box_->lineEdit()->text(); |
434 | |
435 | switch (type) { |
436 | case FilterAction::ActionTypePlain: |
437 | new_filter = action_filter; |
438 | break; |
439 | case FilterAction::ActionTypeAnd: |
440 | if (cur_filter.length()) { |
441 | new_filter = "(" + cur_filter + ") && (" + action_filter + ")"; |
442 | } |
443 | else { |
444 | new_filter = action_filter; |
445 | } |
446 | break; |
447 | case FilterAction::ActionTypeOr: |
448 | if (cur_filter.length()) { |
449 | new_filter = "(" + cur_filter + ") || (" + action_filter + ")"; |
450 | } else { |
451 | new_filter = action_filter; |
452 | } |
453 | break; |
454 | case FilterAction::ActionTypeNot: |
455 | new_filter = "!(" + action_filter + ")"; |
456 | break; |
457 | case FilterAction::ActionTypeAndNot: |
458 | if (cur_filter.length()) { |
459 | new_filter = "(" + cur_filter + ") && !(" + action_filter + ")"; |
460 | } else { |
461 | new_filter = "!(" + action_filter + ")"; |
462 | } |
463 | break; |
464 | case FilterAction::ActionTypeOrNot: |
465 | if (cur_filter.length()) { |
466 | new_filter = "(" + cur_filter + ") || !(" + action_filter + ")"; |
467 | } else { |
468 | new_filter = "!(" + action_filter + ")"; |
469 | } |
470 | break; |
471 | default: |
472 | ws_assert_not_reached()ws_log_fatal_full("", LOG_LEVEL_ERROR, "ui/qt/wireshark_main_window_slots.cpp" , 472, __func__, "assertion \"not reached\" failed"); |
473 | break; |
474 | } |
475 | |
476 | switch (action) { |
477 | case FilterAction::ActionApply: |
478 | df_combo_box_->lineEdit()->setText(new_filter); |
479 | df_combo_box_->applyDisplayFilter(); |
480 | break; |
481 | case FilterAction::ActionColorize: |
482 | colorizeWithFilter(new_filter.toUtf8()); |
483 | break; |
484 | case FilterAction::ActionCopy: |
485 | mainApp->clipboard()->setText(new_filter); |
486 | break; |
487 | case FilterAction::ActionFind: |
488 | main_ui_->searchFrame->findFrameWithFilter(new_filter); |
489 | break; |
490 | case FilterAction::ActionPrepare: |
491 | df_combo_box_->lineEdit()->setText(new_filter); |
492 | df_combo_box_->lineEdit()->setFocus(); |
493 | break; |
494 | case FilterAction::ActionWebLookup: |
495 | { |
496 | QString url = QString("https://www.google.com/search?q=") + new_filter; |
497 | QDesktopServices::openUrl(QUrl(url)); |
498 | break; |
499 | } |
500 | default: |
501 | ws_assert_not_reached()ws_log_fatal_full("", LOG_LEVEL_ERROR, "ui/qt/wireshark_main_window_slots.cpp" , 501, __func__, "assertion \"not reached\" failed"); |
502 | break; |
503 | } |
504 | } |
505 | |
506 | // Capture callbacks |
507 | |
508 | #ifdef HAVE_LIBPCAP1 |
509 | void WiresharkMainWindow::captureCapturePrepared(capture_session *session) { |
510 | setTitlebarForCaptureInProgress(); |
511 | setWindowIcon(mainApp->captureIcon()); |
512 | pushLiveCaptureInProgress(); |
513 | |
514 | /* Disable menu items that make no sense if you're currently running |
515 | a capture. */ |
516 | bool handle_toolbars = (session->session_will_restart ? false : true); |
517 | setForCaptureInProgress(true, handle_toolbars, session->capture_opts->ifaces); |
518 | // set_capture_if_dialog_for_capture_in_progress(true); |
519 | |
520 | // /* Don't set up main window for a capture file. */ |
521 | // main_set_for_capture_file(false); |
522 | showCapture(); |
523 | } |
524 | |
525 | void WiresharkMainWindow::captureCaptureUpdateStarted(capture_session *session) { |
526 | |
527 | /* We've done this in "prepared" above, but it will be cleared while |
528 | switching to the next multiple file. */ |
529 | setTitlebarForCaptureInProgress(); |
530 | setWindowIcon(mainApp->captureIcon()); |
531 | pushLiveCaptureInProgress(); |
532 | |
533 | bool handle_toolbars = (session->session_will_restart ? false : true); |
534 | setForCaptureInProgress(true, handle_toolbars, session->capture_opts->ifaces); |
535 | |
536 | setForCapturedPackets(true); |
537 | } |
538 | |
539 | void WiresharkMainWindow::captureCaptureUpdateFinished(capture_session *session) { |
540 | |
541 | /* The capture isn't stopping any more - it's stopped. */ |
542 | capture_stopping_ = false; |
543 | |
544 | /* Update the main window as appropriate */ |
545 | updateForUnsavedChanges(); |
546 | setTitlebarForCaptureFile(); |
547 | |
548 | /* Enable menu items that make sense if you're not currently running |
549 | a capture. */ |
550 | bool handle_toolbars = (session->session_will_restart ? false : true); |
551 | setForCaptureInProgress(false, handle_toolbars); |
552 | setMenusForCaptureFile(); |
553 | |
554 | setWindowIcon(mainApp->normalIcon()); |
555 | popLiveCaptureInProgress(); |
556 | |
557 | if (global_commandline_info.quit_after_cap) { |
558 | // Command line asked us to quit after capturing. |
559 | // Don't pop up a dialog to ask for unsaved files etc. |
560 | exit(0); |
561 | } |
562 | } |
563 | |
564 | void WiresharkMainWindow::captureCaptureFixedFinished(capture_session *) { |
565 | |
566 | /* The capture isn't stopping any more - it's stopped. */ |
567 | capture_stopping_ = false; |
568 | setTitlebarForCaptureFile(); |
569 | |
570 | /* Enable menu items that make sense if you're not currently running |
571 | a capture. */ |
572 | setForCaptureInProgress(false); |
573 | /* There isn't a real capture_file structure yet, so just force disabling |
574 | menu options. They will "refresh" when the capture file is reloaded to |
575 | display packets */ |
576 | setMenusForCaptureFile(true); |
577 | |
578 | setWindowIcon(mainApp->normalIcon()); |
579 | popLiveCaptureInProgress(); |
580 | |
581 | if (global_commandline_info.quit_after_cap) { |
582 | // Command line asked us to quit after capturing. |
583 | // Don't pop up a dialog to ask for unsaved files etc. |
584 | exit(0); |
585 | } |
586 | } |
587 | |
588 | void WiresharkMainWindow::captureCaptureFailed(capture_session *) { |
589 | /* Capture isn't stopping any more. */ |
590 | capture_stopping_ = false; |
591 | setTitlebarForCaptureFile(); |
592 | setForCaptureInProgress(false); |
593 | showWelcome(); |
594 | |
595 | // Reset expert information indicator |
596 | main_ui_->statusBar->captureFileClosing(); |
597 | mainApp->popStatus(WiresharkApplication::FileStatus); |
598 | |
599 | setWindowIcon(mainApp->normalIcon()); |
600 | popLiveCaptureInProgress(); |
601 | |
602 | if (global_commandline_info.quit_after_cap) { |
603 | // Command line asked us to quit after capturing. |
604 | // Don't pop up a dialog to ask for unsaved files etc. |
605 | exit(0); |
606 | } |
607 | } |
608 | #endif // HAVE_LIBPCAP |
609 | |
610 | // Callbacks from cfile.c and file.c via CaptureFile::captureFileCallback |
611 | |
612 | void WiresharkMainWindow::captureEventHandler(CaptureEvent ev) |
613 | { |
614 | switch (ev.captureContext()) { |
| 1 | Control jumps to 'case File:' at line 616 | |
|
615 | |
616 | case CaptureEvent::File: |
617 | switch (ev.eventType()) { |
| 2 | | Control jumps to 'case Closed:' at line 624 | |
|
618 | case CaptureEvent::Opened: |
619 | captureFileOpened(); |
620 | break; |
621 | case CaptureEvent::Closing: |
622 | captureFileClosing(); |
623 | break; |
624 | case CaptureEvent::Closed: |
625 | captureFileClosed(); |
| 3 | | Calling 'WiresharkMainWindow::captureFileClosed' | |
|
626 | break; |
627 | case CaptureEvent::Started: |
628 | captureFileReadStarted(tr("Loading")); |
629 | break; |
630 | case CaptureEvent::Finished: |
631 | captureFileReadFinished(); |
632 | break; |
633 | default: |
634 | break; |
635 | } |
636 | break; |
637 | |
638 | case CaptureEvent::Reload: |
639 | switch (ev.eventType()) { |
640 | case CaptureEvent::Started: |
641 | captureFileReadStarted(tr("Reloading")); |
642 | break; |
643 | case CaptureEvent::Finished: |
644 | captureFileReadFinished(); |
645 | break; |
646 | default: |
647 | break; |
648 | } |
649 | break; |
650 | |
651 | case CaptureEvent::Rescan: |
652 | switch (ev.eventType()) { |
653 | case CaptureEvent::Started: |
654 | setMenusForCaptureFile(true); |
655 | captureFileReadStarted(tr("Rescanning")); |
656 | break; |
657 | case CaptureEvent::Finished: |
658 | captureFileReadFinished(); |
659 | break; |
660 | default: |
661 | break; |
662 | } |
663 | break; |
664 | |
665 | case CaptureEvent::Retap: |
666 | switch (ev.eventType()) { |
667 | case CaptureEvent::Started: |
668 | freeze(); |
669 | break; |
670 | case CaptureEvent::Finished: |
671 | thaw(); |
672 | break; |
673 | case CaptureEvent::Flushed: |
674 | draw_tap_listeners(false); |
675 | break; |
676 | default: |
677 | break; |
678 | } |
679 | break; |
680 | |
681 | case CaptureEvent::Merge: |
682 | switch (ev.eventType()) { |
683 | case CaptureEvent::Started: |
684 | mainApp->popStatus(WiresharkApplication::FileStatus); |
685 | mainApp->pushStatus(WiresharkApplication::FileStatus, tr("Merging files."), QString()); |
686 | break; |
687 | case CaptureEvent::Finished: |
688 | mainApp->popStatus(WiresharkApplication::FileStatus); |
689 | break; |
690 | default: |
691 | break; |
692 | } |
693 | break; |
694 | |
695 | case CaptureEvent::Save: |
696 | switch (ev.eventType()) { |
697 | case CaptureEvent::Started: |
698 | { |
699 | QFileInfo file_info(ev.filePath()); |
700 | mainApp->popStatus(WiresharkApplication::FileStatus); |
701 | mainApp->pushStatus(WiresharkApplication::FileStatus, tr("Saving %1…").arg(file_info.fileName())); |
702 | break; |
703 | } |
704 | default: |
705 | break; |
706 | } |
707 | break; |
708 | |
709 | #ifdef HAVE_LIBPCAP1 |
710 | case CaptureEvent::Capture: |
711 | switch (ev.eventType()) { |
712 | case CaptureEvent::Prepared: |
713 | captureCapturePrepared(ev.capSession()); |
714 | break; |
715 | case CaptureEvent::Stopping: |
716 | capture_stopping_ = true; |
717 | setMenusForCaptureStopping(); |
718 | break; |
719 | case CaptureEvent::Failed: |
720 | captureCaptureFailed(ev.capSession()); |
721 | default: |
722 | break; |
723 | } |
724 | break; |
725 | |
726 | case CaptureEvent::Update: |
727 | switch (ev.eventType()) { |
728 | case CaptureEvent::Started: |
729 | captureCaptureUpdateStarted(ev.capSession()); |
730 | break; |
731 | case CaptureEvent::Finished: |
732 | captureCaptureUpdateFinished(ev.capSession()); |
733 | break; |
734 | default: |
735 | break; |
736 | } |
737 | break; |
738 | |
739 | case CaptureEvent::Fixed: |
740 | switch (ev.eventType()) { |
741 | case CaptureEvent::Finished: |
742 | captureCaptureFixedFinished(ev.capSession()); |
743 | break; |
744 | default: |
745 | break; |
746 | } |
747 | break; |
748 | #endif |
749 | } |
750 | } |
751 | |
752 | void WiresharkMainWindow::captureFileOpened() { |
753 | if (capture_file_.window() != this) return; |
754 | |
755 | file_set_dialog_->fileOpened(capture_file_.capFile()); |
756 | setMenusForFileSet(true); |
757 | emit setCaptureFile(capture_file_.capFile()); |
758 | } |
759 | |
760 | void WiresharkMainWindow::captureFileReadStarted(const QString &action) { |
761 | // tap_param_dlg_update(); |
762 | |
763 | /* Set up main window for a capture file. */ |
764 | // main_set_for_capture_file(true); |
765 | |
766 | mainApp->popStatus(WiresharkApplication::FileStatus); |
767 | QString msg = QString(tr("%1: %2")).arg(action).arg(capture_file_.fileName()); |
768 | QString msgtip = QString(); |
769 | mainApp->pushStatus(WiresharkApplication::FileStatus, msg, msgtip); |
770 | showCapture(); |
771 | main_ui_->actionAnalyzeReloadLuaPlugins->setEnabled(false); |
772 | main_ui_->wirelessTimelineWidget->captureFileReadStarted(capture_file_.capFile()); |
773 | } |
774 | |
775 | void WiresharkMainWindow::captureFileReadFinished() { |
776 | if (!capture_file_.capFile()->is_tempfile && capture_file_.capFile()->filename) { |
777 | /* Add this filename to the list of recent files in the "Recent Files" submenu */ |
778 | add_menu_recent_capture_file(capture_file_.capFile()->filename, false); |
779 | |
780 | /* Remember folder for next Open dialog and save it in recent */ |
781 | mainApp->setLastOpenDirFromFilename(capture_file_.capFile()->filename); |
782 | } |
783 | |
784 | /* Update the appropriate parts of the main window. */ |
785 | updateForUnsavedChanges(); |
786 | |
787 | /* enable wireless timeline if capture allows it */ |
788 | main_ui_->wirelessTimelineWidget->captureFileReadFinished(); |
789 | |
790 | /* Enable menu items that make sense if you have some captured packets. */ |
791 | setForCapturedPackets(true); |
792 | |
793 | main_ui_->statusBar->setFileName(capture_file_); |
794 | main_ui_->actionAnalyzeReloadLuaPlugins->setEnabled(true); |
795 | |
796 | packet_list_->captureFileReadFinished(); |
797 | |
798 | emit setDissectedCaptureFile(capture_file_.capFile()); |
799 | } |
800 | |
801 | void WiresharkMainWindow::captureFileClosing() { |
802 | setMenusForCaptureFile(true); |
803 | setTitlebarForCaptureFile(); |
804 | setForCapturedPackets(false); |
805 | setForCaptureInProgress(false); |
806 | |
807 | // Reset expert information indicator |
808 | main_ui_->statusBar->captureFileClosing(); |
809 | main_ui_->searchFrame->animatedHide(); |
810 | main_ui_->goToFrame->animatedHide(); |
811 | // gtk_widget_show(expert_info_none); |
812 | emit setCaptureFile(NULL__null); |
813 | emit setDissectedCaptureFile(NULL__null); |
814 | } |
815 | |
816 | void WiresharkMainWindow::captureFileClosed() { |
817 | packets_bar_update(); |
818 | |
819 | file_set_dialog_->fileClosed(); |
820 | setMenusForFileSet(false); |
821 | setWindowModified(false); |
822 | |
823 | // Reset expert information indicator |
824 | main_ui_->statusBar->captureFileClosing(); |
825 | mainApp->popStatus(WiresharkApplication::FileStatus); |
826 | |
827 | setWSWindowTitle(); |
828 | setWindowIcon(mainApp->normalIcon()); |
829 | setMenusForSelectedPacket(); |
| 4 | | Calling 'WiresharkMainWindow::setMenusForSelectedPacket' | |
|
830 | setMenusForSelectedTreeRow(); |
831 | |
832 | #ifdef HAVE_LIBPCAP1 |
833 | if (!global_capture_opts.multi_files_on) |
834 | showWelcome(); |
835 | #endif |
836 | } |
837 | |
838 | // |
839 | // Private slots |
840 | // |
841 | |
842 | // ui/gtk/capture_dlg.c:start_capture_confirmed |
843 | |
844 | void WiresharkMainWindow::startCapture() { |
845 | startCapture(QStringList()); |
846 | } |
847 | |
848 | void WiresharkMainWindow::startCapture(QStringList interfaces) { |
849 | #ifdef HAVE_LIBPCAP1 |
850 | interface_options *interface_opts; |
851 | unsigned i; |
852 | interface_t *device; |
853 | bool can_start_capture = true; |
854 | |
855 | if (interfaces.count() > 0) { |
856 | global_capture_opts.num_selected = 0; |
857 | for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { |
858 | device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i)(((interface_t*) (void *) (global_capture_opts.all_ifaces)-> data) [(i)]); |
859 | |
860 | if (interfaces.contains(device->name)) { |
861 | device->selected = true; |
862 | global_capture_opts.num_selected++; |
863 | } |
864 | else { |
865 | device->selected = false; |
866 | } |
867 | } |
868 | } |
869 | |
870 | /* did the user ever select a capture interface before? */ |
871 | if (global_capture_opts.num_selected == 0) { |
872 | QString msg = QString(tr("No interface selected.")); |
873 | mainApp->pushStatus(WiresharkApplication::TemporaryStatus, msg); |
874 | main_ui_->actionCaptureStart->setChecked(false); |
875 | return; |
876 | } |
877 | |
878 | for (i = 0; i < global_capture_opts.all_ifaces->len; i++) { |
879 | device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i)(((interface_t*) (void *) (global_capture_opts.all_ifaces)-> data) [(i)]); |
880 | if (device->selected && (device->if_info.type == IF_EXTCAP)) { |
881 | /* device is EXTCAP and is selected. Check if all mandatory |
882 | * settings are set. |
883 | */ |
884 | if (extcap_requires_configuration(device->name)) |
885 | { |
886 | /* Request opening of extcap options dialog */ |
887 | QString device_name(device->name); |
888 | emit showExtcapOptions(device_name, false); |
889 | /* Cancel start of capture */ |
890 | can_start_capture = false; |
891 | } |
892 | } |
893 | } |
894 | |
895 | /* If some of extcap was not configured, do not start with the capture */ |
896 | if (!can_start_capture) { |
897 | QString msg = QString(tr("Configure all extcaps before start of capture.")); |
898 | mainApp->pushStatus(WiresharkApplication::TemporaryStatus, msg); |
899 | main_ui_->actionCaptureStart->setChecked(false); |
900 | return; |
901 | } |
902 | |
903 | // Ideally we should have disabled the start capture |
904 | // toolbar buttons and menu items. This may not be the |
905 | // case, e.g. with QtMacExtras. |
906 | if (!capture_filter_valid_) { |
907 | QString msg = QString(tr("Invalid capture filter.")); |
908 | mainApp->pushStatus(WiresharkApplication::TemporaryStatus, msg); |
909 | main_ui_->actionCaptureStart->setChecked(false); |
910 | return; |
911 | } |
912 | |
913 | showCapture(); |
914 | |
915 | /* XXX - we might need to init other pref data as well... */ |
916 | main_ui_->actionGoAutoScroll->setChecked(recent.capture_auto_scroll); |
917 | |
918 | /* XXX - can this ever happen? */ |
919 | if (cap_session_.state != CAPTURE_STOPPED) |
920 | return; |
921 | |
922 | /* close the currently loaded capture file */ |
923 | cf_close((capture_file *)cap_session_.cf); |
924 | |
925 | /* Copy the selected interfaces to the set of interfaces to use for |
926 | this capture. */ |
927 | collect_ifaces(&global_capture_opts); |
928 | |
929 | CaptureFile::globalCapFile()->window = this; |
930 | info_data_.ui.ui = this; |
931 | if (capture_start(&global_capture_opts, NULL__null, &cap_session_, &info_data_, |
932 | main_window_update)) { |
933 | /* The capture succeeded, which means the capture filter syntax is |
934 | valid; add this capture filter to the recent capture filter list. */ |
935 | QByteArray filter_ba; |
936 | for (i = 0; i < global_capture_opts.ifaces->len; i++) { |
937 | interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, i)(((interface_options*) (void *) (global_capture_opts.ifaces)-> data) [(i)]); |
938 | if (interface_opts->cfilter) { |
939 | recent_add_cfilter(interface_opts->name, interface_opts->cfilter); |
940 | if (filter_ba.isEmpty()) { |
941 | filter_ba = interface_opts->cfilter; |
942 | } else { |
943 | /* Not the first selected interface; is its capture filter |
944 | the same as the one the other interfaces we've looked |
945 | at have? */ |
946 | /* XXX: GCC 12.1 has a bogus warning at -O2 and higher |
947 | * even though the isEmpty() check guarantees that |
948 | * filter_ba.constData() is never NULL or empty. |
949 | */ |
950 | #if WS_IS_AT_LEAST_GNUC_VERSION(12,1)(4 > (12) || (4 == (12) && 2 >= (1))) |
951 | DIAG_OFF(stringop-overread)clang diagnostic push clang diagnostic ignored "-Wstringop-overread"
|
952 | #endif |
953 | if (strcmp(interface_opts->cfilter, filter_ba.constData()) != 0) { |
954 | #if WS_IS_AT_LEAST_GNUC_VERSION(12,1)(4 > (12) || (4 == (12) && 2 >= (1))) |
955 | DIAG_ON(stringop-overread)clang diagnostic pop |
956 | #endif |
957 | /* No, so not all selected interfaces have the same capture |
958 | filter. */ |
959 | filter_ba.clear(); |
960 | } |
961 | } |
962 | } |
963 | } |
964 | if (!filter_ba.isEmpty()) { |
965 | recent_add_cfilter(NULL__null, filter_ba.constData()); |
966 | } |
967 | } else { |
968 | CaptureFile::globalCapFile()->window = NULL__null; |
969 | } |
970 | #else // HAVE_LIBPCAP |
971 | Q_UNUSED(interfaces)(void)interfaces; |
972 | #endif // HAVE_LIBPCAP |
973 | } |
974 | |
975 | void WiresharkMainWindow::pushLiveCaptureInProgress() { |
976 | #ifdef HAVE_LIBPCAP1 |
977 | capture_options *capture_opts = cap_session_.capture_opts; |
978 | GString *interface_names; |
979 | |
980 | /* Add "interface name<live capture in progress>" on main status bar */ |
981 | interface_names = get_iface_list_string(capture_opts, 0); |
982 | if (strlen(interface_names->str) > 0) { |
983 | g_string_append(interface_names, ":"); |
984 | } |
985 | g_string_append(interface_names, " "); |
986 | |
987 | mainApp->popStatus(WiresharkApplication::FileStatus); |
988 | QString msg = QString("%1<live capture in progress>").arg(interface_names->str); |
989 | QString msgtip = QString("to file: "); |
990 | if (capture_opts->save_file) |
991 | msgtip += capture_opts->save_file; |
992 | mainApp->pushStatus(WiresharkApplication::FileStatus, msg, msgtip); |
993 | g_string_free(interface_names, true); |
994 | #endif // HAVE_LIBPCAP |
995 | } |
996 | |
997 | void WiresharkMainWindow::popLiveCaptureInProgress() { |
998 | /* Pop the "<live capture in progress>" message off the status bar. */ |
999 | main_ui_->statusBar->setFileName(capture_file_); |
1000 | } |
1001 | |
1002 | void WiresharkMainWindow::stopCapture() { |
1003 | //#ifdef HAVE_AIRPCAP |
1004 | // if (airpcap_if_active) |
1005 | // airpcap_set_toolbar_stop_capture(airpcap_if_active); |
1006 | //#endif |
1007 | |
1008 | #ifdef HAVE_LIBPCAP1 |
1009 | capture_stop(&cap_session_); |
1010 | #endif // HAVE_LIBPCAP |
1011 | |
1012 | } |
1013 | |
1014 | // Keep focus rects from showing through the welcome screen. Primarily for |
1015 | // macOS. |
1016 | void WiresharkMainWindow::mainStackChanged(int) |
1017 | { |
1018 | for (int i = 0; i < main_ui_->mainStack->count(); i++) { |
1019 | main_ui_->mainStack->widget(i)->setEnabled(i == main_ui_->mainStack->currentIndex()); |
1020 | } |
1021 | } |
1022 | |
1023 | // XXX - Copied from ui/gtk/menus.c |
1024 | |
1025 | /** |
1026 | * Add the capture filename (with an absolute path) to the "Recent Files" menu. |
1027 | */ |
1028 | // XXX - We should probably create a RecentFile class. |
1029 | void WiresharkMainWindow::updateRecentCaptures() { |
1030 | QAction *ra; |
1031 | QMenu *recentMenu = main_ui_->menuOpenRecentCaptureFile; |
1032 | QString action_cf_name; |
1033 | |
1034 | if (!recentMenu) { |
1035 | return; |
1036 | } |
1037 | recentMenu->clear(); |
1038 | |
1039 | #if 0 |
1040 | #if defined(QT_WINEXTRAS_LIB) |
1041 | QWinJumpList recent_jl(this); |
1042 | QWinJumpListCategory *recent_jlc = recent_jl.recent(); |
1043 | if (recent_jlc) { |
1044 | recent_jlc->clear(); |
1045 | recent_jlc->setVisible(true); |
1046 | } |
1047 | #endif |
1048 | #endif |
1049 | #if defined(Q_OS_MAC) |
1050 | if (!dock_menu_) { |
1051 | dock_menu_ = new QMenu(); |
1052 | dock_menu_->setAsDockMenu(); |
1053 | } |
1054 | dock_menu_->clear(); |
1055 | #endif |
1056 | |
1057 | /* Iterate through the actions in menuOpenRecentCaptureFile, |
1058 | * removing special items, a maybe duplicate entry and every item above count_max */ |
1059 | int shortcut = Qt::Key_0; |
1060 | foreach(recent_item_status *ri, mainApp->recentItems())for (auto _container_1060 = QtPrivate::qMakeForeachContainer( mainApp->recentItems()); _container_1060.i != _container_1060 .e; ++_container_1060.i) if (recent_item_status *ri = *_container_1060 .i; false) {} else { |
1061 | // Add the new item |
1062 | ra = new QAction(recentMenu); |
1063 | ra->setData(ri->filename); |
1064 | // XXX - Needs get_recent_item_status or equivalent |
1065 | ra->setEnabled(ri->accessible); |
1066 | recentMenu->insertAction(NULL__null, ra); |
1067 | action_cf_name = ra->data().toString(); |
1068 | if (shortcut <= Qt::Key_9) { |
1069 | ra->setShortcut(Qt::META | (Qt::Key)shortcut); |
1070 | shortcut++; |
1071 | } |
1072 | ra->setText(action_cf_name); |
1073 | connect(ra, &QAction::triggered, this, &WiresharkMainWindow::recentActionTriggered); |
1074 | |
1075 | /* This is slow, at least on my VM here. The added links also open Wireshark |
1076 | * in a new window. It might make more sense to add a recent item when we |
1077 | * open a capture file. */ |
1078 | #if 0 |
1079 | #if defined(QT_WINEXTRAS_LIB) |
1080 | if (recent_jlc) { |
1081 | QFileInfo fi(ri->filename); |
1082 | QWinJumpListItem *jli = recent_jlc->addLink( |
1083 | fi.fileName(), |
1084 | QApplication::applicationFilePath(), |
1085 | QStringList() << "-r" << ri->filename |
1086 | ); |
1087 | // XXX set icon |
1088 | jli->setWorkingDirectory(QDir::toNativeSeparators(QApplication::applicationDirPath())); |
1089 | } |
1090 | #endif |
1091 | #endif |
1092 | #if defined(Q_OS_MAC) |
1093 | QAction *rda = new QAction(dock_menu_); |
1094 | QFileInfo fi(ri->filename); |
1095 | rda->setText(fi.fileName()); |
1096 | dock_menu_->insertAction(NULL__null, rda); |
1097 | connect(rda, &QAction::triggered, ra, &QAction::trigger); |
1098 | #endif |
1099 | #if QT_VERSION((6<<16)|(2<<8)|(4)) < QT_VERSION_CHECK(6, 0, 0)((6<<16)|(0<<8)|(0)) |
1100 | if (recentMenu->actions().count() == static_cast<int>(prefs.gui_recent_files_count_max)) { |
1101 | #else |
1102 | if (recentMenu->actions().count() == static_cast<qsizetype>(prefs.gui_recent_files_count_max)) { |
1103 | #endif |
1104 | break; |
1105 | } |
1106 | } |
1107 | |
1108 | if (recentMenu->actions().count() > 0) { |
1109 | // Separator + "Clear" |
1110 | // XXX - Do we really need this? |
1111 | ra = new QAction(recentMenu); |
1112 | ra->setSeparator(true); |
1113 | recentMenu->insertAction(NULL__null, ra); |
1114 | |
1115 | ra = new QAction(recentMenu); |
1116 | ra->setText(tr("Clear Menu")); |
1117 | recentMenu->insertAction(NULL__null, ra); |
1118 | connect(ra, &QAction::triggered, mainApp, &MainApplication::clearRecentCaptures); |
1119 | } else { |
1120 | if (main_ui_->actionDummyNoFilesFound) { |
1121 | recentMenu->addAction(main_ui_->actionDummyNoFilesFound); |
1122 | } |
1123 | } |
1124 | } |
1125 | |
1126 | void WiresharkMainWindow::recentActionTriggered() { |
1127 | QAction *ra = qobject_cast<QAction*>(sender()); |
1128 | |
1129 | if (ra) { |
1130 | QString cfPath = ra->data().toString(); |
1131 | openCaptureFile(cfPath); |
1132 | } |
1133 | } |
1134 | |
1135 | QString WiresharkMainWindow::commentToMenuText(QString text, int max_len) |
1136 | { |
1137 | text = text.trimmed().replace(QRegularExpression("(\\r?\\n|\\r\\n?)+"), " "); |
1138 | if (text.size() > 0) { |
1139 | if (text.size() > max_len) { |
1140 | text.truncate(max_len); |
1141 | text += "…"; |
1142 | } |
1143 | } |
1144 | else { |
1145 | text = tr("(empty comment)", "placeholder for empty comment"); |
1146 | } |
1147 | return text; |
1148 | } |
1149 | |
1150 | void WiresharkMainWindow::setEditCommentsMenu() |
1151 | { |
1152 | main_ui_->menuPacketComment->clear(); |
1153 | QAction *action = main_ui_->menuPacketComment->addAction(tr("Add New Comment…")); |
1154 | connect(action, &QAction::triggered, this, &WiresharkMainWindow::addPacketComment); |
1155 | action->setShortcut(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_C)); |
1156 | if (selectedRows().count() == 1) { |
1157 | const int thisRow = selectedRows().first(); |
1158 | frame_data * current_frame = frameDataForRow(thisRow); |
1159 | wtap_block_t pkt_block = cf_get_packet_block(capture_file_.capFile(), current_frame); |
1160 | unsigned nComments = wtap_block_count_option(pkt_block, OPT_COMMENT1); |
1161 | if (nComments > 0) { |
1162 | main_ui_->menuPacketComment->addSeparator(); |
1163 | for (unsigned i = 0; i < nComments; i++) { |
1164 | QString comment = packet_list_->getPacketComment(i); |
1165 | comment = this->commentToMenuText(comment); |
1166 | action = main_ui_->menuPacketComment->addAction(tr("Edit \"%1\"", "edit packet comment").arg(comment)); |
1167 | connect(action, &QAction::triggered, this, &WiresharkMainWindow::editPacketComment); |
1168 | action->setData(i); |
1169 | } |
1170 | |
1171 | main_ui_->menuPacketComment->addSeparator(); |
1172 | for (unsigned i = 0; i < nComments; i++) { |
1173 | QString comment = packet_list_->getPacketComment(i); |
1174 | comment = this->commentToMenuText(comment); |
1175 | action = main_ui_->menuPacketComment->addAction(tr("Delete \"%1\"", "delete packet comment").arg(comment)); |
1176 | connect(action, &QAction::triggered, this, &WiresharkMainWindow::deletePacketComment); |
1177 | action->setData(i); |
1178 | } |
1179 | main_ui_->menuPacketComment->addSeparator(); |
1180 | action = main_ui_->menuPacketComment->addAction(tr("Delete packet comments")); |
1181 | connect(action, &QAction::triggered, this, &WiresharkMainWindow::deleteCommentsFromPackets); |
1182 | } |
1183 | wtap_block_unref(pkt_block); |
1184 | } |
1185 | if (selectedRows().count() > 1) { |
1186 | main_ui_->menuPacketComment->addSeparator(); |
1187 | action = main_ui_->menuPacketComment->addAction(tr("Delete comments from %n packet(s)", nullptr, static_cast<int>(selectedRows().count()))); |
1188 | connect(action, &QAction::triggered, this, &WiresharkMainWindow::deleteCommentsFromPackets); |
1189 | } |
1190 | } |
1191 | |
1192 | void WiresharkMainWindow::setMenusForSelectedPacket() |
1193 | { |
1194 | bool is_ip = false, is_tcp = false, is_udp = false, is_sctp = false, is_tls = false, is_rtp = false, is_lte_rlc = false, |
1195 | is_quic = false, is_exported_pdu = false; |
1196 | |
1197 | /* Making the menu context-sensitive allows for easier selection of the |
1198 | desired item and has the added benefit, with large captures, of |
1199 | avoiding needless looping through huge lists for marked, ignored, |
1200 | or time-referenced packets. */ |
1201 | |
1202 | /* We have one or more items in the packet list */ |
1203 | bool have_frames = false; |
1204 | /* A frame is selected */ |
1205 | bool frame_selected = false; |
1206 | bool multi_selection = false; |
1207 | /* A visible packet comes after this one in the selection history */ |
1208 | bool next_selection_history = false; |
1209 | /* A visible packet comes before this one in the selection history */ |
1210 | bool previous_selection_history = false; |
1211 | /* We have marked frames. (XXX - why check frame_selected?) */ |
1212 | bool have_marked = false; |
1213 | /* We have a marked frame other than the current frame (i.e., |
1214 | we have at least one marked frame, and either there's more |
1215 | than one marked frame or the current frame isn't marked). */ |
1216 | bool another_is_marked = false; |
1217 | /* One or more frames are hidden by a display filter */ |
1218 | bool have_filtered = false; |
1219 | /* One or more frames have been ignored */ |
1220 | bool have_ignored = false; |
1221 | bool have_time_ref = false; |
1222 | /* We have a time reference frame other than the current frame (i.e., |
1223 | we have at least one time reference frame, and either there's more |
1224 | than one time reference frame or the current frame isn't a |
1225 | time reference frame). (XXX - why check frame_selected?) */ |
1226 | bool another_is_time_ref = false; |
1227 | |
1228 | QList<QAction *> cc_actions = QList<QAction *>() |
1229 | << main_ui_->actionViewColorizeConversation1 << main_ui_->actionViewColorizeConversation2 |
1230 | << main_ui_->actionViewColorizeConversation3 << main_ui_->actionViewColorizeConversation4 |
1231 | << main_ui_->actionViewColorizeConversation5 << main_ui_->actionViewColorizeConversation6 |
1232 | << main_ui_->actionViewColorizeConversation7 << main_ui_->actionViewColorizeConversation8 |
1233 | << main_ui_->actionViewColorizeConversation9 << main_ui_->actionViewColorizeConversation10; |
1234 | |
1235 | if (capture_file_.capFile()) { |
| 5 | | Assuming the condition is true | |
|
| |
1236 | QList<int> rows = selectedRows(); |
1237 | frame_data * current_frame = 0; |
| 7 | | 'current_frame' initialized to a null pointer value | |
|
1238 | if (rows.count() > 0) |
| 8 | | Assuming the condition is false | |
|
| |
1239 | current_frame = frameDataForRow(rows.at(0)); |
1240 | |
1241 | frame_selected = rows.count() == 1; |
| 10 | | Assuming the condition is true | |
|
1242 | if (packet_list_->multiSelectActive()) |
| 11 | | Assuming the condition is false | |
|
| |
1243 | { |
1244 | frame_selected = false; |
1245 | multi_selection = true; |
1246 | } |
1247 | next_selection_history = packet_list_->haveNextHistory(); |
1248 | previous_selection_history = packet_list_->havePreviousHistory(); |
1249 | have_frames = capture_file_.capFile()->count > 0; |
| 13 | | Assuming field 'count' is <= 0 | |
|
1250 | have_marked = capture_file_.capFile()->marked_count > 0; |
| 14 | | Assuming field 'marked_count' is <= 0 | |
|
1251 | another_is_marked = have_marked14.1 | 'have_marked' is false |
14.1 | 'have_marked' is false | && rows.count() <= 1 && |
1252 | !(capture_file_.capFile()->marked_count == 1 && frame_selected && current_frame->marked); |
1253 | have_filtered = capture_file_.capFile()->displayed_count > 0 && capture_file_.capFile()->displayed_count != capture_file_.capFile()->count; |
| 15 | | Assuming field 'displayed_count' is <= 0 | |
|
1254 | have_ignored = capture_file_.capFile()->ignored_count > 0; |
| 16 | | Assuming field 'ignored_count' is <= 0 | |
|
1255 | have_time_ref = capture_file_.capFile()->ref_time_count > 0; |
| 17 | | Assuming field 'ref_time_count' is > 0 | |
|
1256 | another_is_time_ref = have_time_ref17.1 | 'have_time_ref' is true |
17.1 | 'have_time_ref' is true | && rows.count() <= 1 && |
| 18 | | Assuming the condition is true | |
|
1257 | !(capture_file_.capFile()->ref_time_count == 1 && frame_selected19.1 | 'frame_selected' is true |
19.1 | 'frame_selected' is true | && current_frame->ref_time); |
| 19 | | Assuming field 'ref_time_count' is equal to 1 | |
|
| 20 | | Access to field 'ref_time' results in a dereference of a null pointer (loaded from variable 'current_frame') |
|
1258 | |
1259 | if (capture_file_.capFile()->edt && ! multi_selection) |
1260 | { |
1261 | proto_get_frame_protocols(capture_file_.capFile()->edt->pi.layers, |
1262 | &is_ip, &is_tcp, &is_udp, &is_sctp, |
1263 | &is_tls, &is_rtp, &is_lte_rlc); |
1264 | /* TODO: to follow a QUIC stream we need a *decrypted* QUIC connection, i.e. checking for "quic" in the protocol stack is not enough */ |
1265 | is_quic = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, "quic"); |
1266 | is_exported_pdu = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, "exported_pdu"); |
1267 | /* For Exported PDU there is a tag inserting IP addresses into the SRC and DST columns */ |
1268 | if (is_exported_pdu && |
1269 | (capture_file_.capFile()->edt->pi.net_src.type == AT_IPv4 || capture_file_.capFile()->edt->pi.net_src.type == AT_IPv6) && |
1270 | (capture_file_.capFile()->edt->pi.net_dst.type == AT_IPv4 || capture_file_.capFile()->edt->pi.net_dst.type == AT_IPv6)) { |
1271 | is_ip = true; |
1272 | } |
1273 | foreach (FollowStreamAction *follow_action, main_ui_->menuFollow->findChildren<FollowStreamAction *>())for (auto _container_1273 = QtPrivate::qMakeForeachContainer( main_ui_->menuFollow->findChildren<FollowStreamAction *>()); _container_1273.i != _container_1273.e; ++_container_1273 .i) if (FollowStreamAction *follow_action = *_container_1273. i; false) {} else { |
1274 | /* QUIC has TLS handshakes; don't enabled Follow TLS Stream if |
1275 | * there's QUIC. |
1276 | */ |
1277 | bool is_frame = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, follow_action->filterName()); |
1278 | if (g_strcmp0(follow_action->filterName(), "tls") == 0) { |
1279 | follow_action->setEnabled(is_frame && !is_quic); |
1280 | } else { |
1281 | follow_action->setEnabled(is_frame); |
1282 | } |
1283 | } |
1284 | } |
1285 | } |
1286 | |
1287 | main_ui_->actionCopyListAsText->setEnabled(selectedRows().count() > 0); |
1288 | main_ui_->actionCopyListAsCSV->setEnabled(selectedRows().count() > 0); |
1289 | main_ui_->actionCopyListAsYAML->setEnabled(selectedRows().count() > 0); |
1290 | |
1291 | main_ui_->actionEditMarkSelected->setEnabled(frame_selected || multi_selection); |
1292 | main_ui_->actionEditMarkAllDisplayed->setEnabled(have_frames); |
1293 | /* Unlike un-ignore, do not allow unmark of all frames when no frames are displayed */ |
1294 | main_ui_->actionEditUnmarkAllDisplayed->setEnabled(have_marked); |
1295 | main_ui_->actionEditNextMark->setEnabled(another_is_marked); |
1296 | main_ui_->actionEditPreviousMark->setEnabled(another_is_marked); |
1297 | |
1298 | GArray * linkTypes = Q_NULLPTRnullptr; |
1299 | if (capture_file_.capFile() && capture_file_.capFile()->linktypes) |
1300 | linkTypes = capture_file_.capFile()->linktypes; |
1301 | |
1302 | bool enableEditComments = linkTypes && wtap_dump_can_write(capture_file_.capFile()->linktypes, WTAP_COMMENT_PER_PACKET0x00000004); |
1303 | main_ui_->menuPacketComment->setEnabled(enableEditComments && selectedRows().count() > 0); |
1304 | main_ui_->actionDeleteAllPacketComments->setEnabled(enableEditComments); |
1305 | |
1306 | main_ui_->actionEditIgnoreSelected->setEnabled(frame_selected || multi_selection); |
1307 | main_ui_->actionEditIgnoreAllDisplayed->setEnabled(have_filtered); |
1308 | /* Allow un-ignore of all frames even with no frames currently displayed */ |
1309 | main_ui_->actionEditUnignoreAllDisplayed->setEnabled(have_ignored); |
1310 | |
1311 | // XXX: Should we allow frames that don't have a time stamp to be |
1312 | // set as time references? "Time" references are also used to reset |
1313 | // the "Cumulative Bytes", so it's not entirely useless. |
1314 | main_ui_->actionEditSetTimeReference->setEnabled(frame_selected); |
1315 | main_ui_->actionEditUnsetAllTimeReferences->setEnabled(have_time_ref); |
1316 | main_ui_->actionEditNextTimeReference->setEnabled(another_is_time_ref); |
1317 | main_ui_->actionEditPreviousTimeReference->setEnabled(another_is_time_ref); |
1318 | main_ui_->actionEditTimeShift->setEnabled(have_frames); |
1319 | |
1320 | main_ui_->actionGoGoToLinkedPacket->setEnabled(false); |
1321 | main_ui_->actionGoNextHistoryPacket->setEnabled(next_selection_history); |
1322 | main_ui_->actionGoPreviousHistoryPacket->setEnabled(previous_selection_history); |
1323 | |
1324 | foreach(QAction *cc_action, cc_actions)for (auto _container_1324 = QtPrivate::qMakeForeachContainer( cc_actions); _container_1324.i != _container_1324.e; ++_container_1324 .i) if (QAction *cc_action = *_container_1324.i; false) {} else { |
1325 | cc_action->setEnabled(frame_selected); |
1326 | } |
1327 | main_ui_->actionViewColorizeNewColoringRule->setEnabled(frame_selected); |
1328 | |
1329 | main_ui_->actionViewColorizeResetColorization->setEnabled(tmp_color_filters_used()); |
1330 | |
1331 | main_ui_->actionViewShowPacketInNewWindow->setEnabled(frame_selected); |
1332 | main_ui_->actionViewEditResolvedName->setEnabled(frame_selected && is_ip); |
1333 | |
1334 | emit packetInfoChanged(capture_file_.packetInfo()); |
1335 | |
1336 | // set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ViewMenu/NameResolution/ResolveName", |
1337 | // frame_selected && (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name || |
1338 | // gbl_resolv_flags.transport_name)); |
1339 | |
1340 | main_ui_->actionToolsFirewallAclRules->setEnabled(frame_selected); |
1341 | |
1342 | main_ui_->actionStatisticsTcpStreamRoundTripTime->setEnabled(is_tcp); |
1343 | main_ui_->actionStatisticsTcpStreamStevens->setEnabled(is_tcp); |
1344 | main_ui_->actionStatisticsTcpStreamTcptrace->setEnabled(is_tcp); |
1345 | main_ui_->actionStatisticsTcpStreamThroughput->setEnabled(is_tcp); |
1346 | main_ui_->actionStatisticsTcpStreamWindowScaling->setEnabled(is_tcp); |
1347 | |
1348 | main_ui_->actionSCTPAnalyseThisAssociation->setEnabled(is_sctp); |
1349 | main_ui_->actionSCTPShowAllAssociations->setEnabled(is_sctp); |
1350 | main_ui_->actionSCTPFilterThisAssociation->setEnabled(is_sctp); |
1351 | main_ui_->actionTelephonyRtpStreamAnalysis->setEnabled(is_rtp); |
1352 | main_ui_->actionTelephonyRtpPlayer->setEnabled(is_rtp); |
1353 | main_ui_->actionTelephonyLteRlcGraph->setEnabled(is_lte_rlc); |
1354 | } |
1355 | |
1356 | void WiresharkMainWindow::setMenusForSelectedTreeRow(FieldInformation *finfo) { |
1357 | |
1358 | bool can_match_selected = false; |
1359 | bool is_framenum = false; |
1360 | bool have_subtree = false; |
1361 | bool can_open_url = false; |
1362 | bool have_packet_bytes = false; |
1363 | QByteArray field_filter; |
1364 | int field_id = -1; |
1365 | |
1366 | field_info * fi = 0; |
1367 | if (finfo) |
1368 | fi = finfo->fieldInfo(); |
1369 | |
1370 | if (capture_file_.capFile()) { |
1371 | capture_file_.capFile()->finfo_selected = fi; |
1372 | |
1373 | if (fi && fi->tree_type != -1) { |
1374 | have_subtree = true; |
1375 | } |
1376 | |
1377 | if (fi && fi->ds_tvb && (fi->length > 0)) { |
1378 | have_packet_bytes = true; |
1379 | } |
1380 | |
1381 | if (!(capture_file_.capFile()->search_in_progress && (capture_file_.capFile()->hex || (capture_file_.capFile()->string && capture_file_.capFile()->packet_data)))) { |
1382 | // If we're not in the middle of a packet bytes search, then set |
1383 | // search_pos and search_len so that we can start a new search |
1384 | // from this point. (If we are, then we already set it.) |
1385 | if (fi && capture_file_.capFile()->edt && (fi->ds_tvb == capture_file_.capFile()->edt->tvb)) { |
1386 | // We can only do a Packet Bytes search in the main bytes from |
1387 | // the frame, not from any secondary data sources. (XXX: This |
1388 | // might be surprising to users, though.) |
1389 | capture_file_.capFile()->search_pos = (uint32_t)(finfo->position().start + finfo->position().length - 1); |
1390 | capture_file_.capFile()->search_len = (uint32_t)finfo->position().length; |
1391 | } else { |
1392 | capture_file_.capFile()->search_pos = 0; |
1393 | capture_file_.capFile()->search_len = 0; |
1394 | } |
1395 | } |
1396 | } |
1397 | |
1398 | if (capture_file_.capFile() != NULL__null && fi != NULL__null) { |
1399 | const header_field_info *hfinfo = fi->hfinfo; |
1400 | int linked_frame = -1; |
1401 | |
1402 | can_match_selected = proto_can_match_selected(capture_file_.capFile()->finfo_selected, capture_file_.capFile()->edt); |
1403 | if (hfinfo && hfinfo->type == FT_FRAMENUM) { |
1404 | is_framenum = true; |
1405 | linked_frame = fvalue_get_uinteger(fi->value); |
1406 | } |
1407 | |
1408 | char *tmp_field = proto_construct_match_selected_string(fi, capture_file_.capFile()->edt); |
1409 | field_filter = tmp_field; |
1410 | wmem_free(NULL__null, tmp_field); |
1411 | emit fieldFilterChanged(field_filter); |
1412 | |
1413 | field_id = fi->hfinfo->id; |
1414 | /* if the selected field isn't a protocol, get its parent */ |
1415 | if (!proto_registrar_is_protocol(field_id)) { |
1416 | field_id = proto_registrar_get_parent(fi->hfinfo->id); |
1417 | } |
1418 | |
1419 | if (field_id >= 0) { |
1420 | can_open_url = true; |
1421 | main_ui_->actionContextWikiProtocolPage->setData(field_id); |
1422 | main_ui_->actionContextFilterFieldReference->setData(field_id); |
1423 | } else { |
1424 | main_ui_->actionContextWikiProtocolPage->setData(QVariant()); |
1425 | main_ui_->actionContextFilterFieldReference->setData(QVariant()); |
1426 | } |
1427 | |
1428 | if (linked_frame > 0) { |
1429 | main_ui_->actionGoGoToLinkedPacket->setData(linked_frame); |
1430 | } else { |
1431 | main_ui_->actionGoGoToLinkedPacket->setData(QVariant()); |
1432 | } |
1433 | } |
1434 | |
1435 | // Always enable / disable the following items. |
1436 | main_ui_->actionCopyAllVisibleItems->setEnabled(capture_file_.capFile() != NULL__null && ! packet_list_->multiSelectActive()); |
1437 | main_ui_->actionCopyAllVisibleSelectedTreeItems->setEnabled(can_match_selected); |
1438 | main_ui_->actionEditCopyDescription->setEnabled(can_match_selected); |
1439 | main_ui_->actionEditCopyFieldName->setEnabled(can_match_selected); |
1440 | main_ui_->actionEditCopyValue->setEnabled(can_match_selected); |
1441 | main_ui_->actionEditCopyAsFilter->setEnabled(can_match_selected); |
1442 | |
1443 | main_ui_->actionAnalyzeShowPacketBytes->setEnabled(have_packet_bytes); |
1444 | main_ui_->actionFileExportPacketBytes->setEnabled(have_packet_bytes); |
1445 | |
1446 | main_ui_->actionViewExpandSubtrees->setEnabled(have_subtree); |
1447 | main_ui_->actionViewCollapseSubtrees->setEnabled(have_subtree); |
1448 | |
1449 | main_ui_->actionGoGoToLinkedPacket->setEnabled(is_framenum); |
1450 | |
1451 | main_ui_->actionAnalyzeApplyAsColumn->setEnabled(can_match_selected); |
1452 | |
1453 | main_ui_->actionContextShowLinkedPacketInNewWindow->setEnabled(is_framenum); |
1454 | |
1455 | main_ui_->actionContextWikiProtocolPage->setEnabled(can_open_url); |
1456 | main_ui_->actionContextFilterFieldReference->setEnabled(can_open_url); |
1457 | |
1458 | |
1459 | // Only enable / disable the following items if we have focus so that we |
1460 | // don't clobber anything we may have set in setMenusForSelectedPacket. |
1461 | if (!proto_tree_ || !proto_tree_->hasFocus()) return; |
1462 | |
1463 | emit packetInfoChanged(capture_file_.packetInfo()); |
1464 | |
1465 | // set_menu_sensitivity(ui_manager_tree_view_menu, "/TreeViewPopup/ResolveName", |
1466 | // frame_selected && (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name || |
1467 | // gbl_resolv_flags.transport_name)); |
1468 | |
1469 | } |
1470 | |
1471 | void WiresharkMainWindow::interfaceSelectionChanged() |
1472 | { |
1473 | #ifdef HAVE_LIBPCAP1 |
1474 | // XXX This doesn't disable the toolbar button when using |
1475 | // QtMacExtras. |
1476 | if (global_capture_opts.num_selected > 0 && capture_filter_valid_) { |
1477 | main_ui_->actionCaptureStart->setEnabled(true); |
1478 | } else { |
1479 | main_ui_->actionCaptureStart->setEnabled(false); |
1480 | } |
1481 | #endif // HAVE_LIBPCAP |
1482 | } |
1483 | |
1484 | void WiresharkMainWindow::captureFilterSyntaxChanged(bool valid) |
1485 | { |
1486 | capture_filter_valid_ = valid; |
1487 | interfaceSelectionChanged(); |
1488 | } |
1489 | |
1490 | void WiresharkMainWindow::startInterfaceCapture(bool valid, const QString capture_filter) |
1491 | { |
1492 | capture_filter_valid_ = valid; |
1493 | welcome_page_->setCaptureFilter(capture_filter); |
1494 | QString before_what(tr(" before starting a new capture")); |
1495 | if (testCaptureFileClose(before_what)) { |
1496 | // The interface tree will update the selected interfaces via its timer |
1497 | // so no need to do anything here. |
1498 | startCapture(QStringList()); |
1499 | } |
1500 | } |
1501 | |
1502 | void WiresharkMainWindow::applyGlobalCommandLineOptions() |
1503 | { |
1504 | if (global_dissect_options.time_format != TS_NOT_SET) { |
1505 | foreach(QAction* tda, td_actions.keys())for (auto _container_1505 = QtPrivate::qMakeForeachContainer( td_actions.keys()); _container_1505.i != _container_1505.e; ++ _container_1505.i) if (QAction* tda = *_container_1505.i; false ) {} else { |
1506 | if (global_dissect_options.time_format == td_actions[tda]) { |
1507 | tda->setChecked(true); |
1508 | // XXX - this means that if the user sets the |
1509 | // time stamp format with the -t flag, that |
1510 | // setting will persist and will be used as |
1511 | // the default the next time Wireshark is run. |
1512 | recent.gui_time_format = global_dissect_options.time_format; |
1513 | timestamp_set_type(global_dissect_options.time_format); |
1514 | break; |
1515 | } |
1516 | } |
1517 | } |
1518 | if (global_dissect_options.time_precision != TS_PREC_NOT_SET) { |
1519 | foreach(QAction* tpa, tp_actions.keys())for (auto _container_1519 = QtPrivate::qMakeForeachContainer( tp_actions.keys()); _container_1519.i != _container_1519.e; ++ _container_1519.i) if (QAction* tpa = *_container_1519.i; false ) {} else { |
1520 | if (global_dissect_options.time_precision == tp_actions[tpa]) { |
1521 | tpa->setChecked(true); |
1522 | // XXX - this means that if the user sets the |
1523 | // time stamp precision with the -t flag, that |
1524 | // setting will persist and will be used as |
1525 | // the default the next time Wireshark is run. |
1526 | recent.gui_time_precision = global_dissect_options.time_precision; |
1527 | timestamp_set_precision(global_dissect_options.time_precision); |
1528 | break; |
1529 | } |
1530 | } |
1531 | } |
1532 | if (global_commandline_info.full_screen) { |
1533 | this->showFullScreen(); |
1534 | } |
1535 | } |
1536 | |
1537 | void WiresharkMainWindow::redissectPackets() |
1538 | { |
1539 | if (capture_file_.capFile()) { |
1540 | cf_redissect_packets(capture_file_.capFile()); |
1541 | main_ui_->statusBar->expertUpdate(); |
1542 | } |
1543 | |
1544 | proto_free_deregistered_fields(); |
1545 | } |
1546 | |
1547 | void WiresharkMainWindow::checkDisplayFilter() |
1548 | { |
1549 | if (!df_combo_box_->checkDisplayFilter()) { |
1550 | g_free(CaptureFile::globalCapFile()->dfilter); |
1551 | CaptureFile::globalCapFile()->dfilter = NULL__null; |
1552 | } |
1553 | } |
1554 | |
1555 | void WiresharkMainWindow::fieldsChanged() |
1556 | { |
1557 | char *err_msg = NULL__null; |
1558 | if (!color_filters_reload(&err_msg, color_filter_add_cb)) { |
1559 | simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK0x01, "%s", err_msg); |
1560 | g_free(err_msg); |
1561 | } |
1562 | tap_listeners_dfilter_recompile(); |
1563 | |
1564 | emit checkDisplayFilter(); |
1565 | |
1566 | if (have_custom_cols(&CaptureFile::globalCapFile()->cinfo)) { |
1567 | // Recreate packet list columns according to new/changed/deleted fields |
1568 | packet_list_->fieldsChanged(CaptureFile::globalCapFile()); |
1569 | } |
1570 | |
1571 | emit reloadFields(); |
1572 | } |
1573 | |
1574 | void WiresharkMainWindow::reloadLuaPlugins() |
1575 | { |
1576 | #ifdef HAVE_LUA1 |
1577 | if (mainApp->isReloadingLua()) |
1578 | return; |
1579 | |
1580 | bool uses_lua_filehandler = false; |
1581 | |
1582 | if (capture_file_.capFile()) { |
1583 | // Check if the current capture file is opened with a Lua FileHandler |
1584 | capture_file *cf = capture_file_.capFile(); |
1585 | uses_lua_filehandler = wtap_uses_lua_filehandler(cf->provider.wth); |
1586 | |
1587 | if (uses_lua_filehandler && cf->unsaved_changes) { |
1588 | // Prompt to save the file before reloading, in case the FileHandler has changed |
1589 | QString before_what(tr(" before reloading Lua plugins")); |
1590 | if (!testCaptureFileClose(before_what, Reload)) { |
1591 | return; |
1592 | } |
1593 | } |
1594 | } |
1595 | |
1596 | mainApp->setReloadingLua(true); |
1597 | |
1598 | wslua_reload_plugins(NULL__null, NULL__null); |
1599 | this->clearAddedPacketMenus(); |
1600 | funnel_statistics_reload_menus(); |
1601 | reloadDynamicMenus(); |
1602 | closePacketDialogs(); |
1603 | |
1604 | // Preferences may have been deleted so close all widgets using prefs |
1605 | main_ui_->preferenceEditorFrame->animatedHide(); |
1606 | |
1607 | mainApp->readConfigurationFiles(true); |
1608 | commandline_options_reapply(); |
1609 | |
1610 | fieldsChanged(); |
1611 | prefs_apply_all(); |
1612 | |
1613 | if (uses_lua_filehandler) { |
1614 | // Reload the file in case the FileHandler has changed |
1615 | if (cf_reload(capture_file_.capFile()) != CF_OK) { |
1616 | cf_close(capture_file_.capFile()); |
1617 | } |
1618 | proto_free_deregistered_fields(); |
1619 | } else { |
1620 | redissectPackets(); |
1621 | } |
1622 | |
1623 | mainApp->setReloadingLua(false); |
1624 | SimpleDialog::displayQueuedMessages(); |
1625 | #endif |
1626 | } |
1627 | |
1628 | void WiresharkMainWindow::showAccordionFrame(AccordionFrame *show_frame, bool toggle) |
1629 | { |
1630 | QList<AccordionFrame *>frame_list = QList<AccordionFrame *>() |
1631 | << main_ui_->goToFrame << main_ui_->searchFrame |
1632 | << main_ui_->addressEditorFrame << main_ui_->columnEditorFrame |
1633 | << main_ui_->preferenceEditorFrame << main_ui_->filterExpressionFrame; |
1634 | |
1635 | frame_list.removeAll(show_frame); |
1636 | foreach(AccordionFrame *af, frame_list)for (auto _container_1636 = QtPrivate::qMakeForeachContainer( frame_list); _container_1636.i != _container_1636.e; ++_container_1636 .i) if (AccordionFrame *af = *_container_1636.i; false) {} else af->animatedHide(); |
1637 | |
1638 | if (toggle) { |
1639 | if (show_frame->isVisible()) { |
1640 | show_frame->animatedHide(); |
1641 | return; |
1642 | } |
1643 | } |
1644 | show_frame->animatedShow(); |
1645 | } |
1646 | |
1647 | void WiresharkMainWindow::showColumnEditor(int column) |
1648 | { |
1649 | setPreviousFocus(); |
1650 | main_ui_->columnEditorFrame->editColumn(column); |
1651 | showAccordionFrame(main_ui_->columnEditorFrame); |
1652 | } |
1653 | |
1654 | void WiresharkMainWindow::showPreferenceEditor() |
1655 | { |
1656 | showAccordionFrame(main_ui_->preferenceEditorFrame); |
1657 | } |
1658 | |
1659 | void WiresharkMainWindow::initViewColorizeMenu() |
1660 | { |
1661 | QList<QAction *> cc_actions = QList<QAction *>() |
1662 | << main_ui_->actionViewColorizeConversation1 << main_ui_->actionViewColorizeConversation2 |
1663 | << main_ui_->actionViewColorizeConversation3 << main_ui_->actionViewColorizeConversation4 |
1664 | << main_ui_->actionViewColorizeConversation5 << main_ui_->actionViewColorizeConversation6 |
1665 | << main_ui_->actionViewColorizeConversation7 << main_ui_->actionViewColorizeConversation8 |
1666 | << main_ui_->actionViewColorizeConversation9 << main_ui_->actionViewColorizeConversation10; |
1667 | |
1668 | uint8_t color_num = 1; |
1669 | |
1670 | foreach(QAction *cc_action, cc_actions)for (auto _container_1670 = QtPrivate::qMakeForeachContainer( cc_actions); _container_1670.i != _container_1670.e; ++_container_1670 .i) if (QAction *cc_action = *_container_1670.i; false) {} else { |
1671 | cc_action->setData(color_num); |
1672 | connect(cc_action, &QAction::triggered, this, &WiresharkMainWindow::colorizeConversation); |
1673 | |
1674 | const color_filter_t *colorf = color_filters_tmp_color(color_num); |
1675 | if (colorf) { |
1676 | QColor bg = ColorUtils::fromColorT(colorf->bg_color); |
1677 | QColor fg = ColorUtils::fromColorT(colorf->fg_color); |
1678 | cc_action->setIcon(StockIcon::colorIcon(bg.rgb(), fg.rgb(), QString::number(color_num))); |
1679 | } |
1680 | color_num++; |
1681 | } |
1682 | |
1683 | #ifdef Q_OS_MAC |
1684 | // Spotlight uses Cmd+Space |
1685 | main_ui_->actionViewColorizeResetColorization->setShortcut(QKeySequence("Meta+Space")); |
1686 | #endif |
1687 | } |
1688 | |
1689 | void WiresharkMainWindow::addStatsPluginsToMenu() { |
1690 | GList *cfg_list = stats_tree_get_cfg_list(); |
1691 | QAction *stats_tree_action; |
1692 | QMenu *parent_menu; |
1693 | bool first_item = true; |
1694 | |
1695 | for (GList *iter = g_list_first(cfg_list); iter; iter = gxx_list_next(iter)((iter) ? ((reinterpret_cast<GList *>(iter))->next) : nullptr)) { |
1696 | stats_tree_cfg *cfg = gxx_list_data(stats_tree_cfg *, iter)((iter) ? ((reinterpret_cast<stats_tree_cfg *>(iter-> data))) : nullptr); |
1697 | if (!menu_groups_.contains(cfg->stat_group)) { |
1698 | continue; |
1699 | } |
1700 | if (cfg->plugin) { |
1701 | if (first_item) { |
1702 | main_ui_->menuStatistics->addSeparator(); |
1703 | first_item = false; |
1704 | } |
1705 | |
1706 | parent_menu = main_ui_->menuStatistics; |
1707 | // gtk/main_menubar.c compresses double slashes, hence SkipEmptyParts |
1708 | #if QT_VERSION((6<<16)|(2<<8)|(4)) >= QT_VERSION_CHECK(5, 15, 0)((5<<16)|(15<<8)|(0)) |
1709 | QStringList cfg_name_parts = QString(cfg->path).split(STATS_TREE_MENU_SEPARATOR"//", Qt::SkipEmptyParts); |
1710 | #else |
1711 | QStringList cfg_name_parts = QString(cfg->path).split(STATS_TREE_MENU_SEPARATOR"//", QString::SkipEmptyParts); |
1712 | #endif |
1713 | if (cfg_name_parts.isEmpty()) continue; |
1714 | |
1715 | QString stat_name = cfg_name_parts.takeLast().trimmed(); |
1716 | if (!cfg_name_parts.isEmpty()) { |
1717 | QString menu_name = cfg_name_parts.join("/").trimmed(); |
1718 | parent_menu = findOrAddMenu(parent_menu, menu_name); |
1719 | } |
1720 | |
1721 | stats_tree_action = new QAction(stat_name, this); |
1722 | stats_tree_action->setData(QString::fromUtf8(cfg->abbr)); |
1723 | parent_menu->addAction(stats_tree_action); |
1724 | connect(stats_tree_action, &QAction::triggered, this, [this]() { |
1725 | QAction* action = qobject_cast<QAction*>(sender()); |
1726 | if (action) { |
1727 | openStatisticsTreeDialog(action->data().toString().toUtf8()); |
1728 | } |
1729 | }); |
1730 | } |
1731 | } |
1732 | g_list_free(cfg_list); |
1733 | } |
1734 | |
1735 | void WiresharkMainWindow::setFeaturesEnabled(bool enabled) |
1736 | { |
1737 | main_ui_->menuBar->setEnabled(enabled); |
1738 | main_ui_->mainToolBar->setEnabled(enabled); |
1739 | main_ui_->displayFilterToolBar->setEnabled(enabled); |
1740 | if (enabled) |
1741 | { |
1742 | main_ui_->statusBar->clearMessage(); |
1743 | #ifdef HAVE_LIBPCAP1 |
1744 | main_ui_->actionGoAutoScroll->setChecked(recent.capture_auto_scroll); |
1745 | #endif |
1746 | } |
1747 | else |
1748 | { |
1749 | main_ui_->statusBar->showMessage(tr("Please wait while Wireshark is initializing…")); |
1750 | } |
1751 | } |
1752 | |
1753 | // Display Filter Toolbar |
1754 | |
1755 | void WiresharkMainWindow::on_actionNewDisplayFilterExpression_triggered() |
1756 | { |
1757 | main_ui_->filterExpressionFrame->addExpression(df_combo_box_->lineEdit()->text()); |
1758 | } |
1759 | |
1760 | void WiresharkMainWindow::onFilterSelected(QString filterText, bool prepare) |
1761 | { |
1762 | if (filterText.length() <= 0) |
1763 | return; |
1764 | |
1765 | df_combo_box_->setDisplayFilter(filterText); |
1766 | // Holding down the Shift key will only prepare filter. |
1767 | if (!prepare) |
1768 | df_combo_box_->applyDisplayFilter(); |
1769 | } |
1770 | |
1771 | void WiresharkMainWindow::onFilterPreferences() |
1772 | { |
1773 | emit showPreferencesDialog(PrefsModel::typeToString(PrefsModel::FilterButtons)); |
1774 | } |
1775 | |
1776 | void WiresharkMainWindow::onFilterEdit(int uatIndex) |
1777 | { |
1778 | main_ui_->filterExpressionFrame->editExpression(uatIndex); |
1779 | } |
1780 | |
1781 | void WiresharkMainWindow::openStatCommandDialog(const QString &menu_path, const char *arg, void *userdata) |
1782 | { |
1783 | QString slot = QString("statCommand%1").arg(menu_path); |
1784 | QMetaObject::invokeMethod(this, slot.toLatin1().constData(), Q_ARG(const char *, arg)QArgument<const char * >("const char *", arg), Q_ARG(void *, userdata)QArgument<void * >("void *", userdata)); |
1785 | } |
1786 | |
1787 | void WiresharkMainWindow::openTapParameterDialog(const QString cfg_str, const QString arg, void *userdata) |
1788 | { |
1789 | TapParameterDialog *tp_dialog = TapParameterDialog::showTapParameterStatistics(*this, capture_file_, cfg_str, arg, userdata); |
1790 | if (!tp_dialog) return; |
1791 | |
1792 | connect(tp_dialog, &TapParameterDialog::filterAction, this, &WiresharkMainWindow::filterAction); |
1793 | connect(tp_dialog, &TapParameterDialog::updateFilter, df_combo_box_->lineEdit(), &QLineEdit::setText); |
1794 | tp_dialog->show(); |
1795 | } |
1796 | |
1797 | void WiresharkMainWindow::openTapParameterDialog() |
1798 | { |
1799 | QAction *tpa = qobject_cast<QAction *>(QObject::sender()); |
1800 | if (!tpa) return; |
1801 | |
1802 | const QString cfg_str = tpa->data().toString(); |
1803 | openTapParameterDialog(cfg_str, NULL__null, NULL__null); |
1804 | } |
1805 | |
1806 | #if defined(HAVE_SOFTWARE_UPDATE) && defined(Q_OS_WIN) |
1807 | void WiresharkMainWindow::softwareUpdateRequested() { |
1808 | // testCaptureFileClose doesn't use this string because we aren't |
1809 | // going to launch another dialog, but maybe we'll change that. |
1810 | QString before_what(tr(" before updating")); |
1811 | if (!testCaptureFileClose(before_what, Update)) { |
1812 | mainApp->rejectSoftwareUpdate(); |
1813 | } |
1814 | } |
1815 | #endif |
1816 | |
1817 | // File Menu |
1818 | |
1819 | void WiresharkMainWindow::connectFileMenuActions() |
1820 | { |
1821 | connect(main_ui_->actionFileOpen, &QAction::triggered, this, |
1822 | [this]() { openCaptureFile(); }); |
1823 | |
1824 | connect(main_ui_->actionFileMerge, &QAction::triggered, this, |
1825 | [this]() { mergeCaptureFile(); }); |
1826 | |
1827 | connect(main_ui_->actionFileImportFromHexDump, &QAction::triggered, this, |
1828 | [this]() { importCaptureFile(); }); |
1829 | |
1830 | connect(main_ui_->actionFileClose, &QAction::triggered, this, [this]() { |
1831 | QString before_what(tr(" before closing the file")); |
1832 | if (testCaptureFileClose(before_what)) { |
1833 | showWelcome(); |
1834 | } |
1835 | }); |
1836 | |
1837 | connect(main_ui_->actionFileSave, &QAction::triggered, this, |
1838 | [this]() { saveCaptureFile(capture_file_.capFile(), false); }); |
1839 | |
1840 | connect(main_ui_->actionFileSaveAs, &QAction::triggered, this, |
1841 | [this]() { saveAsCaptureFile(capture_file_.capFile()); }); |
1842 | |
1843 | connect(main_ui_->actionFileSetListFiles, &QAction::triggered, this, |
1844 | [this]() { file_set_dialog_->show(); }); |
1845 | |
1846 | connect(main_ui_->actionFileSetNextFile, &QAction::triggered, this, [this]() { |
1847 | fileset_entry *entry = fileset_get_next(); |
1848 | |
1849 | if (entry) { |
1850 | QString new_cf_path = entry->fullname; |
1851 | openCaptureFile(new_cf_path); |
1852 | } |
1853 | }); |
1854 | |
1855 | connect(main_ui_->actionFileSetPreviousFile, &QAction::triggered, this, [this]() { |
1856 | fileset_entry *entry = fileset_get_previous(); |
1857 | |
1858 | if (entry) { |
1859 | QString new_cf_path = entry->fullname; |
1860 | openCaptureFile(new_cf_path); |
1861 | } |
1862 | }); |
1863 | |
1864 | connect(main_ui_->actionFileExportPackets, &QAction::triggered, this, |
1865 | [this]() { exportSelectedPackets(); }); |
1866 | |
1867 | connect(main_ui_->actionFileExportAsPlainText, &QAction::triggered, this, |
1868 | [this]() { exportDissections(export_type_text); }); |
1869 | |
1870 | connect(main_ui_->actionFileExportAsCSV, &QAction::triggered, this, |
1871 | [this]() { exportDissections(export_type_csv); }); |
1872 | |
1873 | connect(main_ui_->actionFileExportAsCArrays, &QAction::triggered, this, |
1874 | [this]() { exportDissections(export_type_carrays); }); |
1875 | |
1876 | connect(main_ui_->actionFileExportAsPSML, &QAction::triggered, this, |
1877 | [this]() { exportDissections(export_type_psml); }); |
1878 | |
1879 | connect(main_ui_->actionFileExportAsPDML, &QAction::triggered, this, |
1880 | [this]() { exportDissections(export_type_pdml); }); |
1881 | |
1882 | connect(main_ui_->actionFileExportAsJSON, &QAction::triggered, this, |
1883 | [this]() { exportDissections(export_type_json); }); |
1884 | |
1885 | connect(main_ui_->actionFileExportPacketBytes, &QAction::triggered, this, |
1886 | [this]() { exportPacketBytes(); }, Qt::QueuedConnection); |
1887 | |
1888 | connect(main_ui_->actionFileExportPDU, &QAction::triggered, this, |
1889 | [this]() { exportPDU(); }); |
1890 | |
1891 | connect(main_ui_->actionFileStripHeaders, &QAction::triggered, this, |
1892 | [this]() { stripPacketHeaders(); }); |
1893 | |
1894 | connect(main_ui_->actionFileExportTLSSessionKeys, &QAction::triggered, this, |
1895 | [this]() { exportTLSSessionKeys(); }); |
1896 | |
1897 | connect(main_ui_->actionFilePrint, &QAction::triggered, this, |
1898 | [this]() { printFile(); }); |
1899 | } |
1900 | |
1901 | void WiresharkMainWindow::exportPacketBytes() |
1902 | { |
1903 | QString file_name; |
1904 | |
1905 | if (!capture_file_.capFile() || !capture_file_.capFile()->finfo_selected) return; |
1906 | |
1907 | file_name = WiresharkFileDialog::getSaveFileName(this, |
1908 | mainApp->windowTitleString(tr("Export Selected Packet Bytes")), |
1909 | mainApp->openDialogInitialDir().canonicalPath(), |
1910 | tr("Raw data (*.bin *.dat *.raw);;All Files (" ALL_FILES_WILDCARD"*" ")") |
1911 | ); |
1912 | |
1913 | if (file_name.length() > 0) { |
1914 | const uint8_t *data_p; |
1915 | |
1916 | data_p = tvb_get_ptr(capture_file_.capFile()->finfo_selected->ds_tvb, 0, -1) + |
1917 | capture_file_.capFile()->finfo_selected->start; |
1918 | write_file_binary_mode(qUtf8Printable(file_name)QtPrivate::asString(file_name).toUtf8().constData(), data_p, capture_file_.capFile()->finfo_selected->length); |
1919 | |
1920 | /* Save the directory name for future file dialogs. */ |
1921 | mainApp->setLastOpenDirFromFilename(file_name); |
1922 | } |
1923 | } |
1924 | |
1925 | void WiresharkMainWindow::exportPDU() |
1926 | { |
1927 | ExportPDUDialog *exportpdu_dialog = new ExportPDUDialog(this); |
1928 | |
1929 | if (exportpdu_dialog->isMinimized() == true) |
1930 | { |
1931 | exportpdu_dialog->showNormal(); |
1932 | } |
1933 | else |
1934 | { |
1935 | exportpdu_dialog->show(); |
1936 | } |
1937 | |
1938 | exportpdu_dialog->raise(); |
1939 | exportpdu_dialog->activateWindow(); |
1940 | } |
1941 | |
1942 | void WiresharkMainWindow::stripPacketHeaders() |
1943 | { |
1944 | StripHeadersDialog *stripheaders_dialog = new StripHeadersDialog(this); |
1945 | |
1946 | if (stripheaders_dialog->isMinimized() == true) |
1947 | { |
1948 | stripheaders_dialog->showNormal(); |
1949 | } |
1950 | else |
1951 | { |
1952 | stripheaders_dialog->show(); |
1953 | } |
1954 | |
1955 | stripheaders_dialog->raise(); |
1956 | stripheaders_dialog->activateWindow(); |
1957 | } |
1958 | |
1959 | |
1960 | void WiresharkMainWindow::exportTLSSessionKeys() |
1961 | { |
1962 | QString file_name; |
1963 | QString save_title; |
1964 | int keylist_len; |
1965 | |
1966 | keylist_len = ssl_session_key_count(); |
1967 | /* don't show up the dialog, if no data has to be saved */ |
1968 | if (keylist_len < 1) { |
1969 | /* shouldn't happen as the menu item should have been greyed out */ |
1970 | QMessageBox::warning( |
1971 | this, |
1972 | tr("No Keys"), |
1973 | tr("There are no TLS Session Keys to save."), |
1974 | QMessageBox::Ok |
1975 | ); |
1976 | return; |
1977 | } |
1978 | |
1979 | save_title.append(mainApp->windowTitleString(tr("Export TLS Session Keys (%Ln key(s))", "", keylist_len))); |
1980 | file_name = WiresharkFileDialog::getSaveFileName(this, |
1981 | save_title, |
1982 | mainApp->openDialogInitialDir().canonicalPath(), |
1983 | tr("TLS Session Keys (*.keys *.txt);;All Files (" ALL_FILES_WILDCARD"*" ")") |
1984 | ); |
1985 | if (file_name.length() > 0) { |
1986 | size_t keylist_length; |
1987 | char *keylist = ssl_export_sessions(&keylist_length); |
1988 | write_file_binary_mode(qUtf8Printable(file_name)QtPrivate::asString(file_name).toUtf8().constData(), keylist, keylist_length); |
1989 | |
1990 | /* Save the directory name for future file dialogs. */ |
1991 | mainApp->setLastOpenDirFromFilename(file_name); |
1992 | g_free(keylist); |
1993 | } |
1994 | } |
1995 | |
1996 | void WiresharkMainWindow::printFile() |
1997 | { |
1998 | capture_file *cf = capture_file_.capFile(); |
1999 | g_return_if_fail(cf)do { if ((cf)) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__PRETTY_FUNCTION__)), "cf"); return; } } while (0); |
2000 | |
2001 | QList<int> rows = packet_list_->selectedRows(true); |
2002 | |
2003 | QStringList entries; |
2004 | foreach (int row, rows)for (auto _container_2004 = QtPrivate::qMakeForeachContainer( rows); _container_2004.i != _container_2004.e; ++_container_2004 .i) if (int row = *_container_2004.i; false) {} else |
2005 | entries << QString::number(row); |
2006 | QString selRange = entries.join(","); |
2007 | |
2008 | PrintDialog * pdlg_ = new PrintDialog(this, cf, selRange); |
2009 | pdlg_->setWindowModality(Qt::ApplicationModal); |
2010 | pdlg_->show(); |
2011 | } |
2012 | |
2013 | // Edit Menu |
2014 | |
2015 | void WiresharkMainWindow::connectEditMenuActions() |
2016 | { |
2017 | connect(main_ui_->actionCopyAllVisibleItems, &QAction::triggered, this, |
2018 | [this]() { copySelectedItems(CopyAllVisibleItems); }); |
2019 | |
2020 | connect(main_ui_->actionCopyListAsText, &QAction::triggered, this, |
2021 | [this]() { copySelectedItems(CopyListAsText); }); |
2022 | |
2023 | connect(main_ui_->actionCopyListAsCSV, &QAction::triggered, this, |
2024 | [this]() { copySelectedItems(CopyListAsCSV); }); |
2025 | |
2026 | connect(main_ui_->actionCopyListAsYAML, &QAction::triggered, this, |
2027 | [this]() { copySelectedItems(CopyListAsYAML); }); |
2028 | |
2029 | connect(main_ui_->actionCopyAllVisibleSelectedTreeItems, &QAction::triggered, this, |
2030 | [this]() { copySelectedItems(CopyAllVisibleSelectedTreeItems); }); |
2031 | |
2032 | connect(main_ui_->actionEditCopyDescription, &QAction::triggered, this, |
2033 | [this]() { copySelectedItems(CopySelectedDescription); }); |
2034 | |
2035 | connect(main_ui_->actionEditCopyFieldName, &QAction::triggered, this, |
2036 | [this]() { copySelectedItems(CopySelectedFieldName); }); |
2037 | |
2038 | connect(main_ui_->actionEditCopyValue, &QAction::triggered, this, |
2039 | [this]() { copySelectedItems(CopySelectedValue); }); |
2040 | |
2041 | connect(main_ui_->actionEditCopyAsFilter, &QAction::triggered, this, |
2042 | [this]() { matchFieldFilter(FilterAction::ActionCopy, FilterAction::ActionTypePlain); }); |
2043 | |
2044 | connect(main_ui_->actionEditFindPacket, &QAction::triggered, this, |
2045 | [this]() { findPacket(); }); |
2046 | |
2047 | connect(main_ui_->actionEditFindNext, &QAction::triggered, this, |
2048 | [this]() { main_ui_->searchFrame->findNext(); }); |
2049 | |
2050 | connect(main_ui_->actionEditFindPrevious, &QAction::triggered, this, |
2051 | [this]() { main_ui_->searchFrame->findPrevious(); }); |
2052 | |
2053 | // The items below are used in the packet list and detail context menus. |
2054 | // Use QueuedConnections so that the context menus aren't destroyed |
2055 | // prematurely. |
2056 | connect(main_ui_->actionEditMarkSelected, &QAction::triggered, this, [this]() { |
2057 | freeze(); |
2058 | packet_list_->markFrame(); |
2059 | thaw(); |
2060 | setMenusForSelectedPacket(); |
2061 | }, Qt::QueuedConnection); |
2062 | |
2063 | connect(main_ui_->actionEditMarkAllDisplayed, &QAction::triggered, this, [this]() { |
2064 | freeze(); |
2065 | packet_list_->markAllDisplayedFrames(true); |
2066 | thaw(); |
2067 | setMenusForSelectedPacket(); |
2068 | }, Qt::QueuedConnection); |
2069 | |
2070 | connect(main_ui_->actionEditUnmarkAllDisplayed, &QAction::triggered, this, [this]() { |
2071 | freeze(); |
2072 | packet_list_->markAllDisplayedFrames(false); |
2073 | thaw(); |
2074 | setMenusForSelectedPacket(); |
2075 | }, Qt::QueuedConnection); |
2076 | |
2077 | connect(main_ui_->actionEditNextMark, &QAction::triggered, this, [this]() { |
2078 | if (capture_file_.capFile()) { |
2079 | cf_find_packet_marked(capture_file_.capFile(), SD_FORWARD); |
2080 | } |
2081 | }, Qt::QueuedConnection); |
2082 | |
2083 | connect(main_ui_->actionEditPreviousMark, &QAction::triggered, this, [this]() { |
2084 | if (capture_file_.capFile()) { |
2085 | cf_find_packet_marked(capture_file_.capFile(), SD_BACKWARD); |
2086 | } |
2087 | }, Qt::QueuedConnection); |
2088 | |
2089 | connect(main_ui_->actionEditIgnoreSelected, &QAction::triggered, this, [this]() { |
2090 | freeze(); |
2091 | packet_list_->ignoreFrame(); |
2092 | thaw(); |
2093 | setMenusForSelectedPacket(); |
2094 | }, Qt::QueuedConnection); |
2095 | |
2096 | connect(main_ui_->actionEditIgnoreAllDisplayed, &QAction::triggered, this, [this]() { |
2097 | freeze(); |
2098 | packet_list_->ignoreAllDisplayedFrames(true); |
2099 | thaw(); |
2100 | setMenusForSelectedPacket(); |
2101 | }, Qt::QueuedConnection); |
2102 | |
2103 | connect(main_ui_->actionEditUnignoreAllDisplayed, &QAction::triggered, this, [this]() { |
2104 | freeze(); |
2105 | packet_list_->ignoreAllDisplayedFrames(false); |
2106 | thaw(); |
2107 | setMenusForSelectedPacket(); |
2108 | }, Qt::QueuedConnection); |
2109 | |
2110 | connect(main_ui_->actionEditSetTimeReference, &QAction::triggered, this, [this]() { |
2111 | packet_list_->setTimeReference(); |
2112 | setMenusForSelectedPacket(); |
2113 | }, Qt::QueuedConnection); |
2114 | |
2115 | connect(main_ui_->actionEditUnsetAllTimeReferences, &QAction::triggered, this, [this]() { |
2116 | packet_list_->unsetAllTimeReferences(); |
2117 | setMenusForSelectedPacket(); |
2118 | }, Qt::QueuedConnection); |
2119 | |
2120 | connect(main_ui_->actionEditNextTimeReference, &QAction::triggered, this, [this]() { |
2121 | if (!capture_file_.capFile()) return; |
2122 | cf_find_packet_time_reference(capture_file_.capFile(), SD_FORWARD); |
2123 | }, Qt::QueuedConnection); |
2124 | |
2125 | connect(main_ui_->actionEditPreviousTimeReference, &QAction::triggered, this, [this]() { |
2126 | if (!capture_file_.capFile()) return; |
2127 | cf_find_packet_time_reference(capture_file_.capFile(), SD_BACKWARD); |
2128 | }, Qt::QueuedConnection); |
2129 | |
2130 | connect(main_ui_->actionEditTimeShift, &QAction::triggered, this, |
2131 | [this]() { editTimeShift(); }, Qt::QueuedConnection); |
2132 | |
2133 | connect(main_ui_->actionDeleteAllPacketComments, &QAction::triggered, this, |
2134 | [this]() { deleteAllPacketComments(); }, Qt::QueuedConnection); |
2135 | |
2136 | connect(main_ui_->actionEditInjectSecrets, &QAction::triggered, this, |
2137 | [this]() { injectSecrets(); }, Qt::QueuedConnection); |
2138 | |
2139 | connect(main_ui_->actionEditDiscardAllSecrets, &QAction::triggered, this, |
2140 | [this]() { discardAllSecrets(); }, Qt::QueuedConnection); |
2141 | |
2142 | connect(main_ui_->actionEditConfigurationProfiles, &QAction::triggered, this, |
2143 | [this]() { editConfigurationProfiles(); }, Qt::QueuedConnection); |
2144 | |
2145 | connect(main_ui_->actionEditPreferences, &QAction::triggered, this, |
2146 | [this]() { showPreferencesDialog(PrefsModel::typeToString(PrefsModel::Appearance)); }, Qt::QueuedConnection); |
2147 | } |
2148 | |
2149 | // XXX This should probably be somewhere else. |
2150 | void WiresharkMainWindow::copySelectedItems(WiresharkMainWindow::CopySelected selection_type) |
2151 | { |
2152 | char label_str[ITEM_LABEL_LENGTH240]; |
2153 | QString clip; |
2154 | |
2155 | if (!capture_file_.capFile()) return; |
2156 | |
2157 | field_info *finfo_selected = capture_file_.capFile()->finfo_selected; |
2158 | |
2159 | switch (selection_type) { |
2160 | case CopySelectedDescription: |
2161 | if (proto_tree_->selectionModel()->hasSelection()) { |
2162 | QModelIndex idx = proto_tree_->selectionModel()->selectedIndexes().first(); |
2163 | clip = idx.data(Qt::DisplayRole).toString(); |
2164 | } |
2165 | break; |
2166 | case CopySelectedFieldName: |
2167 | if (finfo_selected && finfo_selected->hfinfo->abbrev != 0) { |
2168 | clip.append(finfo_selected->hfinfo->abbrev); |
2169 | } |
2170 | break; |
2171 | case CopySelectedValue: |
2172 | if (finfo_selected && capture_file_.capFile()->edt != 0) { |
2173 | char* field_str = get_node_field_value(finfo_selected, capture_file_.capFile()->edt); |
2174 | clip.append(field_str); |
2175 | g_free(field_str); |
2176 | } |
2177 | break; |
2178 | case CopyAllVisibleItems: |
2179 | clip = proto_tree_->toString(); |
2180 | break; |
2181 | case CopyAllVisibleSelectedTreeItems: |
2182 | if (proto_tree_->selectionModel()->hasSelection()) { |
2183 | clip = proto_tree_->toString(proto_tree_->selectionModel()->selectedIndexes().first()); |
2184 | } |
2185 | break; |
2186 | case CopyListAsText: |
2187 | case CopyListAsCSV: |
2188 | case CopyListAsYAML: |
2189 | if (packet_list_->selectedRows().count() > 0) |
2190 | { |
2191 | QList<int> rows = packet_list_->selectedRows(); |
2192 | QStringList content; |
2193 | |
2194 | PacketList::SummaryCopyType copyType = PacketList::CopyAsText; |
2195 | if (selection_type == CopyListAsCSV) |
2196 | copyType = PacketList::CopyAsCSV; |
2197 | else if (selection_type == CopyListAsYAML) |
2198 | copyType = PacketList::CopyAsYAML; |
2199 | |
2200 | if ((copyType == PacketList::CopyAsText) || |
2201 | (copyType == PacketList::CopyAsCSV)) { |
2202 | QString headerEntry = packet_list_->createHeaderSummaryText(copyType); |
2203 | content << headerEntry; |
2204 | } |
2205 | foreach (int row, rows)for (auto _container_2205 = QtPrivate::qMakeForeachContainer( rows); _container_2205.i != _container_2205.e; ++_container_2205 .i) if (int row = *_container_2205.i; false) {} else |
2206 | { |
2207 | QModelIndex idx = packet_list_->model()->index(row, 0); |
2208 | if (! idx.isValid()) |
2209 | continue; |
2210 | |
2211 | QString entry = packet_list_->createSummaryText(idx, copyType); |
2212 | content << entry; |
2213 | } |
2214 | |
2215 | if (content.count() > 0) { |
2216 | clip = content.join("\n"); |
2217 | // |
2218 | // Each YAML item ends with a newline, so the string |
2219 | // ends with a newline already if it's CopyListAsYAML. |
2220 | // If we add a newline, there'd be an extra blank |
2221 | // line. |
2222 | // |
2223 | // Otherwise, we've used newlines as separators, not |
2224 | // terminators, so there's no final newline. Add it. |
2225 | // |
2226 | if (selection_type != CopyListAsYAML) |
2227 | clip += "\n"; |
2228 | } |
2229 | } |
2230 | break; |
2231 | } |
2232 | |
2233 | if (clip.length() == 0) { |
2234 | /* If no representation then... Try to read the value */ |
2235 | proto_item_fill_label(capture_file_.capFile()->finfo_selected, label_str); |
2236 | clip.append(label_str); |
2237 | } |
2238 | |
2239 | if (clip.length()) { |
2240 | mainApp->clipboard()->setText(clip); |
2241 | } else { |
2242 | QString err = tr("Couldn't copy text. Try another item."); |
2243 | mainApp->pushStatus(WiresharkApplication::TemporaryStatus, err); |
2244 | } |
2245 | } |
2246 | |
2247 | void WiresharkMainWindow::findPacket() |
2248 | { |
2249 | if (! packet_list_->model() || packet_list_->model()->rowCount() < 1) { |
2250 | return; |
2251 | } |
2252 | setPreviousFocus(); |
2253 | if (!main_ui_->searchFrame->isVisible()) { |
2254 | showAccordionFrame(main_ui_->searchFrame, true); |
2255 | } else { |
2256 | main_ui_->searchFrame->animatedHide(); |
2257 | } |
2258 | main_ui_->searchFrame->setFocus(); |
2259 | } |
2260 | |
2261 | void WiresharkMainWindow::editTimeShift() |
2262 | { |
2263 | TimeShiftDialog *ts_dialog = new TimeShiftDialog(this, capture_file_.capFile()); |
2264 | connect(ts_dialog, &TimeShiftDialog::finished, this, &WiresharkMainWindow::editTimeShiftFinished); |
2265 | |
2266 | connect(this, &WiresharkMainWindow::setCaptureFile, ts_dialog, &TimeShiftDialog::setCaptureFile); |
2267 | connect(ts_dialog, &TimeShiftDialog::timeShifted, packet_list_, &PacketList::applyTimeShift, Qt::QueuedConnection); |
2268 | |
2269 | ts_dialog->setWindowModality(Qt::ApplicationModal); |
2270 | ts_dialog->setAttribute(Qt::WA_DeleteOnClose); |
2271 | ts_dialog->show(); |
2272 | } |
2273 | |
2274 | void WiresharkMainWindow::editTimeShiftFinished(int) |
2275 | { |
2276 | if (capture_file_.capFile()->unsaved_changes) { |
2277 | updateForUnsavedChanges(); |
2278 | } |
2279 | } |
2280 | |
2281 | void WiresharkMainWindow::addPacketComment() |
2282 | { |
2283 | QList<int> rows = selectedRows(); |
2284 | if (rows.count() == 0) |
2285 | return; |
2286 | |
2287 | frame_data * fdata = frameDataForRow(rows.at(0)); |
2288 | if (! fdata) |
2289 | return; |
2290 | |
2291 | PacketCommentDialog* pc_dialog; |
2292 | pc_dialog = new PacketCommentDialog(false, this, NULL__null); |
2293 | connect(pc_dialog, &QDialog::finished, std::bind(&WiresharkMainWindow::addPacketCommentFinished, this, pc_dialog, std::placeholders::_1)); |
2294 | pc_dialog->setWindowModality(Qt::ApplicationModal); |
2295 | pc_dialog->setAttribute(Qt::WA_DeleteOnClose); |
2296 | pc_dialog->show(); |
2297 | } |
2298 | |
2299 | void WiresharkMainWindow::addPacketCommentFinished(PacketCommentDialog* pc_dialog _U___attribute__((unused)), int result _U___attribute__((unused))) |
2300 | { |
2301 | if (result == QDialog::Accepted) { |
2302 | packet_list_->addPacketComment(pc_dialog->text()); |
2303 | updateForUnsavedChanges(); |
2304 | } |
2305 | } |
2306 | |
2307 | void WiresharkMainWindow::editPacketComment() |
2308 | { |
2309 | QList<int> rows = selectedRows(); |
2310 | if (rows.count() != 1) |
2311 | return; |
2312 | |
2313 | QAction *ra = qobject_cast<QAction*>(sender()); |
2314 | unsigned nComment = ra->data().toUInt(); |
2315 | PacketCommentDialog* pc_dialog; |
2316 | pc_dialog = new PacketCommentDialog(true, this, packet_list_->getPacketComment(nComment)); |
2317 | connect(pc_dialog, &QDialog::finished, std::bind(&WiresharkMainWindow::editPacketCommentFinished, this, pc_dialog, std::placeholders::_1, nComment)); |
2318 | pc_dialog->setWindowModality(Qt::ApplicationModal); |
2319 | pc_dialog->setAttribute(Qt::WA_DeleteOnClose); |
2320 | pc_dialog->show(); |
2321 | } |
2322 | |
2323 | void WiresharkMainWindow::editPacketCommentFinished(PacketCommentDialog* pc_dialog _U___attribute__((unused)), int result _U___attribute__((unused)), unsigned nComment) |
2324 | { |
2325 | if (result == QDialog::Accepted) { |
2326 | packet_list_->setPacketComment(nComment, pc_dialog->text()); |
2327 | updateForUnsavedChanges(); |
2328 | } |
2329 | } |
2330 | |
2331 | void WiresharkMainWindow::deletePacketComment() |
2332 | { |
2333 | QAction *ra = qobject_cast<QAction*>(sender()); |
2334 | unsigned nComment = ra->data().toUInt(); |
2335 | packet_list_->setPacketComment(nComment, QString("")); |
2336 | updateForUnsavedChanges(); |
2337 | } |
2338 | |
2339 | void WiresharkMainWindow::deleteCommentsFromPackets() |
2340 | { |
2341 | packet_list_->deleteCommentsFromPackets(); |
2342 | updateForUnsavedChanges(); |
2343 | } |
2344 | |
2345 | void WiresharkMainWindow::deleteAllPacketComments() |
2346 | { |
2347 | QMessageBox *msg_dialog = new QMessageBox(); |
2348 | connect(msg_dialog, &QMessageBox::finished, this, &WiresharkMainWindow::deleteAllPacketCommentsFinished); |
2349 | |
2350 | msg_dialog->setIcon(QMessageBox::Question); |
2351 | msg_dialog->setText(tr("Are you sure you want to remove all packet comments?")); |
2352 | |
2353 | msg_dialog->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); |
2354 | msg_dialog->setDefaultButton(QMessageBox::Ok); |
2355 | |
2356 | msg_dialog->setWindowModality(Qt::ApplicationModal); |
2357 | msg_dialog->setAttribute(Qt::WA_DeleteOnClose); |
2358 | msg_dialog->show(); |
2359 | } |
2360 | |
2361 | void WiresharkMainWindow::deleteAllPacketCommentsFinished(int result) |
2362 | { |
2363 | if (result == QMessageBox::Ok) { |
2364 | /* XXX Do we need a wait/hourglass for large files? */ |
2365 | packet_list_->deleteAllPacketComments(); |
2366 | updateForUnsavedChanges(); |
2367 | } |
2368 | } |
2369 | |
2370 | void WiresharkMainWindow::injectSecrets() |
2371 | { |
2372 | int keylist_len; |
2373 | |
2374 | keylist_len = ssl_session_key_count(); |
2375 | /* don't do anything if no data has to be saved */ |
2376 | if (keylist_len < 1) { |
2377 | QMessageBox::Button ret = QMessageBox::warning( |
2378 | this, |
2379 | tr("No TLS Secrets"), |
2380 | tr("There are no available secrets used to decrypt TLS traffic in the capture file.\ |
2381 | Would you like to view information about how to decrypt TLS traffic on the wiki?"), |
2382 | QMessageBox::Yes | QMessageBox::No, |
2383 | QMessageBox::No); |
2384 | |
2385 | if (ret != QMessageBox::Yes) return; |
2386 | |
2387 | QUrl wiki_url = QString(WS_WIKI_URL("TLS#tls-decryption")"https://wiki.wireshark.org" "/" "TLS#tls-decryption"); |
2388 | QDesktopServices::openUrl(wiki_url); |
2389 | return; |
2390 | } |
2391 | |
2392 | if (!capture_file_.isValid()) |
2393 | return; |
2394 | |
2395 | /* XXX: It would be nice to handle other types of secrets that |
2396 | * can be written to a DSB, maybe have a proper dialog. |
2397 | */ |
2398 | capture_file *cf = capture_file_.capFile(); |
2399 | tls_export_dsb(cf); |
2400 | updateForUnsavedChanges(); |
2401 | } |
2402 | |
2403 | void WiresharkMainWindow::discardAllSecrets() |
2404 | { |
2405 | if (!capture_file_.isValid()) |
2406 | return; |
2407 | |
2408 | QMessageBox* msg_dialog = new QMessageBox(); |
2409 | connect(msg_dialog, &QMessageBox::finished, this, &WiresharkMainWindow::discardAllSecretsFinished); |
2410 | |
2411 | msg_dialog->setIcon(QMessageBox::Question); |
2412 | msg_dialog->setText(tr("Are you sure you want to discard all decryption secrets?")); |
2413 | |
2414 | msg_dialog->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); |
2415 | msg_dialog->setDefaultButton(QMessageBox::Ok); |
2416 | |
2417 | msg_dialog->setWindowModality(Qt::ApplicationModal); |
2418 | msg_dialog->setAttribute(Qt::WA_DeleteOnClose); |
2419 | msg_dialog->show(); |
2420 | } |
2421 | |
2422 | void WiresharkMainWindow::discardAllSecretsFinished(int result) |
2423 | { |
2424 | if (result == QMessageBox::Ok) { |
2425 | /* XXX: It would be nice to handle other types of secrets that |
2426 | * can be written to a DSB, maybe have a proper dialog. |
2427 | */ |
2428 | capture_file* cf = capture_file_.capFile(); |
2429 | if (wtap_file_discard_decryption_secrets(cf->provider.wth)) { |
2430 | cf->unsaved_changes = true; |
2431 | updateForUnsavedChanges(); |
2432 | } |
2433 | } |
2434 | } |
2435 | |
2436 | void WiresharkMainWindow::editConfigurationProfiles() |
2437 | { |
2438 | ProfileDialog *cp_dialog = new ProfileDialog(); |
2439 | cp_dialog->setWindowModality(Qt::ApplicationModal); |
2440 | cp_dialog->setAttribute(Qt::WA_DeleteOnClose); |
2441 | cp_dialog->show(); |
2442 | } |
2443 | |
2444 | void WiresharkMainWindow::showPreferencesDialog(QString module_name) |
2445 | { |
2446 | PreferencesDialog *pref_dialog = new PreferencesDialog(this); |
2447 | connect(pref_dialog, &PreferencesDialog::destroyed, mainApp, &MainApplication::flushAppSignals); |
2448 | saveWindowGeometry(); // Save in case the layout panes are rearranged |
2449 | |
2450 | pref_dialog->setPane(module_name); |
2451 | pref_dialog->setWindowModality(Qt::ApplicationModal); |
2452 | pref_dialog->setAttribute(Qt::WA_DeleteOnClose); |
2453 | pref_dialog->show(); |
2454 | } |
2455 | |
2456 | // View Menu |
2457 | |
2458 | void WiresharkMainWindow::connectViewMenuActions() |
2459 | { |
2460 | connect(main_ui_->actionViewFullScreen, &QAction::triggered, this, [this](bool checked) { |
2461 | if (checked) { |
2462 | // Save the state for future restore |
2463 | was_maximized_ = this->isMaximized(); |
2464 | this->showFullScreen(); |
2465 | } else { |
2466 | // Restore the previous state |
2467 | if (was_maximized_) { |
2468 | this->showMaximized(); |
2469 | } else { |
2470 | this->showNormal(); |
2471 | } |
2472 | } |
2473 | }); |
2474 | |
2475 | connect(main_ui_->actionViewTimeDisplaySecondsWithHoursAndMinutes, &QAction::triggered, this, |
2476 | [this](bool checked) { setTimeDisplaySecondsWithHoursAndMinutes(checked); }); |
2477 | |
2478 | connect(main_ui_->actionViewEditResolvedName, &QAction::triggered, this, |
2479 | [this]() { editResolvedName(); }); |
2480 | |
2481 | connect(main_ui_->actionViewNameResolutionPhysical, &QAction::triggered, this, |
2482 | [this]() { setNameResolution(); }); |
2483 | |
2484 | connect(main_ui_->actionViewNameResolutionNetwork, &QAction::triggered, this, |
2485 | [this]() { setNameResolution(); }); |
2486 | |
2487 | connect(main_ui_->actionViewNameResolutionTransport, &QAction::triggered, this, |
2488 | [this]() { setNameResolution(); }); |
2489 | |
2490 | connect(main_ui_->actionViewZoomIn, &QAction::triggered, this, [this]() { |
2491 | recent.gui_zoom_level++; |
2492 | zoomText(); |
2493 | }); |
2494 | |
2495 | connect(main_ui_->actionViewZoomOut, &QAction::triggered, this, [this]() { |
2496 | recent.gui_zoom_level--; |
2497 | zoomText(); |
2498 | }); |
2499 | |
2500 | connect(main_ui_->actionViewNormalSize, &QAction::triggered, this, [this]() { |
2501 | recent.gui_zoom_level = 0; |
2502 | zoomText(); |
2503 | }); |
2504 | |
2505 | connect(main_ui_->actionViewExpandSubtrees, &QAction::triggered, |
2506 | proto_tree_, &ProtoTree::expandSubtrees); |
2507 | |
2508 | connect(main_ui_->actionViewCollapseSubtrees, &QAction::triggered, |
2509 | proto_tree_, &ProtoTree::collapseSubtrees); |
2510 | |
2511 | connect(main_ui_->actionViewExpandAll, &QAction::triggered, |
2512 | proto_tree_, &ProtoTree::expandAll); |
2513 | |
2514 | connect(main_ui_->actionViewCollapseAll, &QAction::triggered, |
2515 | proto_tree_, &ProtoTree::collapseAll); |
2516 | |
2517 | connect(main_ui_->actionViewColorizePacketList, &QAction::triggered, this, [this](bool checked) { |
2518 | recent.packet_list_colorize = checked; |
2519 | packet_list_->recolorPackets(); |
2520 | }); |
2521 | |
2522 | connect(main_ui_->actionViewColoringRules, &QAction::triggered, this, |
2523 | [this]() { showColoringRulesDialog(); }); |
2524 | |
2525 | connect(main_ui_->actionViewColorizeResetColorization, &QAction::triggered, this, [this]() { |
2526 | char *err_msg = NULL__null; |
2527 | if (!color_filters_reset_tmp(&err_msg)) { |
2528 | simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK0x01, "%s", err_msg); |
2529 | g_free(err_msg); |
2530 | } |
2531 | packet_list_->recolorPackets(); |
2532 | setMenusForSelectedPacket(); |
2533 | }); |
2534 | |
2535 | connect(main_ui_->actionViewColorizeNewColoringRule, &QAction::triggered, this, |
2536 | [this]() { colorizeConversation(true); }); |
2537 | |
2538 | connect(main_ui_->actionViewResetLayout, &QAction::triggered, this, [this]() { |
2539 | recent.gui_geometry_main_upper_pane = 0; |
2540 | recent.gui_geometry_main_lower_pane = 0; |
2541 | g_free(recent.gui_geometry_main_master_split); |
2542 | g_free(recent.gui_geometry_main_extra_split); |
2543 | recent.gui_geometry_main_master_split = NULL__null; |
2544 | recent.gui_geometry_main_extra_split = NULL__null; |
2545 | applyRecentPaneGeometry(); |
2546 | }); |
2547 | |
2548 | connect(main_ui_->actionViewResizeColumns, &QAction::triggered, this, [this]() { |
2549 | if (! packet_list_->model()) |
2550 | return; |
2551 | for (int col = 0; col < packet_list_->model()->columnCount(); col++) { |
2552 | packet_list_->resizeColumnToContents(col); |
2553 | recent_set_column_width(col, packet_list_->columnWidth(col)); |
2554 | } |
2555 | }); |
2556 | |
2557 | connect(main_ui_->actionViewInternalsConversationHashTables, &QAction::triggered, this, [this]() { |
2558 | ConversationHashTablesDialog *conversation_hash_tables_dlg = new ConversationHashTablesDialog(this); |
2559 | conversation_hash_tables_dlg->show(); |
2560 | }); |
2561 | |
2562 | connect(main_ui_->actionViewInternalsDissectorTables, &QAction::triggered, this, [this]() { |
2563 | DissectorTablesDialog *dissector_tables_dlg = new DissectorTablesDialog(this); |
2564 | dissector_tables_dlg->show(); |
2565 | }); |
2566 | |
2567 | connect(main_ui_->actionViewInternalsSupportedProtocols, &QAction::triggered, this, [this]() { |
2568 | SupportedProtocolsDialog *supported_protocols_dlg = new SupportedProtocolsDialog(this); |
2569 | supported_protocols_dlg->show(); |
2570 | }); |
2571 | |
2572 | connect(main_ui_->actionViewShowPacketInNewWindow, &QAction::triggered, this, |
2573 | [this]() { openPacketDialog(); }); |
2574 | |
2575 | // This is only used in ProtoTree. Defining it here makes more sense. |
2576 | connect(main_ui_->actionContextShowLinkedPacketInNewWindow, &QAction::triggered, this, |
2577 | [this]() { openPacketDialog(true); }); |
2578 | |
2579 | connect(main_ui_->actionViewReload_as_File_Format_or_Capture, &QAction::triggered, this, |
2580 | [this]() { reloadCaptureFileAsFormatOrCapture(); }); |
2581 | |
2582 | connect(main_ui_->actionViewReload, &QAction::triggered, this, |
2583 | [this]() { reloadCaptureFile(); }); |
2584 | } |
2585 | |
2586 | void WiresharkMainWindow::showHideMainWidgets(QAction *action) |
2587 | { |
2588 | if (!action) { |
2589 | return; |
2590 | } |
2591 | bool show = action->isChecked(); |
2592 | QWidget *widget = action->data().value<QWidget*>(); |
2593 | |
2594 | // We may have come from the toolbar context menu, so check/uncheck each |
2595 | // action as well. |
2596 | if (widget == main_ui_->mainToolBar) { |
2597 | recent.main_toolbar_show = show; |
2598 | main_ui_->actionViewMainToolbar->setChecked(show); |
2599 | } else if (widget == main_ui_->displayFilterToolBar) { |
2600 | recent.filter_toolbar_show = show; |
2601 | main_ui_->actionViewFilterToolbar->setChecked(show); |
2602 | #if defined(HAVE_LIBNL1) && defined(HAVE_NL802111) |
2603 | } else if (widget == main_ui_->wirelessToolBar) { |
2604 | recent.wireless_toolbar_show = show; |
2605 | main_ui_->actionViewWirelessToolbar->setChecked(show); |
2606 | #endif |
2607 | } else if (widget == main_ui_->statusBar) { |
2608 | recent.statusbar_show = show; |
2609 | main_ui_->actionViewStatusBar->setChecked(show); |
2610 | } else if (widget == packet_list_) { |
2611 | recent.packet_list_show = show; |
2612 | main_ui_->actionViewPacketList->setChecked(show); |
2613 | } else if (widget == proto_tree_) { |
2614 | recent.tree_view_show = show; |
2615 | main_ui_->actionViewPacketDetails->setChecked(show); |
2616 | } else if (widget == byte_view_tab_) { |
2617 | recent.byte_view_show = show; |
2618 | main_ui_->actionViewPacketBytes->setChecked(show); |
2619 | } else if (widget == packet_diagram_) { |
2620 | recent.packet_diagram_show = show; |
2621 | main_ui_->actionViewPacketDiagram->setChecked(show); |
2622 | } else { |
2623 | foreach(QAction *action, main_ui_->menuInterfaceToolbars->actions())for (auto _container_2623 = QtPrivate::qMakeForeachContainer( main_ui_->menuInterfaceToolbars->actions()); _container_2623 .i != _container_2623.e; ++_container_2623.i) if (QAction *action = *_container_2623.i; false) {} else { |
2624 | QToolBar *toolbar = action->data().value<QToolBar *>(); |
2625 | if (widget == toolbar) { |
2626 | GList *entry = g_list_find_custom(recent.interface_toolbars, action->text().toUtf8(), (GCompareFunc)strcmp); |
2627 | if (show && !entry) { |
2628 | recent.interface_toolbars = g_list_append(recent.interface_toolbars, qstring_strdup(action->text())); |
2629 | } else if (!show && entry) { |
2630 | recent.interface_toolbars = g_list_remove(recent.interface_toolbars, entry->data); |
2631 | } |
2632 | action->setChecked(show); |
2633 | } |
2634 | } |
2635 | |
2636 | ext_toolbar_t * toolbar = VariantPointer<ext_toolbar_t>::asPtr(action->data()); |
2637 | if (toolbar) { |
2638 | GList *entry = g_list_find_custom(recent.gui_additional_toolbars, toolbar->name, (GCompareFunc)strcmp); |
2639 | if (show && !entry) { |
2640 | recent.gui_additional_toolbars = g_list_append(recent.gui_additional_toolbars, g_strdup(toolbar->name)); |
2641 | } else if (!show && entry) { |
2642 | recent.gui_additional_toolbars = g_list_remove(recent.gui_additional_toolbars, entry->data); |
2643 | } |
2644 | action->setChecked(show); |
2645 | |
2646 | QList<QToolBar *> toolbars = findChildren<QToolBar *>(); |
2647 | foreach(QToolBar *bar, toolbars)for (auto _container_2647 = QtPrivate::qMakeForeachContainer( toolbars); _container_2647.i != _container_2647.e; ++_container_2647 .i) if (QToolBar *bar = *_container_2647.i; false) {} else { |
2648 | AdditionalToolBar *iftoolbar = dynamic_cast<AdditionalToolBar *>(bar); |
2649 | if (iftoolbar && iftoolbar->menuName().compare(toolbar->name) == 0) { |
2650 | iftoolbar->setVisible(show); |
2651 | } |
2652 | } |
2653 | } |
2654 | } |
2655 | |
2656 | if (widget) { |
2657 | widget->setVisible(show); |
2658 | } |
2659 | } |
2660 | |
2661 | void WiresharkMainWindow::setTimestampFormat(QAction *action) |
2662 | { |
2663 | if (!action) { |
2664 | return; |
2665 | } |
2666 | ts_type tsf = action->data().value<ts_type>(); |
2667 | if (recent.gui_time_format != tsf) { |
2668 | timestamp_set_type(tsf); |
2669 | recent.gui_time_format = tsf; |
2670 | |
2671 | if (packet_list_) { |
2672 | packet_list_->resetColumns(); |
2673 | packet_list_->resizeAllColumns(true); |
2674 | } |
2675 | } |
2676 | } |
2677 | |
2678 | void WiresharkMainWindow::setTimestampPrecision(QAction *action) |
2679 | { |
2680 | if (!action) { |
2681 | return; |
2682 | } |
2683 | ts_precision tsp = action->data().value<ts_precision>(); |
2684 | if (recent.gui_time_precision != tsp) { |
2685 | timestamp_set_precision(tsp); |
2686 | recent.gui_time_precision = tsp; |
2687 | |
2688 | if (packet_list_) { |
2689 | packet_list_->resetColumns(); |
2690 | packet_list_->resizeAllColumns(true); |
2691 | } |
2692 | } |
2693 | } |
2694 | |
2695 | void WiresharkMainWindow::setTimeDisplaySecondsWithHoursAndMinutes(bool checked) |
2696 | { |
2697 | if (checked) { |
2698 | recent.gui_seconds_format = TS_SECONDS_HOUR_MIN_SEC; |
2699 | } else { |
2700 | recent.gui_seconds_format = TS_SECONDS_DEFAULT; |
2701 | } |
2702 | timestamp_set_seconds_type(recent.gui_seconds_format); |
2703 | |
2704 | if (packet_list_) { |
2705 | packet_list_->resetColumns(); |
2706 | packet_list_->resizeAllColumns(true); |
2707 | } |
2708 | } |
2709 | |
2710 | void WiresharkMainWindow::editResolvedName() |
2711 | { |
2712 | //int column = packet_list_->selectedColumn(); |
2713 | int column = -1; |
2714 | |
2715 | if (packet_list_->contextMenuActive() || packet_list_->hasFocus()) { |
2716 | if (packet_list_->currentIndex().isValid()) { |
2717 | column = packet_list_->currentIndex().column(); |
2718 | } |
2719 | } |
2720 | |
2721 | main_ui_->addressEditorFrame->editAddresses(capture_file_, column); |
2722 | showAccordionFrame(main_ui_->addressEditorFrame); |
2723 | } |
2724 | |
2725 | void WiresharkMainWindow::setNameResolution() |
2726 | { |
2727 | gbl_resolv_flags.mac_name = main_ui_->actionViewNameResolutionPhysical->isChecked() ? true : false; |
2728 | gbl_resolv_flags.network_name = main_ui_->actionViewNameResolutionNetwork->isChecked() ? true : false; |
2729 | gbl_resolv_flags.transport_name = main_ui_->actionViewNameResolutionTransport->isChecked() ? true : false; |
2730 | |
2731 | if (packet_list_) { |
2732 | packet_list_->resetColumns(); |
2733 | } |
2734 | mainApp->emitAppSignal(WiresharkApplication::NameResolutionChanged); |
2735 | } |
2736 | |
2737 | void WiresharkMainWindow::zoomText() |
2738 | { |
2739 | mainApp->zoomTextFont(recent.gui_zoom_level); |
2740 | } |
2741 | |
2742 | void WiresharkMainWindow::showColoringRulesDialog() |
2743 | { |
2744 | ColoringRulesDialog *coloring_rules_dialog = new ColoringRulesDialog(this); |
2745 | connect(coloring_rules_dialog, &ColoringRulesDialog::accepted, |
2746 | packet_list_, &PacketList::recolorPackets); |
2747 | connect(coloring_rules_dialog, &ColoringRulesDialog::filterAction, |
2748 | this, &WiresharkMainWindow::filterAction); |
2749 | |
2750 | coloring_rules_dialog->setWindowModality(Qt::ApplicationModal); |
2751 | coloring_rules_dialog->setAttribute(Qt::WA_DeleteOnClose); |
2752 | coloring_rules_dialog->show(); |
2753 | } |
2754 | |
2755 | // actionViewColorizeConversation1 - 10 |
2756 | void WiresharkMainWindow::colorizeConversation(bool create_rule) |
2757 | { |
2758 | QAction *colorize_action = qobject_cast<QAction *>(sender()); |
2759 | if (!colorize_action) return; |
2760 | |
2761 | if (capture_file_.capFile() && selectedRows().count() > 0) { |
2762 | packet_info *pi = capture_file_.packetInfo(); |
2763 | uint8_t cc_num = colorize_action->data().toUInt(); |
2764 | char *filter = conversation_filter_from_packet(pi); |
2765 | if (filter == NULL__null) { |
2766 | mainApp->pushStatus(WiresharkApplication::TemporaryStatus, tr("Unable to build conversation filter.")); |
2767 | return; |
2768 | } |
2769 | |
2770 | if (create_rule) { |
2771 | ColoringRulesDialog coloring_rules_dialog(this, filter); |
2772 | connect(&coloring_rules_dialog, &ColoringRulesDialog::accepted, |
2773 | packet_list_, &PacketList::recolorPackets); |
2774 | connect(&coloring_rules_dialog, &ColoringRulesDialog::filterAction, |
2775 | this, &WiresharkMainWindow::filterAction); |
2776 | coloring_rules_dialog.exec(); |
2777 | } else { |
2778 | char *err_msg = NULL__null; |
2779 | if (!color_filters_set_tmp(cc_num, filter, false, &err_msg)) { |
2780 | simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK0x01, "%s", err_msg); |
2781 | g_free(err_msg); |
2782 | } |
2783 | packet_list_->recolorPackets(); |
2784 | } |
2785 | } |
2786 | setMenusForSelectedPacket(); |
2787 | } |
2788 | |
2789 | void WiresharkMainWindow::colorizeActionTriggered() |
2790 | { |
2791 | QByteArray filter; |
2792 | int color_number = -1; |
2793 | |
2794 | ConversationAction *conv_action = qobject_cast<ConversationAction *>(sender()); |
2795 | if (conv_action) { |
2796 | filter = conv_action->filter(); |
2797 | color_number = conv_action->colorNumber(); |
2798 | } else { |
2799 | ColorizeAction *colorize_action = qobject_cast<ColorizeAction *>(sender()); |
2800 | if (colorize_action) { |
2801 | filter = colorize_action->filter(); |
2802 | color_number = colorize_action->colorNumber(); |
2803 | } |
2804 | } |
2805 | |
2806 | colorizeWithFilter(filter, color_number); |
2807 | } |
2808 | |
2809 | void WiresharkMainWindow::colorizeWithFilter(QByteArray filter, int color_number) |
2810 | { |
2811 | if (filter.isEmpty()) return; |
2812 | |
2813 | if (color_number > 0) { |
2814 | // Assume "Color X" |
2815 | char *err_msg = NULL__null; |
2816 | if (!color_filters_set_tmp(color_number, filter.constData(), false, &err_msg)) { |
2817 | simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK0x01, "%s", err_msg); |
2818 | g_free(err_msg); |
2819 | } |
2820 | packet_list_->recolorPackets(); |
2821 | } else { |
2822 | // New coloring rule |
2823 | ColoringRulesDialog coloring_rules_dialog(window(), filter); |
2824 | connect(&coloring_rules_dialog, &ColoringRulesDialog::accepted, |
2825 | packet_list_, &PacketList::recolorPackets); |
2826 | connect(&coloring_rules_dialog, &ColoringRulesDialog::filterAction, |
2827 | this, &WiresharkMainWindow::filterAction); |
2828 | coloring_rules_dialog.exec(); |
2829 | } |
2830 | main_ui_->actionViewColorizeResetColorization->setEnabled(tmp_color_filters_used()); |
2831 | } |
2832 | |
2833 | void WiresharkMainWindow::openPacketDialog(bool from_reference) |
2834 | { |
2835 | frame_data * fdata = Q_NULLPTRnullptr; |
2836 | |
2837 | /* Find the frame for which we're popping up a dialog */ |
2838 | if (from_reference) { |
2839 | uint32_t framenum = fvalue_get_uinteger(capture_file_.capFile()->finfo_selected->value); |
2840 | if (framenum == 0) |
2841 | return; |
2842 | |
2843 | fdata = frame_data_sequence_find(capture_file_.capFile()->provider.frames, framenum); |
2844 | } else if (selectedRows().count() == 1) { |
2845 | fdata = frameDataForRow(selectedRows().at(0)); |
2846 | } else if (selectedRows().count() > 1) |
2847 | return; |
2848 | |
2849 | /* If we have a frame, pop up the dialog */ |
2850 | if (fdata) { |
2851 | PacketDialog *packet_dialog = new PacketDialog(*this, capture_file_, fdata); |
2852 | |
2853 | connect(packet_dialog, &PacketDialog::showProtocolPreferences, |
2854 | this, &WiresharkMainWindow::showPreferencesDialog); |
2855 | connect(packet_dialog, SIGNAL(editProtocolPreference(preference*, pref_module*))qFlagLocation("2""editProtocolPreference(preference*, pref_module*)" "\0" "ui/qt/wireshark_main_window_slots.cpp" ":" "2855"), |
2856 | main_ui_->preferenceEditorFrame, SLOT(editPreference(preference*, pref_module*))qFlagLocation("1""editPreference(preference*, pref_module*)" "\0" "ui/qt/wireshark_main_window_slots.cpp" ":" "2856")); |
2857 | |
2858 | connect(this, &WiresharkMainWindow::closePacketDialogs, packet_dialog, &PacketDialog::close); |
2859 | zoomText(); // Emits mainApp->zoomMonospaceFont(QFont) |
2860 | |
2861 | packet_dialog->show(); |
2862 | } |
2863 | } |
2864 | |
2865 | void WiresharkMainWindow::reloadCaptureFileAsFormatOrCapture() |
2866 | { |
2867 | capture_file *cf = CaptureFile::globalCapFile(); |
2868 | |
2869 | if (cf->unsaved_changes) { |
2870 | QString before_what(tr(" before reloading the file")); |
2871 | if (!testCaptureFileClose(before_what, Reload)) |
2872 | return; |
2873 | } |
2874 | |
2875 | if (cf->open_type == WTAP_TYPE_AUTO0) |
2876 | cf->open_type = open_info_name_to_type("MIME Files Format"); |
2877 | else /* TODO: This should be latest format chosen by user */ |
2878 | cf->open_type = WTAP_TYPE_AUTO0; |
2879 | |
2880 | cf_reload(cf); |
2881 | } |
2882 | |
2883 | void WiresharkMainWindow::reloadCaptureFile() |
2884 | { |
2885 | capture_file *cf = CaptureFile::globalCapFile(); |
2886 | |
2887 | if (cf->unsaved_changes) { |
2888 | QString before_what(tr(" before reloading the file")); |
2889 | if (!testCaptureFileClose(before_what, Reload)) |
2890 | return; |
2891 | } |
2892 | |
2893 | cf_reload(cf); |
2894 | } |
2895 | |
2896 | |
2897 | // Expand / collapse slots in proto_tree |
2898 | |
2899 | // Go Menu |
2900 | |
2901 | void WiresharkMainWindow::connectGoMenuActions() |
2902 | { |
2903 | connect(main_ui_->actionGoGoToPacket, &QAction::triggered, this, [this]() { |
2904 | if (! packet_list_->model() || packet_list_->model()->rowCount() < 1) { |
2905 | return; |
2906 | } |
2907 | setPreviousFocus(); |
2908 | |
2909 | showAccordionFrame(main_ui_->goToFrame, true); |
2910 | if (main_ui_->goToFrame->isVisible()) { |
2911 | main_ui_->goToLineEdit->clear(); |
2912 | main_ui_->goToLineEdit->setFocus(); |
2913 | } |
2914 | }); |
2915 | |
2916 | connect(main_ui_->actionGoGoToLinkedPacket, &QAction::triggered, this, [this]() { |
2917 | QAction *gta = qobject_cast<QAction*>(sender()); |
2918 | if (!gta) return; |
2919 | |
2920 | bool ok = false; |
2921 | int packet_num = gta->data().toInt(&ok); |
2922 | if (!ok) return; |
2923 | |
2924 | packet_list_->goToPacket(packet_num); |
2925 | }); |
2926 | |
2927 | connect(main_ui_->actionGoNextPacket, &QAction::triggered, |
2928 | packet_list_, &PacketList::goNextPacket); |
2929 | |
2930 | connect(main_ui_->actionGoPreviousPacket, &QAction::triggered, |
2931 | packet_list_, &PacketList::goPreviousPacket); |
2932 | |
2933 | connect(main_ui_->actionGoFirstPacket, &QAction::triggered, |
2934 | packet_list_, &PacketList::goFirstPacket); |
2935 | |
2936 | connect(main_ui_->actionGoLastPacket, &QAction::triggered, |
2937 | packet_list_, &PacketList::goLastPacket); |
2938 | |
2939 | connect(main_ui_->actionGoNextConversationPacket, &QAction::triggered, this, |
2940 | [this]() { goToConversationFrame(true); }); |
2941 | |
2942 | connect(main_ui_->actionGoPreviousConversationPacket, &QAction::triggered, this, |
2943 | [this]() { goToConversationFrame(false); }); |
2944 | |
2945 | connect(main_ui_->actionGoNextHistoryPacket, &QAction::triggered, |
2946 | packet_list_, &PacketList::goNextHistoryPacket); |
2947 | |
2948 | connect(main_ui_->actionGoPreviousHistoryPacket, &QAction::triggered, |
2949 | packet_list_, &PacketList::goPreviousHistoryPacket); |
2950 | |
2951 | // triggered is whenever the user clicks the button; save that as |
2952 | // the new recent value |
2953 | connect(main_ui_->actionGoAutoScroll, &QAction::triggered, this, |
2954 | [](bool checked) { recent.capture_auto_scroll = checked; }); |
2955 | |
2956 | // toggled is whenever the value changes; if it changes programmatically |
2957 | // (e.g., the user scrolls upwards so we stop auto scrolling) change |
2958 | // whether the button is checked but don't save value to recent (it's |
2959 | // a temporary change) |
2960 | connect(main_ui_->actionGoAutoScroll, &QAction::toggled, this, |
2961 | [this](bool checked) { packet_list_->setVerticalAutoScroll(checked); }); |
2962 | } |
2963 | |
2964 | void WiresharkMainWindow::goToConversationFrame(bool go_next) { |
2965 | char *filter = NULL__null; |
2966 | dfilter_t *dfcode = NULL__null; |
2967 | bool found_packet = false; |
2968 | packet_info *pi = capture_file_.packetInfo(); |
2969 | |
2970 | if (!pi) { |
2971 | // No packet was selected, or multiple packets were selected. |
2972 | return; |
2973 | } |
2974 | |
2975 | /* Try to build a conversation |
2976 | * filter in the order TCP, UDP, IP, Ethernet and apply the |
2977 | * coloring */ |
2978 | filter = conversation_filter_from_packet(pi); |
2979 | if (filter == NULL__null) { |
2980 | mainApp->pushStatus(WiresharkApplication::TemporaryStatus, tr("Unable to build conversation filter.")); |
2981 | g_free(filter); |
2982 | return; |
2983 | } |
2984 | |
2985 | if (!dfilter_compile(filter, &dfcode, NULL)dfilter_compile_full(filter, &dfcode, __null, (1U << 1)|(1U << 2), __func__)) { |
2986 | /* The attempt failed; report an error. */ |
2987 | mainApp->pushStatus(WiresharkApplication::TemporaryStatus, tr("Error compiling filter for this conversation.")); |
2988 | g_free(filter); |
2989 | return; |
2990 | } |
2991 | |
2992 | found_packet = cf_find_packet_dfilter(capture_file_.capFile(), dfcode, go_next ? SD_FORWARD : SD_BACKWARD); |
2993 | |
2994 | if (!found_packet) { |
2995 | /* We didn't find a packet */ |
2996 | mainApp->pushStatus(WiresharkApplication::TemporaryStatus, tr("No previous/next packet in conversation.")); |
2997 | } |
2998 | |
2999 | dfilter_free(dfcode); |
3000 | g_free(filter); |
3001 | } |
3002 | |
3003 | // Capture Menu |
3004 | |
3005 | void WiresharkMainWindow::connectCaptureMenuActions() |
3006 | { |
3007 | #ifdef HAVE_LIBPCAP1 |
3008 | connect(main_ui_->actionCaptureOptions, &QAction::triggered, this, |
3009 | [this]() { showCaptureOptionsDialog(); }); |
3010 | #endif |
3011 | |
3012 | connect(main_ui_->actionCaptureStart, &QAction::triggered, this, |
3013 | [this]() { startCaptureTriggered(); }); |
3014 | |
3015 | connect(main_ui_->actionCaptureStop, &QAction::triggered, this, |
3016 | [this]() { stopCapture(); }); |
3017 | |
3018 | #ifdef HAVE_LIBPCAP1 |
3019 | connect(main_ui_->actionCaptureRestart, &QAction::triggered, this, [this]() { |
3020 | QString before_what(tr(" before restarting the capture")); |
3021 | cap_session_.capture_opts->restart = true; |
3022 | if (!testCaptureFileClose(before_what, Restart)) { |
3023 | return; |
3024 | } |
3025 | startCapture(QStringList()); |
3026 | }); |
3027 | #endif // HAVE_LIBPCAP |
3028 | |
3029 | connect(main_ui_->actionCaptureCaptureFilters, &QAction::triggered, this, [this]() { |
3030 | FilterDialog *capture_filter_dlg = new FilterDialog(window(), FilterDialog::CaptureFilter); |
3031 | capture_filter_dlg->setWindowModality(Qt::ApplicationModal); |
3032 | capture_filter_dlg->setAttribute(Qt::WA_DeleteOnClose); |
3033 | capture_filter_dlg->show(); |
3034 | }); |
3035 | |
3036 | #ifdef HAVE_LIBPCAP1 |
3037 | connect(main_ui_->actionCaptureRefreshInterfaces, &QAction::triggered, this, [this]() { |
3038 | main_ui_->actionCaptureRefreshInterfaces->setEnabled(false); |
3039 | mainApp->refreshLocalInterfaces(); |
3040 | main_ui_->actionCaptureRefreshInterfaces->setEnabled(true); |
3041 | }); |
3042 | #endif |
3043 | } |
3044 | |
3045 | void WiresharkMainWindow::showCaptureOptionsDialog() |
3046 | { |
3047 | #ifdef HAVE_LIBPCAP1 |
3048 | if (!capture_options_dialog_) { |
3049 | capture_options_dialog_ = new CaptureOptionsDialog(this); |
3050 | |
3051 | connect(capture_options_dialog_, &CaptureOptionsDialog::startCapture, this, [this]() { startCapture(); }); |
3052 | connect(capture_options_dialog_, &CaptureOptionsDialog::stopCapture, this, &WiresharkMainWindow::stopCapture); |
3053 | |
3054 | connect(capture_options_dialog_, &CaptureOptionsDialog::interfacesChanged, |
3055 | this->welcome_page_, &WelcomePage::interfaceSelected); |
3056 | connect(capture_options_dialog_, &CaptureOptionsDialog::interfacesChanged, |
3057 | this->welcome_page_->getInterfaceFrame(), &InterfaceFrame::updateSelectedInterfaces); |
3058 | connect(capture_options_dialog_, &CaptureOptionsDialog::interfaceListChanged, |
3059 | this->welcome_page_->getInterfaceFrame(), &InterfaceFrame::interfaceListChanged); |
3060 | connect(capture_options_dialog_, &CaptureOptionsDialog::captureFilterTextEdited, |
3061 | this->welcome_page_, &WelcomePage::setCaptureFilterText); |
3062 | // Propagate selection changes from main UI to dialog. |
3063 | connect(this->welcome_page_, &WelcomePage::interfacesChanged, |
3064 | capture_options_dialog_, &CaptureOptionsDialog::interfaceSelected); |
3065 | |
3066 | connect(capture_options_dialog_, &CaptureOptionsDialog::setFilterValid, |
3067 | this, &WiresharkMainWindow::startInterfaceCapture); |
3068 | |
3069 | connect(capture_options_dialog_, &CaptureOptionsDialog::showExtcapOptions, |
3070 | this, &WiresharkMainWindow::showExtcapOptionsDialog); |
3071 | } |
3072 | capture_options_dialog_->updateInterfaces(); |
3073 | |
3074 | if (capture_options_dialog_->isMinimized()) { |
3075 | capture_options_dialog_->showNormal(); |
3076 | } else { |
3077 | capture_options_dialog_->show(); |
3078 | } |
3079 | |
3080 | capture_options_dialog_->raise(); |
3081 | capture_options_dialog_->activateWindow(); |
3082 | #endif |
3083 | } |
3084 | |
3085 | void WiresharkMainWindow::startCaptureTriggered() |
3086 | { |
3087 | //#ifdef HAVE_AIRPCAP |
3088 | // airpcap_if_active = airpcap_if_selected; |
3089 | // if (airpcap_if_active) |
3090 | // airpcap_set_toolbar_start_capture(airpcap_if_active); |
3091 | //#endif |
3092 | |
3093 | // if (cap_open_w) { |
3094 | // /* |
3095 | // * There's an options dialog; get the values from it and close it. |
3096 | // */ |
3097 | // bool success; |
3098 | |
3099 | // /* Determine if "capture start" while building of the "capture options" window */ |
3100 | // /* is in progress. If so, ignore the "capture start. */ |
3101 | // /* XXX: Would it be better/cleaner for the "capture options" window code to */ |
3102 | // /* disable the capture start button temporarily ? */ |
3103 | // if (cap_open_complete == false) { |
3104 | // return; /* Building options window: ignore "capture start" */ |
3105 | // } |
3106 | // success = capture_dlg_prep(cap_open_w); |
3107 | // window_destroy(GTK_WIDGET(cap_open_w)); |
3108 | // if (!success) |
3109 | // return; /* error in options dialog */ |
3110 | // } |
3111 | |
3112 | #ifdef HAVE_LIBPCAP1 |
3113 | if (global_capture_opts.num_selected == 0) { |
3114 | QString err_msg = tr("No Interface Selected."); |
3115 | mainApp->pushStatus(WiresharkApplication::TemporaryStatus, err_msg); |
3116 | main_ui_->actionCaptureStart->setChecked(false); |
3117 | return; |
3118 | } |
3119 | |
3120 | /* XXX - will closing this remove a temporary file? */ |
3121 | QString before_what(tr(" before starting a new capture")); |
3122 | if (testCaptureFileClose(before_what)) { |
3123 | startCapture(QStringList()); |
3124 | } else { |
3125 | // simply clicking the button sets it to 'checked' even though we've |
3126 | // decided to do nothing, so undo that |
3127 | main_ui_->actionCaptureStart->setChecked(false); |
3128 | } |
3129 | #endif // HAVE_LIBPCAP |
3130 | } |
3131 | |
3132 | // Analyze Menu |
3133 | |
3134 | struct epan_uat; |
3135 | |
3136 | void WiresharkMainWindow::connectAnalyzeMenuActions() |
3137 | { |
3138 | connect(main_ui_->actionAnalyzeDisplayFilters, &QAction::triggered, this, [=]() { |
3139 | FilterDialog *display_filter_dlg = new FilterDialog(window(), FilterDialog::DisplayFilter); |
3140 | display_filter_dlg->setWindowModality(Qt::ApplicationModal); |
3141 | display_filter_dlg->setAttribute(Qt::WA_DeleteOnClose); |
3142 | display_filter_dlg->show(); |
3143 | }); |
3144 | |
3145 | connect(main_ui_->actionAnalyzeDisplayFilterMacros, &QAction::triggered, this, [=]() { |
3146 | FilterDialog *display_filter_dlg = new FilterDialog(window(), FilterDialog::DisplayMacro); |
3147 | display_filter_dlg->setWindowModality(Qt::ApplicationModal); |
3148 | display_filter_dlg->setAttribute(Qt::WA_DeleteOnClose); |
3149 | display_filter_dlg->show(); |
3150 | }); |
3151 | |
3152 | connect(main_ui_->actionDisplayFilterExpression, &QAction::triggered, this, [=]() { |
3153 | DisplayFilterExpressionDialog *dfe_dialog = new DisplayFilterExpressionDialog(this); |
3154 | |
3155 | connect(dfe_dialog, &DisplayFilterExpressionDialog::insertDisplayFilter, |
3156 | qobject_cast<SyntaxLineEdit *>(df_combo_box_->lineEdit()), &SyntaxLineEdit::insertFilter); |
3157 | |
3158 | dfe_dialog->show(); |
3159 | }); |
3160 | |
3161 | connect(main_ui_->actionAnalyzeApplyAsColumn, &QAction::triggered, this, &WiresharkMainWindow::applyFieldAsColumn); |
3162 | |
3163 | connect(main_ui_->actionAnalyzeEnabledProtocols, &QAction::triggered, this, [=]() { |
3164 | EnabledProtocolsDialog *enable_proto_dialog = new EnabledProtocolsDialog(this); |
3165 | connect(enable_proto_dialog, &EnabledProtocolsDialog::destroyed, mainApp, &MainApplication::flushAppSignals); |
3166 | |
3167 | enable_proto_dialog->setWindowModality(Qt::ApplicationModal); |
3168 | enable_proto_dialog->setAttribute(Qt::WA_DeleteOnClose); |
3169 | enable_proto_dialog->show(); |
3170 | }); |
3171 | |
3172 | connect(main_ui_->actionAnalyzeDecodeAs, &QAction::triggered, this, [=]() { |
3173 | QAction *da_action = qobject_cast<QAction*>(sender()); |
3174 | bool create_new = da_action && da_action->property("create_new").toBool(); |
3175 | |
3176 | DecodeAsDialog *da_dialog = new DecodeAsDialog(this, capture_file_.capFile(), create_new); |
3177 | connect(da_dialog, &DecodeAsDialog::destroyed, mainApp, &MainApplication::flushAppSignals); |
3178 | |
3179 | da_dialog->setWindowModality(Qt::ApplicationModal); |
3180 | da_dialog->setAttribute(Qt::WA_DeleteOnClose); |
3181 | da_dialog->show(); |
3182 | }); |
3183 | |
3184 | connect(main_ui_->actionAnalyzeReloadLuaPlugins, &QAction::triggered, this, &WiresharkMainWindow::reloadLuaPlugins); |
3185 | |
3186 | connect(main_ui_->actionAnalyzeShowPacketBytes, &QAction::triggered, this, [=]() { |
3187 | ShowPacketBytesDialog *spbd = new ShowPacketBytesDialog(*this, capture_file_); |
3188 | spbd->addCodecs(text_codec_map_); |
3189 | spbd->show(); |
3190 | }); |
3191 | |
3192 | connect(main_ui_->actionAnalyzeExpertInfo, &QAction::triggered, this, [=]() { |
3193 | statCommandExpertInfo(NULL__null, NULL__null); |
3194 | }); |
3195 | } |
3196 | |
3197 | void WiresharkMainWindow::filterMenuAboutToShow() |
3198 | { |
3199 | QMenu * menu = qobject_cast<QMenu *>(sender()); |
3200 | QString field_filter; |
3201 | |
3202 | if (capture_file_.capFile() && capture_file_.capFile()->finfo_selected) { |
3203 | char *tmp_field = proto_construct_match_selected_string(capture_file_.capFile()->finfo_selected, |
3204 | capture_file_.capFile()->edt); |
3205 | field_filter = QString(tmp_field); |
3206 | wmem_free(NULL__null, tmp_field); |
3207 | } |
3208 | bool enable = ! field_filter.isEmpty(); |
3209 | bool prepare = menu->objectName().compare("menuPrepareAFilter") == 0; |
3210 | |
3211 | menu->clear(); |
3212 | QActionGroup * group = FilterAction::createFilterGroup(field_filter, prepare, enable, menu); |
3213 | menu->addActions(group->actions()); |
3214 | } |
3215 | |
3216 | void WiresharkMainWindow::matchFieldFilter(FilterAction::Action action, FilterAction::ActionType filter_type) |
3217 | { |
3218 | QString field_filter; |
3219 | |
3220 | if (packet_list_->contextMenuActive() || packet_list_->hasFocus()) { |
3221 | field_filter = packet_list_->getFilterFromRowAndColumn(packet_list_->currentIndex()); |
3222 | } else if (capture_file_.capFile() && capture_file_.capFile()->finfo_selected) { |
3223 | char *tmp_field = proto_construct_match_selected_string(capture_file_.capFile()->finfo_selected, |
3224 | capture_file_.capFile()->edt); |
3225 | field_filter = QString(tmp_field); |
3226 | wmem_free(NULL__null, tmp_field); |
3227 | } |
3228 | |
3229 | if (field_filter.isEmpty()) { |
3230 | QString err = tr("No filter available. Try another %1.").arg(packet_list_->contextMenuActive() ? tr("column") : tr("item")); |
3231 | mainApp->pushStatus(WiresharkApplication::TemporaryStatus, err); |
3232 | return; |
3233 | } |
3234 | |
3235 | setDisplayFilter(field_filter, action, filter_type); |
3236 | } |
3237 | |
3238 | void WiresharkMainWindow::applyFieldAsColumn() |
3239 | { |
3240 | if (capture_file_.capFile() != 0 && capture_file_.capFile()->finfo_selected != 0) { |
3241 | const header_field_info *hfinfo = capture_file_.capFile()->finfo_selected->hfinfo; |
3242 | int col = column_prefs_has_custom(hfinfo->abbrev); |
3243 | if (col == -1) { |
3244 | insertColumn(hfinfo->name, hfinfo->abbrev); |
3245 | } else { |
3246 | QString status; |
3247 | if (QString(hfinfo->name) == get_column_title(col)) { |
3248 | status = tr("The \"%1\" column already exists.").arg(hfinfo->name); |
3249 | } else { |
3250 | status = tr("The \"%1\" column already exists as \"%2\".").arg(hfinfo->name).arg(get_column_title(col)); |
3251 | } |
3252 | mainApp->pushStatus(WiresharkApplication::TemporaryStatus, status); |
3253 | |
3254 | if (!get_column_visible(col)) { |
3255 | packet_list_->setColumnHidden(col, false); |
3256 | set_column_visible(col, true); |
3257 | prefs_main_write(); |
3258 | } |
3259 | } |
3260 | } |
3261 | } |
3262 | |
3263 | void WiresharkMainWindow::applyConversationFilter() |
3264 | { |
3265 | ConversationAction *conv_action = qobject_cast<ConversationAction*>(sender()); |
3266 | if (!conv_action) return; |
3267 | |
3268 | packet_info *pinfo = capture_file_.packetInfo(); |
3269 | if (!pinfo) return; |
3270 | |
3271 | QByteArray conv_filter = conv_action->filter(); |
3272 | if (conv_filter.isEmpty()) return; |
3273 | |
3274 | if (conv_action->isFilterValid(pinfo)) { |
3275 | |
3276 | df_combo_box_->lineEdit()->setText(conv_filter); |
3277 | df_combo_box_->applyDisplayFilter(); |
3278 | } |
3279 | } |
3280 | |
3281 | void WiresharkMainWindow::applyExportObject() |
3282 | { |
3283 | ExportObjectAction *export_action = qobject_cast<ExportObjectAction*>(sender()); |
3284 | if (!export_action) |
3285 | return; |
3286 | |
3287 | ExportObjectDialog* export_dialog = new ExportObjectDialog(*this, capture_file_, export_action->exportObject()); |
3288 | export_dialog->setWindowModality(Qt::ApplicationModal); |
3289 | export_dialog->setAttribute(Qt::WA_DeleteOnClose); |
3290 | export_dialog->show(); |
3291 | } |
3292 | |
3293 | void WiresharkMainWindow::openFollowStreamDialog(int proto_id, unsigned stream_num, unsigned sub_stream_num, bool use_stream_index) { |
3294 | FollowStreamDialog *fsd = new FollowStreamDialog(*this, capture_file_, proto_id); |
3295 | connect(fsd, &FollowStreamDialog::updateFilter, this, &WiresharkMainWindow::filterPackets); |
3296 | connect(fsd, &FollowStreamDialog::goToPacket, this, [=](int packet_num) {packet_list_->goToPacket(packet_num);}); |
3297 | fsd->addCodecs(text_codec_map_); |
3298 | fsd->show(); |
3299 | if (use_stream_index) { |
3300 | // If a specific conversation was requested, then ignore any previous |
3301 | // display filters and display all related packets. |
3302 | fsd->follow("", true, stream_num, sub_stream_num); |
3303 | } else { |
3304 | fsd->follow(getFilter()); |
3305 | } |
3306 | } |
3307 | |
3308 | void WiresharkMainWindow::openFollowStreamDialog(int proto_id) { |
3309 | openFollowStreamDialog(proto_id, 0, 0, false); |
3310 | } |
3311 | |
3312 | void WiresharkMainWindow::openSCTPAllAssocsDialog() |
3313 | { |
3314 | SCTPAllAssocsDialog *sctp_dialog = new SCTPAllAssocsDialog(this, capture_file_.capFile()); |
3315 | connect(sctp_dialog, &SCTPAllAssocsDialog::filterPackets, this, &WiresharkMainWindow::filterPackets); |
3316 | connect(this, &WiresharkMainWindow::setCaptureFile, sctp_dialog, &SCTPAllAssocsDialog::setCaptureFile); |
3317 | sctp_dialog->fillTable(); |
3318 | |
3319 | if (sctp_dialog->isMinimized() == true) |
3320 | { |
3321 | sctp_dialog->showNormal(); |
3322 | } |
3323 | else |
3324 | { |
3325 | sctp_dialog->show(); |
3326 | } |
3327 | |
3328 | sctp_dialog->raise(); |
3329 | sctp_dialog->activateWindow(); |
3330 | } |
3331 | |
3332 | void WiresharkMainWindow::on_actionSCTPShowAllAssociations_triggered() |
3333 | { |
3334 | openSCTPAllAssocsDialog(); |
3335 | } |
3336 | |
3337 | void WiresharkMainWindow::on_actionSCTPAnalyseThisAssociation_triggered() |
3338 | { |
3339 | const sctp_assoc_info_t* assoc = SCTPAssocAnalyseDialog::findAssocForPacket(capture_file_.capFile()); |
3340 | if (!assoc) { |
3341 | return; |
3342 | } |
3343 | SCTPAssocAnalyseDialog *sctp_analyse = new SCTPAssocAnalyseDialog(this, assoc, capture_file_.capFile()); |
3344 | connect(sctp_analyse, &SCTPAssocAnalyseDialog::filterPackets, this, &WiresharkMainWindow::filterPackets); |
3345 | |
3346 | if (sctp_analyse->isMinimized() == true) |
3347 | { |
3348 | sctp_analyse->showNormal(); |
3349 | } |
3350 | else |
3351 | { |
3352 | sctp_analyse->show(); |
3353 | } |
3354 | |
3355 | sctp_analyse->raise(); |
3356 | sctp_analyse->activateWindow(); |
3357 | } |
3358 | |
3359 | void WiresharkMainWindow::on_actionSCTPFilterThisAssociation_triggered() |
3360 | { |
3361 | const sctp_assoc_info_t* assoc = SCTPAssocAnalyseDialog::findAssocForPacket(capture_file_.capFile()); |
3362 | if (assoc) { |
3363 | QString newFilter = QString("sctp.assoc_index==%1").arg(assoc->assoc_id); |
3364 | assoc = NULL__null; |
3365 | emit filterPackets(newFilter, false); |
3366 | } |
3367 | } |
3368 | |
3369 | // -z wlan,stat |
3370 | void WiresharkMainWindow::statCommandWlanStatistics(const char *arg, void *) |
3371 | { |
3372 | WlanStatisticsDialog *wlan_stats_dlg = new WlanStatisticsDialog(*this, capture_file_, arg); |
3373 | wlan_stats_dlg->show(); |
3374 | connect(wlan_stats_dlg, &WlanStatisticsDialog::filterAction, this, &WiresharkMainWindow::filterAction); |
3375 | } |
3376 | |
3377 | // -z expert |
3378 | void WiresharkMainWindow::statCommandExpertInfo(const char *, void *) |
3379 | { |
3380 | const DisplayFilterEdit *df_edit = dynamic_cast<DisplayFilterEdit *>(df_combo_box_->lineEdit()); |
3381 | ExpertInfoDialog *expert_dialog = new ExpertInfoDialog(*this, capture_file_, df_edit->text()); |
3382 | |
3383 | connect(expert_dialog->getExpertInfoView(), &ExpertInfoTreeView::goToPacket, |
3384 | this, [=](int packet_num) {packet_list_->goToPacket(packet_num);}); |
3385 | connect(expert_dialog, &ExpertInfoDialog::filterAction, this, &WiresharkMainWindow::filterAction); |
3386 | |
3387 | expert_dialog->show(); |
3388 | } |
3389 | |
3390 | |
3391 | // Next / previous / first / last slots in packet_list |
3392 | |
3393 | // Statistics Menu |
3394 | |
3395 | void WiresharkMainWindow::connectStatisticsMenuActions() |
3396 | { |
3397 | connect(main_ui_->actionStatisticsCaptureFileProperties, &QAction::triggered, this, [=]() { |
3398 | CaptureFilePropertiesDialog *capture_file_properties_dialog = new CaptureFilePropertiesDialog(*this, capture_file_); |
3399 | connect(capture_file_properties_dialog, &CaptureFilePropertiesDialog::captureCommentChanged, |
3400 | this, &WiresharkMainWindow::updateForUnsavedChanges); |
3401 | capture_file_properties_dialog->show(); |
3402 | }); |
3403 | |
3404 | connect(main_ui_->actionStatisticsResolvedAddresses, &QAction::triggered, this, &WiresharkMainWindow::showResolvedAddressesDialog); |
3405 | |
3406 | connect(main_ui_->actionStatisticsProtocolHierarchy, &QAction::triggered, this, [=]() { |
3407 | ProtocolHierarchyDialog *phd = new ProtocolHierarchyDialog(*this, capture_file_); |
3408 | connect(phd, &ProtocolHierarchyDialog::filterAction, this, &WiresharkMainWindow::filterAction); |
3409 | phd->show(); |
3410 | }); |
3411 | |
3412 | connect(main_ui_->actionStatisticsConversations, &QAction::triggered, this, &WiresharkMainWindow::showConversationsDialog); |
3413 | connect(main_ui_->actionStatisticsEndpoints, &QAction::triggered, this, &WiresharkMainWindow::showEndpointsDialog); |
3414 | |
3415 | connect(main_ui_->actionStatisticsPacketLengths, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("plen"); }); |
3416 | |
3417 | connect(main_ui_->actionStatisticsIOGraph, &QAction::triggered, this, [=]() { statCommandIOGraph(NULL__null, NULL__null); }); |
3418 | |
3419 | connect(main_ui_->actionStatisticsFlowGraph, &QAction::triggered, this, [=]() { |
3420 | SequenceDialog *sequence_dialog = new SequenceDialog(*this, capture_file_); |
3421 | sequence_dialog->show(); |
3422 | }); |
3423 | |
3424 | connect(main_ui_->actionStatisticsCollectd, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("collectd"); }); |
3425 | connect(main_ui_->actionStatisticsDNS, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("dns"); }); |
3426 | connect(main_ui_->actionStatisticsDNS_QR, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("dns_qr"); }); |
3427 | connect(main_ui_->actionStatisticsHART_IP, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("hart_ip"); }); |
3428 | connect(main_ui_->actionStatisticsHpfeeds, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("hpfeeds"); }); |
3429 | connect(main_ui_->actionStatisticsHTTP2, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("http2"); }); |
3430 | connect(main_ui_->actionStatisticsUdpMulticastStreams, &QAction::triggered, this, [=]() { statCommandMulticastStatistics(NULL__null, NULL__null); }); |
3431 | |
3432 | connect(main_ui_->actionStatistics29WestTopics_Advertisem*nts_by_Topic, &QAction::triggered, this, [=]() { |
3433 | openStatisticsTreeDialog("lbmr_topic_ads_topic"); |
3434 | }); |
3435 | |
3436 | connect(main_ui_->actionStatistics29WestTopics_Advertisem*nts_by_Source, &QAction::triggered, this, [=]() { |
3437 | openStatisticsTreeDialog("lbmr_topic_ads_source"); |
3438 | }); |
3439 | |
3440 | connect(main_ui_->actionStatistics29WestTopics_Advertisem*nts_by_Transport, &QAction::triggered, this, [=]() { |
3441 | openStatisticsTreeDialog("lbmr_topic_ads_transport"); |
3442 | }); |
3443 | |
3444 | connect(main_ui_->actionStatistics29WestTopics_Queries_by_Topic, &QAction::triggered, this, [=]() { |
3445 | openStatisticsTreeDialog("lbmr_topic_queries_topic"); |
3446 | }); |
3447 | |
3448 | connect(main_ui_->actionStatistics29WestTopics_Queries_by_Receiver, &QAction::triggered, this, [=]() { |
3449 | openStatisticsTreeDialog("lbmr_topic_queries_receiver"); |
3450 | }); |
3451 | |
3452 | connect(main_ui_->actionStatistics29WestTopics_Wildcard_Queries_by_Pattern, &QAction::triggered, this, [=]() { |
3453 | openStatisticsTreeDialog("lbmr_topic_queries_pattern"); |
3454 | }); |
3455 | |
3456 | connect(main_ui_->actionStatistics29WestTopics_Wildcard_Queries_by_Receiver, &QAction::triggered, this, [=]() { |
3457 | openStatisticsTreeDialog("lbmr_topic_queries_pattern_receiver"); |
3458 | }); |
3459 | |
3460 | connect(main_ui_->actionStatistics29WestQueues_Advertisem*nts_by_Queue, &QAction::triggered, this, [=]() { |
3461 | openStatisticsTreeDialog("lbmr_queue_ads_queue"); |
3462 | }); |
3463 | |
3464 | connect(main_ui_->actionStatistics29WestQueues_Advertisem*nts_by_Source, &QAction::triggered, this, [=]() { |
3465 | openStatisticsTreeDialog("lbmr_queue_ads_source"); |
3466 | }); |
3467 | |
3468 | connect(main_ui_->actionStatistics29WestQueues_Queries_by_Queue, &QAction::triggered, this, [=]() { |
3469 | openStatisticsTreeDialog("lbmr_queue_queries_queue"); |
3470 | }); |
3471 | |
3472 | connect(main_ui_->actionStatistics29WestQueues_Queries_by_Receiver, &QAction::triggered, this, [=]() { |
3473 | openStatisticsTreeDialog("lbmr_queue_queries_receiver"); |
3474 | }); |
3475 | |
3476 | connect(main_ui_->actionStatistics29WestUIM_Streams, &QAction::triggered, this, [=]() { |
3477 | LBMStreamDialog *stream_dialog = new LBMStreamDialog(this, capture_file_.capFile()); |
3478 | // connect(stream_dialog, &LBMStreamDialog::goToPacket, packet_list_, &PacketList::goToPacket); |
3479 | connect(this, &WiresharkMainWindow::setCaptureFile, stream_dialog, &LBMStreamDialog::setCaptureFile); |
3480 | stream_dialog->show(); |
3481 | }); |
3482 | |
3483 | connect(main_ui_->actionStatistics29WestLBTRM, &QAction::triggered, this, [=]() { |
3484 | LBMLBTRMTransportDialog * lbtrm_dialog = new LBMLBTRMTransportDialog(this, capture_file_.capFile()); |
3485 | connect(lbtrm_dialog, &LBMLBTRMTransportDialog::goToPacket, this, [=](int packet_num) {packet_list_->goToPacket(packet_num);}); |
3486 | connect(this, &WiresharkMainWindow::setCaptureFile, lbtrm_dialog, &LBMLBTRMTransportDialog::setCaptureFile); |
3487 | lbtrm_dialog->show(); |
3488 | }); |
3489 | |
3490 | connect(main_ui_->actionStatistics29WestLBTRU, &QAction::triggered, this, [=]() { |
3491 | LBMLBTRUTransportDialog * lbtru_dialog = new LBMLBTRUTransportDialog(this, capture_file_.capFile()); |
3492 | connect(lbtru_dialog, &LBMLBTRUTransportDialog::goToPacket, this, [=](int packet_num) {packet_list_->goToPacket(packet_num);}); |
3493 | connect(this, &WiresharkMainWindow::setCaptureFile, lbtru_dialog, &LBMLBTRUTransportDialog::setCaptureFile); |
3494 | lbtru_dialog->show(); |
3495 | }); |
3496 | |
3497 | connect(main_ui_->actionStatisticsTcpStreamStevens, &QAction::triggered, this, [=]() { openTcpStreamDialog(GRAPH_TSEQ_STEVENS); }); |
3498 | connect(main_ui_->actionStatisticsTcpStreamTcptrace, &QAction::triggered, this, [=]() { openTcpStreamDialog(GRAPH_TSEQ_TCPTRACE); }); |
3499 | connect(main_ui_->actionStatisticsTcpStreamThroughput, &QAction::triggered, this, [=]() { openTcpStreamDialog(GRAPH_THROUGHPUT); }); |
3500 | connect(main_ui_->actionStatisticsTcpStreamRoundTripTime, &QAction::triggered, this, [=]() { openTcpStreamDialog(GRAPH_RTT); }); |
3501 | connect(main_ui_->actionStatisticsTcpStreamWindowScaling, &QAction::triggered, this, [=]() { openTcpStreamDialog(GRAPH_WSCALE); }); |
3502 | |
3503 | connect(main_ui_->actionStatisticsANCP, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("ancp"); }); |
3504 | |
3505 | connect(main_ui_->actionStatisticsBACappInstanceId, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("bacapp_instanceid"); }); |
3506 | connect(main_ui_->actionStatisticsBACappIP, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("bacapp_ip"); }); |
3507 | connect(main_ui_->actionStatisticsBACappObjectId, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("bacapp_objectid"); }); |
3508 | connect(main_ui_->actionStatisticsBACappService, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("bacapp_service"); }); |
3509 | |
3510 | connect(main_ui_->actionStatisticsHTTPPacketCounter, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("http"); }); |
3511 | connect(main_ui_->actionStatisticsHTTPRequests, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("http_req"); }); |
3512 | connect(main_ui_->actionStatisticsHTTPLoadDistribution, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("http_srv"); }); |
3513 | connect(main_ui_->actionStatisticsHTTPRequestSequences, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("http_seq"); }); |
3514 | |
3515 | connect(main_ui_->actionStatisticsSametime, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("sametime"); }); |
3516 | |
3517 | connect(main_ui_->actionStatisticsSOMEIPmessages, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("someip_messages"); }); |
3518 | connect(main_ui_->actionStatisticsSOMEIPSDentries, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("someipsd_entries"); }); |
3519 | |
3520 | connect(main_ui_->actionStatisticsLTP, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("ltp"); }); |
3521 | } |
3522 | |
3523 | void WiresharkMainWindow::openTcpStreamDialog(int graph_type) |
3524 | { |
3525 | TCPStreamDialog *stream_dialog = new TCPStreamDialog(this, capture_file_.capFile(), (tcp_graph_type)graph_type); |
3526 | connect(stream_dialog, &TCPStreamDialog::goToPacket, this, [=](int packet_num) {packet_list_->goToPacket(packet_num);}); |
3527 | connect(this, &WiresharkMainWindow::setCaptureFile, stream_dialog, &TCPStreamDialog::setCaptureFile); |
3528 | if (stream_dialog->result() == QDialog::Accepted) { |
3529 | stream_dialog->show(); |
3530 | } |
3531 | } |
3532 | |
3533 | // -z mcast,stat |
3534 | void WiresharkMainWindow::statCommandMulticastStatistics(const char *arg, void *) |
3535 | { |
3536 | MulticastStatisticsDialog *mcast_stats_dlg = new MulticastStatisticsDialog(*this, capture_file_, arg); |
3537 | connect(mcast_stats_dlg, &MulticastStatisticsDialog::filterAction, this, &WiresharkMainWindow::filterAction); |
3538 | mcast_stats_dlg->show(); |
3539 | } |
3540 | |
3541 | void WiresharkMainWindow::openStatisticsTreeDialog(const char *abbr) |
3542 | { |
3543 | StatsTreeDialog *st_dialog = new StatsTreeDialog(*this, capture_file_, abbr); |
3544 | // connect(st_dialog, &StatsTreeDialog::goToPacket, packet_list_, &PacketList::goToPacket); |
3545 | st_dialog->show(); |
3546 | } |
3547 | |
3548 | // -z io,stat |
3549 | void WiresharkMainWindow::statCommandIOGraph(const char *, void *) |
3550 | { |
3551 | showIOGraphDialog(IOG_ITEM_UNIT_PACKETS, QString()); |
3552 | } |
3553 | |
3554 | void WiresharkMainWindow::showIOGraphDialog(io_graph_item_unit_t value_units, QString yfield) |
3555 | { |
3556 | const DisplayFilterEdit *df_edit = qobject_cast<DisplayFilterEdit *>(df_combo_box_->lineEdit()); |
3557 | IOGraphDialog *iog_dialog = nullptr; |
3558 | QString displayFilter; |
3559 | if (df_edit) |
3560 | displayFilter = df_edit->text(); |
3561 | |
3562 | if (!yfield.isEmpty()) { |
3563 | QList<IOGraphDialog *> iographdialogs = findChildren<IOGraphDialog *>(); |
3564 | // GeometryStateDialogs aren't parented on Linux and Windows |
3565 | // (see geometry_state_dialog.h), so we search for an |
3566 | // I/O Dialog in all the top level widgets. |
3567 | if (iographdialogs.isEmpty()) { |
3568 | foreach(QWidget *topLevelWidget, mainApp->topLevelWidgets())for (auto _container_3568 = QtPrivate::qMakeForeachContainer( mainApp->topLevelWidgets()); _container_3568.i != _container_3568 .e; ++_container_3568.i) if (QWidget *topLevelWidget = *_container_3568 .i; false) {} else { |
3569 | if (qobject_cast<IOGraphDialog*>(topLevelWidget)) { |
3570 | iographdialogs << qobject_cast<IOGraphDialog*>(topLevelWidget); |
3571 | } |
3572 | } |
3573 | } |
3574 | bool iog_found = false; |
3575 | foreach(iog_dialog, iographdialogs)for (auto _container_3575 = QtPrivate::qMakeForeachContainer( iographdialogs); _container_3575.i != _container_3575.e; ++_container_3575 .i) if (iog_dialog = *_container_3575.i; false) {} else { |
3576 | if (!iog_dialog->fileClosed()) { |
3577 | iog_found = true; |
3578 | iog_dialog->addGraph(true, displayFilter, value_units, yfield); |
3579 | break; |
3580 | } |
3581 | } |
3582 | if (!iog_found) { |
3583 | iog_dialog = nullptr; |
3584 | } |
3585 | } |
3586 | |
3587 | if (iog_dialog == nullptr) { |
3588 | iog_dialog = new IOGraphDialog(*this, capture_file_, displayFilter, value_units, yfield); |
3589 | connect(iog_dialog, &IOGraphDialog::goToPacket, this, [=](int packet_num) {packet_list_->goToPacket(packet_num);}); |
3590 | connect(this, &WiresharkMainWindow::reloadFields, iog_dialog, &IOGraphDialog::reloadFields); |
3591 | } |
3592 | if (iog_dialog->isMinimized()) { |
3593 | iog_dialog->showNormal(); |
3594 | } else { |
3595 | iog_dialog->show(); |
3596 | } |
3597 | iog_dialog->raise(); |
3598 | iog_dialog->activateWindow(); |
3599 | } |
3600 | |
3601 | // Telephony Menu |
3602 | |
3603 | void WiresharkMainWindow::connectTelephonyMenuActions() |
3604 | { |
3605 | connect(main_ui_->actionTelephonyVoipCalls, &QAction::triggered, this, [=]() { |
3606 | VoipCallsDialog *dialog = VoipCallsDialog::openVoipCallsDialogVoip(*this, capture_file_, packet_list_); |
3607 | dialog->show(); |
3608 | }); |
3609 | |
3610 | connect(main_ui_->actionTelephonyIax2StreamAnalysis, &QAction::triggered, this, [=]() { |
3611 | Iax2AnalysisDialog *iax2_analysis_dialog = new Iax2AnalysisDialog(*this, capture_file_); |
3612 | connect(iax2_analysis_dialog, &Iax2AnalysisDialog::goToPacket, this, [=](int packet) { packet_list_->goToPacket(packet); }); |
3613 | iax2_analysis_dialog->show(); |
3614 | }); |
3615 | |
3616 | connect(main_ui_->actionTelephonyISUPMessages, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("isup_msg"); }); |
3617 | |
3618 | connect(main_ui_->actionTelephonyGsmMapSummary, &QAction::triggered, this, [=]() { |
3619 | GsmMapSummaryDialog *gms_dialog = new GsmMapSummaryDialog(*this, capture_file_); |
3620 | gms_dialog->show(); |
3621 | }); |
3622 | |
3623 | connect(main_ui_->actionTelephonyLteMacStatistics, &QAction::triggered, this, [=]() { statCommandLteMacStatistics(NULL__null, NULL__null); }); |
3624 | connect(main_ui_->actionTelephonyLteRlcGraph, &QAction::triggered, this, [=]() { |
3625 | // We don't yet know the channel. |
3626 | launchRLCGraph(false, RLC_RAT_LTE0, 0, 0, 0, 0, 0); |
3627 | }); |
3628 | connect(main_ui_->actionTelephonyLteRlcStatistics, &QAction::triggered, this, [=]() { statCommandLteRlcStatistics(NULL__null, NULL__null); }); |
3629 | |
3630 | connect(main_ui_->actionTelephonyMtp3Summary, &QAction::triggered, this, [=]() { |
3631 | Mtp3SummaryDialog *mtp3s_dialog = new Mtp3SummaryDialog(*this, capture_file_); |
3632 | mtp3s_dialog->show(); |
3633 | }); |
3634 | |
3635 | connect(main_ui_->actionTelephonyOsmuxPacketCounter, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("osmux"); }); |
3636 | |
3637 | connect(main_ui_->actionTelephonyRtpStreams, &QAction::triggered, this, &WiresharkMainWindow::openTelephonyRtpStreamsDialog); |
3638 | connect(main_ui_->actionTelephonyRtpStreamAnalysis, &QAction::triggered, this, &WiresharkMainWindow::openRtpStreamAnalysisDialog); |
3639 | connect(main_ui_->actionTelephonyRtpPlayer, &QAction::triggered, this, &WiresharkMainWindow::openRtpPlayerDialog); |
3640 | |
3641 | connect(main_ui_->actionTelephonyRTSPPacketCounter, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("rtsp"); }); |
3642 | |
3643 | connect(main_ui_->actionTelephonySMPPOperations, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("smpp_commands"); }); |
3644 | |
3645 | connect(main_ui_->actionTelephonyUCPMessages, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("ucp_messages"); }); |
3646 | |
3647 | connect(main_ui_->actionTelephonyF1APMessages, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("f1ap"); }); |
3648 | |
3649 | connect(main_ui_->actionTelephonyNGAPMessages, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("ngap"); }); |
3650 | |
3651 | connect(main_ui_->actionTelephonyE2APMessages, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("e2ap"); }); |
3652 | |
3653 | connect(main_ui_->actionTelephonySipFlows, &QAction::triggered, this, [=]() { |
3654 | VoipCallsDialog *dialog = VoipCallsDialog::openVoipCallsDialogSip(*this, capture_file_, packet_list_); |
3655 | dialog->show(); |
3656 | }); |
3657 | } |
3658 | |
3659 | RtpPlayerDialog *WiresharkMainWindow::openTelephonyRtpPlayerDialog() |
3660 | { |
3661 | RtpPlayerDialog *dialog; |
3662 | |
3663 | #ifdef HAVE_LIBPCAP1 |
3664 | dialog = RtpPlayerDialog::openRtpPlayerDialog(*this, capture_file_, packet_list_, captureSession()->state != CAPTURE_STOPPED); |
3665 | #else |
3666 | dialog = RtpPlayerDialog::openRtpPlayerDialog(*this, capture_file_, packet_list_, false); |
3667 | #endif |
3668 | |
3669 | dialog->show(); |
3670 | |
3671 | return dialog; |
3672 | } |
3673 | |
3674 | RtpAnalysisDialog *WiresharkMainWindow::openTelephonyRtpAnalysisDialog() |
3675 | { |
3676 | RtpAnalysisDialog *dialog; |
3677 | |
3678 | dialog = RtpAnalysisDialog::openRtpAnalysisDialog(*this, capture_file_, packet_list_); |
3679 | dialog->show(); |
3680 | |
3681 | return dialog; |
3682 | } |
3683 | |
3684 | // -z mac-3gpp,stat |
3685 | void WiresharkMainWindow::statCommandLteMacStatistics(const char *arg, void *) |
3686 | { |
3687 | LteMacStatisticsDialog *lte_mac_stats_dlg = new LteMacStatisticsDialog(*this, capture_file_, arg); |
3688 | connect(lte_mac_stats_dlg, &LteMacStatisticsDialog::filterAction, this, &WiresharkMainWindow::filterAction); |
3689 | lte_mac_stats_dlg->show(); |
3690 | } |
3691 | |
3692 | void WiresharkMainWindow::statCommandLteRlcStatistics(const char *arg, void *) |
3693 | { |
3694 | LteRlcStatisticsDialog *lte_rlc_stats_dlg = new LteRlcStatisticsDialog(*this, capture_file_, arg); |
3695 | connect(lte_rlc_stats_dlg, &LteRlcStatisticsDialog::filterAction, this, &WiresharkMainWindow::filterAction); |
3696 | // N.B. It is necessary for the RLC Statistics window to launch the RLC graph in this way, to ensure |
3697 | // that the goToPacket() signal/slot connection gets set up... |
3698 | connect(lte_rlc_stats_dlg, &LteRlcStatisticsDialog::launchRLCGraph, this, &WiresharkMainWindow::launchRLCGraph); |
3699 | |
3700 | lte_rlc_stats_dlg->show(); |
3701 | } |
3702 | |
3703 | void WiresharkMainWindow::launchRLCGraph(bool channelKnown, |
3704 | uint8_t RAT, uint16_t ueid, uint8_t rlcMode, |
3705 | uint16_t channelType, uint16_t channelId, uint8_t direction) |
3706 | { |
3707 | LteRlcGraphDialog *lrg_dialog = new LteRlcGraphDialog(*this, capture_file_, channelKnown); |
3708 | connect(lrg_dialog, &LteRlcGraphDialog::goToPacket, this, [=](int packet_num) {packet_list_->goToPacket(packet_num);}); |
3709 | // This is a bit messy, but wanted to hide these parameters from users of |
3710 | // on_actionTelephonyLteRlcGraph_triggered(). |
3711 | if (channelKnown) { |
3712 | lrg_dialog->setChannelInfo(RAT, ueid, rlcMode, channelType, channelId, direction); |
3713 | } |
3714 | lrg_dialog->show(); |
3715 | } |
3716 | |
3717 | RtpStreamDialog *WiresharkMainWindow::openTelephonyRtpStreamsDialog() |
3718 | { |
3719 | RtpStreamDialog *dialog = RtpStreamDialog::openRtpStreamDialog(*this, capture_file_, packet_list_); |
3720 | dialog->show(); |
3721 | |
3722 | return dialog; |
3723 | } |
3724 | |
3725 | void WiresharkMainWindow::openRtpStreamAnalysisDialog() |
3726 | { |
3727 | QVector<rtpstream_id_t *> stream_ids; |
3728 | QString err; |
3729 | |
3730 | if (QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier)) { |
3731 | err = findRtpStreams(&stream_ids, true); |
3732 | } else { |
3733 | err = findRtpStreams(&stream_ids, false); |
3734 | } |
3735 | if (!err.isNull()) { |
3736 | QMessageBox::warning(this, tr("RTP packet search failed"), |
3737 | err, |
3738 | QMessageBox::Ok); |
3739 | } else { |
3740 | openTelephonyRtpAnalysisDialog()->addRtpStreams(stream_ids); |
3741 | } |
3742 | foreach(rtpstream_id_t *id, stream_ids)for (auto _container_3742 = QtPrivate::qMakeForeachContainer( stream_ids); _container_3742.i != _container_3742.e; ++_container_3742 .i) if (rtpstream_id_t *id = *_container_3742.i; false) {} else { |
3743 | rtpstream_id_free(id); |
3744 | g_free(id); |
3745 | } |
3746 | } |
3747 | |
3748 | void WiresharkMainWindow::openRtpPlayerDialog() |
3749 | { |
3750 | QVector<rtpstream_id_t *> stream_ids; |
3751 | QString err; |
3752 | |
3753 | if (QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier)) { |
3754 | err = findRtpStreams(&stream_ids, true); |
3755 | } else { |
3756 | err = findRtpStreams(&stream_ids, false); |
3757 | } |
3758 | if (!err.isNull()) { |
3759 | QMessageBox::warning(this, tr("RTP packet search failed"), |
3760 | err, |
3761 | QMessageBox::Ok); |
3762 | #ifdef QT_MULTIMEDIA_LIB1 |
3763 | } else { |
3764 | openTelephonyRtpPlayerDialog()->addRtpStreams(stream_ids); |
3765 | #endif // QT_MULTIMEDIA_LIB |
3766 | } |
3767 | foreach(rtpstream_id_t *id, stream_ids)for (auto _container_3767 = QtPrivate::qMakeForeachContainer( stream_ids); _container_3767.i != _container_3767.e; ++_container_3767 .i) if (rtpstream_id_t *id = *_container_3767.i; false) {} else { |
3768 | rtpstream_id_free(id); |
3769 | g_free(id); |
3770 | } |
3771 | } |
3772 | |
3773 | // Wireless Menu |
3774 | |
3775 | void WiresharkMainWindow::connectWirelessMenuActions() |
3776 | { |
3777 | connect(main_ui_->actionBluetoothATT_Server_Attributes, &QAction::triggered, this, [=]() { |
3778 | BluetoothAttServerAttributesDialog *bluetooth_att_sever_attributes_dialog = new BluetoothAttServerAttributesDialog(*this, capture_file_); |
3779 | connect(bluetooth_att_sever_attributes_dialog, &BluetoothAttServerAttributesDialog::goToPacket, |
3780 | this, [=](int packet_num) {packet_list_->goToPacket(packet_num);}); |
3781 | connect(bluetooth_att_sever_attributes_dialog, &BluetoothAttServerAttributesDialog::updateFilter, |
3782 | this, &WiresharkMainWindow::filterPackets); |
3783 | bluetooth_att_sever_attributes_dialog->show(); |
3784 | }); |
3785 | |
3786 | connect(main_ui_->actionBluetoothDevices, &QAction::triggered, this, [=]() { |
3787 | BluetoothDevicesDialog *bluetooth_devices_dialog = new BluetoothDevicesDialog(*this, capture_file_, packet_list_); |
3788 | connect(bluetooth_devices_dialog, &BluetoothDevicesDialog::goToPacket, this, [=](int packet_num) {packet_list_->goToPacket(packet_num);}); |
3789 | connect(bluetooth_devices_dialog, &BluetoothDevicesDialog::updateFilter, |
3790 | this, &WiresharkMainWindow::filterPackets); |
3791 | bluetooth_devices_dialog->show(); |
3792 | }); |
3793 | |
3794 | connect(main_ui_->actionBluetoothHCI_Summary, &QAction::triggered, this, [=]() { |
3795 | BluetoothHciSummaryDialog *bluetooth_hci_summary_dialog = new BluetoothHciSummaryDialog(*this, capture_file_); |
3796 | connect(bluetooth_hci_summary_dialog, &BluetoothHciSummaryDialog::goToPacket, |
3797 | this, [=](int packet_num) {packet_list_->goToPacket(packet_num);}); |
3798 | connect(bluetooth_hci_summary_dialog, &BluetoothHciSummaryDialog::updateFilter, |
3799 | this, &WiresharkMainWindow::filterPackets); |
3800 | bluetooth_hci_summary_dialog->show(); |
3801 | }); |
3802 | |
3803 | connect(main_ui_->actionWirelessWlanStatistics, &QAction::triggered, this, [=]() { statCommandWlanStatistics(NULL__null, NULL__null); }); |
3804 | } |
3805 | |
3806 | // Tools Menu |
3807 | |
3808 | void WiresharkMainWindow::connectToolsMenuActions() |
3809 | { |
3810 | connect(main_ui_->actionToolsFirewallAclRules, &QAction::triggered, this, [=]() { |
3811 | FirewallRulesDialog *firewall_rules_dialog = new FirewallRulesDialog(*this, capture_file_); |
3812 | firewall_rules_dialog->show(); |
3813 | }); |
3814 | |
3815 | connect(main_ui_->actionToolsCredentials, &QAction::triggered, this, [=]() { |
3816 | CredentialsDialog *credentials_dialog = new CredentialsDialog(*this, capture_file_, packet_list_); |
3817 | credentials_dialog->show(); |
3818 | }); |
3819 | |
3820 | connect(main_ui_->actionToolsMacLookup, &QAction::triggered, this, [=]() { |
3821 | ManufDialog *manuf_dialog = new ManufDialog(*this, capture_file_); |
3822 | manuf_dialog->show(); |
3823 | }); |
3824 | |
3825 | connect(main_ui_->actionToolsTLSKeylog, &QAction::triggered, this, &WiresharkMainWindow::openTLSKeylogDialog); |
3826 | } |
3827 | |
3828 | // Help Menu |
3829 | void WiresharkMainWindow::connectHelpMenuActions() |
3830 | { |
3831 | |
3832 | connect(main_ui_->actionHelpAbout, &QAction::triggered, this, [=]() { |
3833 | AboutDialog *about_dialog = new AboutDialog(this); |
3834 | |
3835 | if (about_dialog->isMinimized() == true) |
3836 | { |
3837 | about_dialog->showNormal(); |
3838 | } |
3839 | else |
3840 | { |
3841 | about_dialog->show(); |
3842 | } |
3843 | |
3844 | about_dialog->raise(); |
3845 | about_dialog->activateWindow(); |
3846 | }); |
3847 | |
3848 | connect(main_ui_->actionHelpContents, &QAction::triggered, this, [=]() { mainApp->helpTopicAction(HELP_CONTENT); }); |
3849 | connect(main_ui_->actionHelpMPWireshark, &QAction::triggered, this, [=]() { mainApp->helpTopicAction(LOCALPAGE_MAN_WIRESHARK); }); |
3850 | connect(main_ui_->actionHelpMPWireshark_Filter, &QAction::triggered, this, [=]() { mainApp->helpTopicAction(LOCALPAGE_MAN_WIRESHARK_FILTER); }); |
3851 | connect(main_ui_->actionHelpMPCapinfos, &QAction::triggered, this, [=]() { mainApp->helpTopicAction(LOCALPAGE_MAN_CAPINFOS); }); |
3852 | connect(main_ui_->actionHelpMPDumpcap, &QAction::triggered, this, [=]() { mainApp->helpTopicAction(LOCALPAGE_MAN_DUMPCAP); }); |
3853 | connect(main_ui_->actionHelpMPEditcap, &QAction::triggered, this, [=]() { mainApp->helpTopicAction(LOCALPAGE_MAN_EDITCAP); }); |
3854 | connect(main_ui_->actionHelpMPMergecap, &QAction::triggered, this, [=]() { mainApp->helpTopicAction(LOCALPAGE_MAN_MERGECAP); }); |
3855 | connect(main_ui_->actionHelpMPRawshark, &QAction::triggered, this, [=]() { mainApp->helpTopicAction(LOCALPAGE_MAN_RAWSHARK); }); |
3856 | connect(main_ui_->actionHelpMPReordercap, &QAction::triggered, this, [=]() { mainApp->helpTopicAction(LOCALPAGE_MAN_REORDERCAP); }); |
3857 | connect(main_ui_->actionHelpMPText2pcap, &QAction::triggered, this, [=]() { mainApp->helpTopicAction(LOCALPAGE_MAN_TEXT2PCAP); }); |
3858 | connect(main_ui_->actionHelpMPTShark, &QAction::triggered, this, [=]() { mainApp->helpTopicAction(LOCALPAGE_MAN_TSHARK); }); |
3859 | connect(main_ui_->actionHelpWebsite, &QAction::triggered, this, [=]() { mainApp->helpTopicAction(ONLINEPAGE_HOME); }); |
3860 | connect(main_ui_->actionHelpFAQ, &QAction::triggered, this, [=]() { mainApp->helpTopicAction(ONLINEPAGE_FAQ); }); |
3861 | connect(main_ui_->actionHelpAsk, &QAction::triggered, this, [=]() { mainApp->helpTopicAction(ONLINEPAGE_ASK); }); |
3862 | connect(main_ui_->actionHelpDownloads, &QAction::triggered, this, [=]() { mainApp->helpTopicAction(ONLINEPAGE_DOWNLOAD); }); |
3863 | connect(main_ui_->actionHelpWiki, &QAction::triggered, this, [=]() { mainApp->helpTopicAction(ONLINEPAGE_WIKI); }); |
3864 | connect(main_ui_->actionHelpSampleCaptures, &QAction::triggered, this, [=]() { mainApp->helpTopicAction(ONLINEPAGE_SAMPLE_FILES); }); |
3865 | connect(main_ui_->actionHelpReleaseNotes, &QAction::triggered, this, [=]() { mainApp->helpTopicAction(LOCALPAGE_RELEASE_NOTES); }); |
3866 | } |
3867 | |
3868 | #ifdef HAVE_SOFTWARE_UPDATE |
3869 | void WiresharkMainWindow::checkForUpdates() |
3870 | { |
3871 | software_update_check(); |
3872 | } |
3873 | #endif |
3874 | |
3875 | void WiresharkMainWindow::setPreviousFocus() { |
3876 | previous_focus_ = mainApp->focusWidget(); |
3877 | if (previous_focus_ != nullptr) { |
3878 | connect(previous_focus_, &QWidget::destroyed, this, &WiresharkMainWindow::resetPreviousFocus); |
3879 | } |
3880 | } |
3881 | |
3882 | void WiresharkMainWindow::resetPreviousFocus() { |
3883 | previous_focus_ = nullptr; |
3884 | } |
3885 | |
3886 | void WiresharkMainWindow::goToCancelClicked() |
3887 | { |
3888 | main_ui_->goToFrame->animatedHide(); |
3889 | if (previous_focus_) { |
3890 | disconnect(previous_focus_, &QWidget::destroyed, this, &WiresharkMainWindow::resetPreviousFocus); |
3891 | previous_focus_->setFocus(); |
3892 | resetPreviousFocus(); |
3893 | } |
3894 | } |
3895 | |
3896 | void WiresharkMainWindow::goToGoClicked() |
3897 | { |
3898 | gotoFrame(main_ui_->goToLineEdit->text().toInt()); |
3899 | |
3900 | goToCancelClicked(); |
3901 | } |
3902 | |
3903 | void WiresharkMainWindow::goToLineEditReturnPressed() |
3904 | { |
3905 | goToGoClicked(); |
3906 | } |
3907 | |
3908 | void WiresharkMainWindow::showResolvedAddressesDialog() |
3909 | { |
3910 | QString capFileName; |
3911 | wtap* wth = Q_NULLPTRnullptr; |
3912 | if (capture_file_.isValid()) |
3913 | { |
3914 | capFileName = capture_file_.capFile()->filename; |
3915 | wth = capture_file_.capFile()->provider.wth; |
3916 | } |
3917 | ResolvedAddressesDialog *resolved_addresses_dialog = |
3918 | new ResolvedAddressesDialog(this, capFileName, wth); |
3919 | resolved_addresses_dialog->show(); |
3920 | } |
3921 | |
3922 | void WiresharkMainWindow::showConversationsDialog() |
3923 | { |
3924 | ConversationDialog *conv_dialog = new ConversationDialog(*this, capture_file_); |
3925 | connect(conv_dialog, &ConversationDialog::filterAction, this, &WiresharkMainWindow::filterAction); |
3926 | connect(conv_dialog, &ConversationDialog::openFollowStreamDialog, this, |
3927 | [=](int proto_id, unsigned stream_num, unsigned sub_stream_num) { |
3928 | openFollowStreamDialog(proto_id, stream_num, sub_stream_num); |
3929 | }); |
3930 | connect(conv_dialog, &ConversationDialog::openTcpStreamGraph, this, &WiresharkMainWindow::openTcpStreamDialog); |
3931 | conv_dialog->show(); |
3932 | } |
3933 | |
3934 | void WiresharkMainWindow::showEndpointsDialog() |
3935 | { |
3936 | EndpointDialog *endp_dialog = new EndpointDialog(*this, capture_file_); |
3937 | connect(endp_dialog, &EndpointDialog::filterAction, this, &WiresharkMainWindow::filterAction); |
3938 | connect(endp_dialog, &EndpointDialog::openFollowStreamDialog, this, |
3939 | [=](int proto_id) {openFollowStreamDialog(proto_id); |
3940 | }); |
3941 | connect(endp_dialog, &EndpointDialog::openTcpStreamGraph, this, &WiresharkMainWindow::openTcpStreamDialog); |
3942 | endp_dialog->show(); |
3943 | } |
3944 | |
3945 | void WiresharkMainWindow::externalMenuItemTriggered() |
3946 | { |
3947 | QAction * triggerAction = NULL__null; |
3948 | QVariant v; |
3949 | ext_menubar_t * entry = NULL__null; |
3950 | |
3951 | if (QObject::sender()) { |
3952 | triggerAction = (QAction *)QObject::sender(); |
3953 | v = triggerAction->data(); |
3954 | |
3955 | if (v.canConvert<void *>()) { |
3956 | entry = (ext_menubar_t *)v.value<void *>(); |
3957 | |
3958 | if (entry->type == EXT_MENUBAR_ITEM) { |
3959 | entry->callback(EXT_MENUBAR_QT_GUI, (void *)((void *)main_ui_), entry->user_data); |
3960 | } else { |
3961 | QDesktopServices::openUrl(QUrl(QString((char *)entry->user_data))); |
3962 | } |
3963 | } |
3964 | } |
3965 | } |
3966 | |
3967 | void WiresharkMainWindow::extcap_options_finished(int result) |
3968 | { |
3969 | if (result == QDialog::Accepted) { |
3970 | QString before_what(tr(" before starting a new capture")); |
3971 | if (testCaptureFileClose(before_what)) { |
3972 | startCapture(QStringList()); |
3973 | } |
3974 | } |
3975 | this->welcome_page_->getInterfaceFrame()->interfaceListChanged(); |
3976 | } |
3977 | |
3978 | void WiresharkMainWindow::showExtcapOptionsDialog(QString &device_name, bool startCaptureOnClose) |
3979 | { |
3980 | ExtcapOptionsDialog * extcap_options_dialog = ExtcapOptionsDialog::createForDevice(device_name, startCaptureOnClose, this); |
3981 | /* The dialog returns null, if the given device name is not a valid extcap device */ |
3982 | if (extcap_options_dialog) { |
3983 | extcap_options_dialog->setModal(true); |
3984 | extcap_options_dialog->setAttribute(Qt::WA_DeleteOnClose); |
3985 | connect(extcap_options_dialog, &ExtcapOptionsDialog::finished, this, &WiresharkMainWindow::extcap_options_finished); |
3986 | #ifdef HAVE_LIBPCAP1 |
3987 | if (capture_options_dialog_) { |
3988 | /* Allow capture options dialog to close */ |
3989 | connect(extcap_options_dialog, &ExtcapOptionsDialog::accepted, capture_options_dialog_, &CaptureOptionsDialog::accept); |
3990 | } |
3991 | #endif |
3992 | extcap_options_dialog->show(); |
3993 | } |
3994 | } |
3995 | |
3996 | void WiresharkMainWindow::on_actionContextWikiProtocolPage_triggered() |
3997 | { |
3998 | QAction *wa = qobject_cast<QAction*>(sender()); |
3999 | if (!wa) return; |
4000 | |
4001 | bool ok = false; |
4002 | int field_id = wa->data().toInt(&ok); |
4003 | if (!ok) return; |
4004 | |
4005 | const QString proto_abbrev = proto_registrar_get_abbrev(field_id); |
4006 | |
4007 | int ret = QMessageBox::question(this, mainApp->windowTitleString(tr("Wiki Page for %1").arg(proto_abbrev)), |
4008 | tr("<p>The Wireshark Wiki is maintained by the community.</p>" |
4009 | "<p>The page you are about to load might be wonderful, " |
4010 | "incomplete, wrong, or nonexistent.</p>" |
4011 | "<p>Proceed to the wiki?</p>"), |
4012 | QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); |
4013 | |
4014 | if (ret != QMessageBox::Yes) return; |
4015 | |
4016 | QUrl wiki_url = QString(WS_WIKI_URL("Protocols/%1")"https://wiki.wireshark.org" "/" "Protocols/%1").arg(proto_abbrev); |
4017 | QDesktopServices::openUrl(wiki_url); |
4018 | } |
4019 | |
4020 | void WiresharkMainWindow::on_actionContextFilterFieldReference_triggered() |
4021 | { |
4022 | QAction *wa = qobject_cast<QAction*>(sender()); |
4023 | if (!wa) return; |
4024 | |
4025 | bool ok = false; |
4026 | int field_id = wa->data().toInt(&ok); |
4027 | if (!ok) return; |
4028 | |
4029 | const QString proto_abbrev = proto_registrar_get_abbrev(field_id); |
4030 | |
4031 | QUrl dfref_url = QString(WS_DOCS_URL"https://www.wireshark.org/docs/" "/dfref/%1/%2") |
4032 | .arg(proto_abbrev[0]) |
4033 | .arg(proto_abbrev); |
4034 | QDesktopServices::openUrl(dfref_url); |
4035 | } |
4036 | |
4037 | void WiresharkMainWindow::activatePluginIFToolbar(bool) |
4038 | { |
4039 | QAction *sendingAction = dynamic_cast<QAction *>(sender()); |
4040 | if (!sendingAction || !sendingAction->data().isValid()) |
4041 | return; |
4042 | |
4043 | ext_toolbar_t *toolbar = VariantPointer<ext_toolbar_t>::asPtr(sendingAction->data()); |
4044 | |
4045 | QList<QToolBar *> toolbars = findChildren<QToolBar *>(); |
4046 | foreach(QToolBar *bar, toolbars)for (auto _container_4046 = QtPrivate::qMakeForeachContainer( toolbars); _container_4046.i != _container_4046.e; ++_container_4046 .i) if (QToolBar *bar = *_container_4046.i; false) {} else { |
4047 | AdditionalToolBar *iftoolbar = dynamic_cast<AdditionalToolBar *>(bar); |
4048 | if (iftoolbar && iftoolbar->menuName().compare(toolbar->name) == 0) { |
4049 | if (iftoolbar->isVisible()) { |
4050 | iftoolbar->setVisible(false); |
4051 | sendingAction->setChecked(true); |
4052 | } else { |
4053 | iftoolbar->setVisible(true); |
4054 | sendingAction->setChecked(true); |
4055 | } |
4056 | } |
4057 | } |
4058 | } |
4059 | |
4060 | void WiresharkMainWindow::rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_id_t *> stream_ids _U___attribute__((unused))) |
4061 | { |
4062 | #ifdef QT_MULTIMEDIA_LIB1 |
4063 | openTelephonyRtpPlayerDialog()->replaceRtpStreams(stream_ids); |
4064 | #endif |
4065 | } |
4066 | |
4067 | void WiresharkMainWindow::rtpPlayerDialogAddRtpStreams(QVector<rtpstream_id_t *> stream_ids _U___attribute__((unused))) |
4068 | { |
4069 | #ifdef QT_MULTIMEDIA_LIB1 |
4070 | openTelephonyRtpPlayerDialog()->addRtpStreams(stream_ids); |
4071 | #endif |
4072 | } |
4073 | |
4074 | void WiresharkMainWindow::rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_id_t *> stream_ids _U___attribute__((unused))) |
4075 | { |
4076 | #ifdef QT_MULTIMEDIA_LIB1 |
4077 | openTelephonyRtpPlayerDialog()->removeRtpStreams(stream_ids); |
4078 | #endif |
4079 | } |
4080 | |
4081 | void WiresharkMainWindow::rtpAnalysisDialogReplaceRtpStreams(QVector<rtpstream_id_t *> stream_ids) |
4082 | { |
4083 | openTelephonyRtpAnalysisDialog()->replaceRtpStreams(stream_ids); |
4084 | } |
4085 | |
4086 | void WiresharkMainWindow::rtpAnalysisDialogAddRtpStreams(QVector<rtpstream_id_t *> stream_ids) |
4087 | { |
4088 | openTelephonyRtpAnalysisDialog()->addRtpStreams(stream_ids); |
4089 | } |
4090 | |
4091 | void WiresharkMainWindow::rtpAnalysisDialogRemoveRtpStreams(QVector<rtpstream_id_t *> stream_ids) |
4092 | { |
4093 | openTelephonyRtpAnalysisDialog()->removeRtpStreams(stream_ids); |
4094 | } |
4095 | |
4096 | void WiresharkMainWindow::rtpStreamsDialogSelectRtpStreams(QVector<rtpstream_id_t *> stream_ids) |
4097 | { |
4098 | openTelephonyRtpStreamsDialog()->selectRtpStream(stream_ids); |
4099 | } |
4100 | |
4101 | void WiresharkMainWindow::rtpStreamsDialogDeselectRtpStreams(QVector<rtpstream_id_t *> stream_ids) |
4102 | { |
4103 | openTelephonyRtpStreamsDialog()->deselectRtpStream(stream_ids); |
4104 | } |
4105 | |
4106 | #ifdef _MSC_VER |
4107 | #pragma warning(pop) |
4108 | #endif |