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