summaryrefslogtreecommitdiffstats
path: root/ui/qt/utils/profile_switcher.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ui/qt/utils/profile_switcher.cpp')
-rw-r--r--ui/qt/utils/profile_switcher.cpp140
1 files changed, 140 insertions, 0 deletions
diff --git a/ui/qt/utils/profile_switcher.cpp b/ui/qt/utils/profile_switcher.cpp
new file mode 100644
index 00000000..ded1b1f5
--- /dev/null
+++ b/ui/qt/utils/profile_switcher.cpp
@@ -0,0 +1,140 @@
+/* profile_switcher.cpp
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+// #include <capture_file.h>
+#include <main_application.h>
+
+#include <ui/profile.h>
+#include <ui/recent.h>
+
+#include <ui/qt/capture_file.h>
+#include <ui/qt/models/packet_list_model.h>
+
+#include "profile_switcher.h"
+
+#include "file.h"
+
+#include <epan/epan.h>
+#include <epan/epan_dissect.h>
+#include <epan/prefs.h>
+#include "frame_tvbuff.h"
+
+// Enable switching iff:
+// - We're opening a new capture file via the UI.
+// - We haven't changed our profile, either manually or automatically.
+
+ProfileSwitcher::ProfileSwitcher(QObject *parent) :
+ QObject(parent),
+ capture_file_changed_(true),
+ profile_changed_(false)
+{
+ if (g_list_length(current_profile_list()) == 0) {
+ init_profile_list();
+ }
+ connect(mainApp, &MainApplication::profileChanging, this, &ProfileSwitcher::disableSwitching);
+}
+
+void ProfileSwitcher::captureEventHandler(CaptureEvent ev)
+{
+ if (ev.captureContext() != CaptureEvent::File) {
+ return;
+ }
+
+ CaptureFile *capture_file = qobject_cast<CaptureFile *>(sender());
+ if (!capture_file) {
+ return;
+ }
+
+ // CaptureEvent doesn't have a "this is the same file" flag, so
+ // track that via the filename.
+ switch (ev.eventType()) {
+ case CaptureEvent::Opened:
+ if (previous_cap_file_ != capture_file->filePath()) {
+ capture_file_changed_ = true;
+ profile_changed_ = false;
+ }
+ break;
+ case CaptureEvent::Closing:
+ previous_cap_file_ = capture_file->filePath();
+ break;
+ default:
+ break;
+ }
+}
+
+void ProfileSwitcher::checkPacket(capture_file *cap_file, frame_data *fdata, qsizetype row)
+{
+ if (profile_changed_ || !capture_file_changed_ || row >= recent.gui_profile_switch_check_count) {
+ return;
+ }
+
+ if (row == 0) {
+ clearProfileFilters();
+ for (GList *cur = current_profile_list() ; cur; cur = cur->next) {
+ profile_def *profile = static_cast<profile_def *>(cur->data);
+ if (!profile->auto_switch_filter) {
+ continue;
+ }
+ dfilter_t *dfcode;
+ if (dfilter_compile(profile->auto_switch_filter, &dfcode, NULL) && dfcode) {
+ profile_filters_.append({profile->name, dfcode});
+ }
+ }
+ }
+
+ if (profile_filters_.empty()) {
+ return;
+ }
+
+ QString new_profile;
+ wtap_rec rec;
+ Buffer buf;
+ wtap_rec_init(&rec);
+ ws_buffer_init(&buf, 1514);
+ epan_dissect_t edt;
+
+ for (auto &cur_filter : profile_filters_) {
+ if (!cf_read_record(cap_file, fdata, &rec, &buf)) {
+ continue;
+ }
+ epan_dissect_init(&edt, cap_file->epan, TRUE, FALSE);
+ epan_dissect_prime_with_dfilter(&edt, cur_filter.dfcode);
+ epan_dissect_run(&edt, cap_file->cd_t, &rec,
+ frame_tvbuff_new_buffer(&cap_file->provider, fdata, &buf),
+ fdata, NULL);
+ bool matched = dfilter_apply_edt(cur_filter.dfcode, &edt);
+ epan_dissect_cleanup(&edt);
+ if (matched) {
+ new_profile = cur_filter.name;
+ break;
+ }
+ }
+
+ wtap_rec_cleanup(&rec);
+ ws_buffer_free(&buf);
+
+ if (!new_profile.isEmpty()) {
+ clearProfileFilters();
+ previous_cap_file_ = cap_file->filename;
+ mainApp->setConfigurationProfile(qUtf8Printable(new_profile), false);
+ }
+}
+
+void ProfileSwitcher::clearProfileFilters()
+{
+ for (auto &cur_filter : profile_filters_) {
+ dfilter_free(cur_filter.dfcode);
+ }
+ profile_filters_.clear();
+}
+
+void ProfileSwitcher::disableSwitching()
+{
+ profile_changed_ = true;
+}