summaryrefslogtreecommitdiffstats
path: root/ui/qt/manage_interfaces_dialog.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-09-19 04:14:26 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-09-19 04:14:26 +0000
commitc4e8a3222648fcf22ca207f1815ebbf7cd144eeb (patch)
tree93d5c6aa93d9987680dd1adad5685e2ad698f223 /ui/qt/manage_interfaces_dialog.cpp
parentAdding upstream version 4.2.6. (diff)
downloadwireshark-c4e8a3222648fcf22ca207f1815ebbf7cd144eeb.tar.xz
wireshark-c4e8a3222648fcf22ca207f1815ebbf7cd144eeb.zip
Adding upstream version 4.4.0.upstream/4.4.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ui/qt/manage_interfaces_dialog.cpp')
-rw-r--r--ui/qt/manage_interfaces_dialog.cpp180
1 files changed, 133 insertions, 47 deletions
diff --git a/ui/qt/manage_interfaces_dialog.cpp b/ui/qt/manage_interfaces_dialog.cpp
index a8529e26..ca7a1d9a 100644
--- a/ui/qt/manage_interfaces_dialog.cpp
+++ b/ui/qt/manage_interfaces_dialog.cpp
@@ -23,6 +23,10 @@
#include "ui/qt/remote_settings_dialog.h"
#include "capture/capture-pcap-util.h"
#include "ui/recent.h"
+#include "wsutil/filesystem.h"
+#include <QJsonDocument>
+#include <QJsonArray>
+#include <QJsonObject>
#endif
#include "ui/iface_lists.h"
#include "ui/preference_utils.h"
@@ -72,53 +76,89 @@ enum {
};
#ifdef HAVE_PCAP_REMOTE
-static void populateExistingRemotes(gpointer key, gpointer value, gpointer user_data)
+#define REMOTE_HOSTS_FILE "remote_hosts.json"
+
+void ManageInterfacesDialog::addRemote(const QVariantMap&& remoteHostMap)
{
- ManageInterfacesDialog *dialog = (ManageInterfacesDialog*)user_data;
- const gchar *host = (const gchar *)key;
- struct remote_host *remote_host = (struct remote_host *)value;
remote_options global_remote_opts;
int err;
- gchar *err_str;
+ char* err_str;
global_remote_opts.src_type = CAPTURE_IFREMOTE;
- global_remote_opts.remote_host_opts.remote_host = g_strdup(host);
- global_remote_opts.remote_host_opts.remote_port = g_strdup(remote_host->remote_port);
- global_remote_opts.remote_host_opts.auth_type = remote_host->auth_type;
- global_remote_opts.remote_host_opts.auth_username = g_strdup(remote_host->auth_username);
- global_remote_opts.remote_host_opts.auth_password = g_strdup(remote_host->auth_password);
- global_remote_opts.remote_host_opts.datatx_udp = FALSE;
- global_remote_opts.remote_host_opts.nocap_rpcap = TRUE;
- global_remote_opts.remote_host_opts.nocap_local = FALSE;
+ global_remote_opts.remote_host_opts.remote_host = qstring_strdup(remoteHostMap["host"].toString());
+ global_remote_opts.remote_host_opts.remote_port = qstring_strdup(remoteHostMap["port"].toString());
+ global_remote_opts.remote_host_opts.auth_type = static_cast<capture_auth>(remoteHostMap["auth"].toInt());
+ global_remote_opts.remote_host_opts.auth_username = qstring_strdup(remoteHostMap["username"].toString());
+ global_remote_opts.remote_host_opts.auth_password = qstring_strdup(remoteHostMap["password"].toString());
+ global_remote_opts.remote_host_opts.datatx_udp = false;
+ global_remote_opts.remote_host_opts.nocap_rpcap = true;
+ global_remote_opts.remote_host_opts.nocap_local = false;
#ifdef HAVE_PCAP_SETSAMPLING
global_remote_opts.sampling_method = CAPTURE_SAMP_NONE;
- global_remote_opts.sampling_param = 0;
+ global_remote_opts.sampling_param = 0;
#endif
- GList *rlist = get_remote_interface_list(global_remote_opts.remote_host_opts.remote_host,
- global_remote_opts.remote_host_opts.remote_port,
- global_remote_opts.remote_host_opts.auth_type,
- global_remote_opts.remote_host_opts.auth_username,
- global_remote_opts.remote_host_opts.auth_password,
- &err, &err_str);
+
+ // This doesn't handle CAPTURE_AUTH_PWD because we don't store the password
+ // XXX: Don't these strings get leaked? I think that they're dup'ed again
+ // later. Same for in RemoteCaptureDialog::apply_remote()
+
+ GList* rlist = get_remote_interface_list(global_remote_opts.remote_host_opts.remote_host,
+ global_remote_opts.remote_host_opts.remote_port,
+ global_remote_opts.remote_host_opts.auth_type,
+ global_remote_opts.remote_host_opts.auth_username,
+ global_remote_opts.remote_host_opts.auth_password,
+ &err, &err_str);
+
if (rlist == NULL) {
switch (err) {
case 0:
- QMessageBox::warning(dialog, QObject::tr("Error"), QObject::tr("No remote interfaces found."));
+ QMessageBox::warning(this, QObject::tr("Error"), QObject::tr("No remote interfaces found."));
break;
case CANT_GET_INTERFACE_LIST:
- QMessageBox::critical(dialog, QObject::tr("Error"), err_str);
+ QMessageBox::critical(this, QObject::tr("Error"), err_str);
break;
case DONT_HAVE_PCAP:
- QMessageBox::critical(dialog, QObject::tr("Error"), QObject::tr("PCAP not found"));
+ QMessageBox::critical(this, QObject::tr("Error"), QObject::tr("PCAP not found"));
break;
default:
- QMessageBox::critical(dialog, QObject::tr("Error"), QObject::tr("Unknown error"));
+ QMessageBox::critical(this, QObject::tr("Error"), QObject::tr("Unknown error"));
break;
}
return;
}
+ // XXX: If the connection fails we won't add it, so it won't get saved to
+ // load automatically next time (but will perhaps still be in recent.)
+ // That's mostly a feature not a bug, but we might want support for
+ // currently disabled remote hosts.
+
+ emit remoteAdded(rlist, &global_remote_opts);
+}
+
+void ManageInterfacesDialog::populateExistingRemotes()
+{
+ const char* cfile = REMOTE_HOSTS_FILE;
+
+ /* Try personal config file first */
+ QString fileName = gchar_free_to_qstring(get_persconffile_path(cfile, true));
+
+ if (fileName.isEmpty() || !QFileInfo::exists(fileName)) {
+ return;
+ }
+
+ QFile file(fileName);
+ if (!file.open(QIODevice::ReadOnly)) {
+ return;
+ }
+
+ QJsonDocument document = QJsonDocument::fromJson(file.readAll());
+ if (!document.isArray()) {
+ return;
+ }
+
+ foreach(QJsonValue value, document.array()) {
+ addRemote(value.toObject().toVariantMap());
+ }
- emit dialog->remoteAdded(rlist, &global_remote_opts);
}
#endif /* HAVE_PCAP_REMOTE */
@@ -157,10 +197,13 @@ ManageInterfacesDialog::ManageInterfacesDialog(QWidget *parent) :
proxyModel->setRemoteDisplay(false);
#endif
proxyModel->setFilterByType(false);
+ proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
ui->localView->setModel(proxyModel);
ui->localView->resizeColumnToContents(proxyModel->mapSourceToColumn(IFTREE_COL_HIDDEN));
ui->localView->resizeColumnToContents(proxyModel->mapSourceToColumn(IFTREE_COL_NAME));
+ ui->localView->header()->setSortIndicator(-1, Qt::AscendingOrder);
+ ui->localView->setSortingEnabled(true);
pipeProxyModel = new InterfaceSortFilterModel(this);
columns.clear();
@@ -176,7 +219,7 @@ ManageInterfacesDialog::ManageInterfacesDialog(QWidget *parent) :
ui->pipeView->setModel(pipeProxyModel);
ui->delPipe->setEnabled(pipeProxyModel->rowCount() > 0);
- ui->pipeView->setItemDelegateForColumn(pipeProxyModel->mapSourceToColumn(IFTREE_COL_PIPE_PATH), new PathSelectionDelegate());
+ ui->pipeView->setItemDelegateForColumn(pipeProxyModel->mapSourceToColumn(IFTREE_COL_PIPE_PATH), new PathSelectionDelegate(this));
connect(ui->pipeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, [=](const QItemSelection &sel, const QItemSelection &) {
ui->delPipe->setEnabled(sel.count() > 0);
});
@@ -200,7 +243,7 @@ ManageInterfacesDialog::ManageInterfacesDialog(QWidget *parent) :
connect(this, SIGNAL(remoteAdded(GList*, remote_options*)), this, SLOT(addRemoteInterfaces(GList*, remote_options*)));
connect(this, SIGNAL(remoteSettingsChanged(interface_t *)), this, SLOT(setRemoteSettings(interface_t *)));
connect(ui->remoteList, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(remoteSelectionChanged(QTreeWidgetItem*, int)));
- recent_remote_host_list_foreach(populateExistingRemotes, this);
+ populateExistingRemotes();
#endif
ui->tabWidget->setCurrentIndex(tab_local_);
@@ -272,8 +315,8 @@ void ManageInterfacesDialog::on_addPipe_clicked()
memset(&device, 0, sizeof(device));
device.name = qstring_strdup(tr("New Pipe"));
device.display_name = g_strdup(device.name);
- device.hidden = FALSE;
- device.selected = TRUE;
+ device.hidden = false;
+ device.selected = true;
device.pmode = global_capture_opts.default_options.promisc_mode;
device.has_snaplen = global_capture_opts.default_options.has_snaplen;
device.snaplen = global_capture_opts.default_options.snaplen;
@@ -319,20 +362,25 @@ void ManageInterfacesDialog::updateRemoteInterfaceList(GList* rlist, remote_opti
GList *if_entry, *lt_entry;
if_info_t *if_info;
char *if_string = NULL;
- gchar *descr, *auth_str;
+ char *descr, *auth_str;
if_capabilities_t *caps;
- gint linktype_count;
+ int linktype_count;
bool monitor_mode, found = false;
GSList *curr_addr;
int ips = 0;
- guint i;
+ unsigned i;
if_addr_t *addr;
data_link_info_t *data_link_info;
GString *ip_str;
link_row *linkr = NULL;
interface_t device;
- guint num_interfaces;
+ unsigned num_interfaces;
+ // Add any (remote) interface in rlist to the global list of all
+ // interfaces.
+ // Most of this is copied from scan_local_interfaces_filtered, but
+ // some of it doesn't make sense for remote interfaces (yet?) - we
+ // can't, for example, control monitor mode.
num_interfaces = global_capture_opts.all_ifaces->len;
for (if_entry = g_list_first(rlist); if_entry != NULL; if_entry = gxx_list_next(if_entry)) {
auth_str = NULL;
@@ -345,12 +393,12 @@ void ManageInterfacesDialog::updateRemoteInterfaceList(GList* rlist, remote_opti
if (device.hidden)
continue;
if (strcmp(device.name, if_info->name) == 0) {
- found = TRUE;
+ found = true;
break;
}
}
if (found) {
- found = FALSE;
+ found = false;
continue;
}
ip_str = g_string_new("");
@@ -430,11 +478,15 @@ void ManageInterfacesDialog::updateRemoteInterfaceList(GList* rlist, remote_opti
linktype_count = 0;
device.links = NULL;
if (caps != NULL) {
+ GList *lt_list = caps->data_link_types;
#ifdef HAVE_PCAP_CREATE
- device.monitor_mode_enabled = monitor_mode;
+ device.monitor_mode_enabled = monitor_mode && caps->can_set_rfmon;
device.monitor_mode_supported = caps->can_set_rfmon;
+ if (device.monitor_mode_enabled) {
+ lt_list = caps->data_link_types_rfmon;
+ }
#endif
- for (lt_entry = caps->data_link_types; lt_entry != NULL; lt_entry = gxx_list_next(lt_entry)) {
+ for (lt_entry = lt_list; lt_entry != NULL; lt_entry = gxx_list_next(lt_entry)) {
data_link_info = gxx_list_data(data_link_info_t *, lt_entry);
linkr = new link_row;
/*
@@ -459,8 +511,8 @@ void ManageInterfacesDialog::updateRemoteInterfaceList(GList* rlist, remote_opti
} /* for link_types */
} else {
#if defined(HAVE_PCAP_CREATE)
- device.monitor_mode_enabled = FALSE;
- device.monitor_mode_supported = FALSE;
+ device.monitor_mode_enabled = false;
+ device.monitor_mode_supported = false;
#endif
device.active_dlt = -1;
}
@@ -468,7 +520,7 @@ void ManageInterfacesDialog::updateRemoteInterfaceList(GList* rlist, remote_opti
device.no_addresses = ips;
device.remote_opts.src_type= roptions->src_type;
if (device.remote_opts.src_type == CAPTURE_IFREMOTE) {
- device.local = FALSE;
+ device.local = false;
}
device.remote_opts.remote_host_opts.remote_host = g_strdup(roptions->remote_host_opts.remote_host);
device.remote_opts.remote_host_opts.remote_port = g_strdup(roptions->remote_host_opts.remote_port);
@@ -482,7 +534,7 @@ void ManageInterfacesDialog::updateRemoteInterfaceList(GList* rlist, remote_opti
device.remote_opts.sampling_method = roptions->sampling_method;
device.remote_opts.sampling_param = roptions->sampling_param;
#endif
- device.selected = TRUE;
+ device.selected = true;
global_capture_opts.num_selected++;
g_array_append_val(global_capture_opts.all_ifaces, device);
g_string_free(ip_str, TRUE);
@@ -500,9 +552,17 @@ void ManageInterfacesDialog::addRemoteInterfaces(GList* rlist, remote_options *r
void ManageInterfacesDialog::remoteAccepted()
{
QTreeWidgetItemIterator it(ui->remoteList);
+ QJsonArray hostArray;
while (*it) {
- for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ if ((*it)->parent() == nullptr) {
+ QVariant v = (*it)->data(0, Qt::UserRole);
+ if (v.canConvert<QJsonObject>()) {
+ hostArray.append(v.toJsonValue());
+ }
+ }
+
+ for (unsigned i = 0; i < global_capture_opts.all_ifaces->len; i++) {
interface_t *device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
if ((*it)->text(col_r_host_dev_).compare(device->name))
continue;
@@ -510,6 +570,21 @@ void ManageInterfacesDialog::remoteAccepted()
}
++it;
}
+
+ const char* cfile = REMOTE_HOSTS_FILE;
+ /* Try personal config file first */
+ QString fileName = gchar_free_to_qstring(get_persconffile_path(cfile, true));
+
+ if (fileName.isEmpty()) {
+ return;
+ }
+
+ QFile file(fileName);
+ if (!file.open(QIODevice::WriteOnly)) {
+ return;
+ }
+
+ file.write(QJsonDocument(hostArray).toJson(QJsonDocument::Compact));
}
void ManageInterfacesDialog::on_remoteList_currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)
@@ -523,7 +598,7 @@ void ManageInterfacesDialog::on_remoteList_itemClicked(QTreeWidgetItem *item, in
return;
}
- for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ for (unsigned i = 0; i < global_capture_opts.all_ifaces->len; i++) {
interface_t *device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
if (!device->local) {
if (item->text(col_r_host_dev_).compare(device->name))
@@ -540,7 +615,7 @@ void ManageInterfacesDialog::on_delRemote_clicked()
return;
}
- for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ for (unsigned i = 0; i < global_capture_opts.all_ifaces->len; i++) {
interface_t *device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
if (item->text(col_r_host_dev_).compare(device->remote_opts.remote_host_opts.remote_host))
continue;
@@ -559,7 +634,7 @@ void ManageInterfacesDialog::on_addRemote_clicked()
void ManageInterfacesDialog::showRemoteInterfaces()
{
- guint i;
+ unsigned i;
interface_t *device;
QTreeWidgetItem * item = nullptr;
@@ -580,6 +655,17 @@ void ManageInterfacesDialog::showRemoteInterfaces()
if (items.count() == 0) {
item = new QTreeWidgetItem(ui->remoteList);
item->setText(col_r_host_dev_, parentName);
+ QJsonObject remote_host{
+ {"host", parentName},
+ {"port", device->remote_opts.remote_host_opts.remote_port},
+ {"auth_type", device->remote_opts.remote_host_opts.auth_type},
+ {"username", device->remote_opts.remote_host_opts.auth_username},
+ // {"password", device->remote_opts.remote_host_opts.auth_password},
+ // We should find some way to store the password in a
+ // credential manager (cf. #17949 for extcap) and
+ // reference it
+ };
+ item->setData(0, Qt::UserRole, remote_host);
item->setExpanded(true);
}
else {
@@ -599,7 +685,7 @@ void ManageInterfacesDialog::showRemoteInterfaces()
void ManageInterfacesDialog::on_remoteSettings_clicked()
{
- guint i = 0;
+ unsigned i = 0;
interface_t *device;
QTreeWidgetItem* item = ui->remoteList->currentItem();
if (!item) {
@@ -622,7 +708,7 @@ void ManageInterfacesDialog::on_remoteSettings_clicked()
void ManageInterfacesDialog::setRemoteSettings(interface_t *iface)
{
- for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ for (unsigned i = 0; i < global_capture_opts.all_ifaces->len; i++) {
interface_t *device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
if (!device->local) {
if (strcmp(iface->name, device->name)) {