summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIrene Ruengeler <ruengeler@wireshark.org>2014-06-04 11:03:59 +0200
committerAnders Broman <a.broman58@gmail.com>2014-06-12 05:54:59 +0000
commitdf8c4bf2644d39d66613868256d918346d56aef8 (patch)
treeb0a04ebc37a508598b5e49652ebe83219fff47c2
parent428c5b9448a510da1d8bc903f59364ef830585ac (diff)
downloadwireshark-df8c4bf2644d39d66613868256d918346d56aef8.tar.gz
Capture Interfaces Dialog:
- allow to change the interface options in the table - save the options to preferences when the dialog is left - add a field for setting a capture filter for all selected interfaces - add a "Compile BPF" button and a window to show the compiled filter output - try to address Alexis' and Evan's comments Change-Id: Ic1272e29183ec80e2d2f4b3e494c79dabe2c3b6f Reviewed-on: https://code.wireshark.org/review/1946 Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com> Tested-by: Alexis La Goutte <alexis.lagoutte@gmail.com> Reviewed-by: Anders Broman <a.broman58@gmail.com>
-rw-r--r--capture_opts.h1
-rw-r--r--capture_ui_utils.c66
-rw-r--r--capture_ui_utils.h6
-rw-r--r--epan/prefs.c4
-rw-r--r--epan/prefs.h1
-rw-r--r--image/status.qrc1
-rw-r--r--ui/qt/CMakeLists.txt3
-rw-r--r--ui/qt/Makefile.am2
-rw-r--r--ui/qt/Makefile.common4
-rw-r--r--ui/qt/QtShark.pro3
-rw-r--r--ui/qt/capture_interfaces_dialog.cpp609
-rw-r--r--ui/qt/capture_interfaces_dialog.h49
-rw-r--r--ui/qt/capture_interfaces_dialog.ui83
-rw-r--r--ui/qt/compiled_filter_output.cpp115
-rw-r--r--ui/qt/compiled_filter_output.h72
-rw-r--r--ui/qt/compiled_filter_output.ui94
-rw-r--r--ui/qt/interface_tree.cpp25
-rw-r--r--ui/qt/interface_tree.h1
-rw-r--r--ui/qt/main_window.cpp4
-rw-r--r--ui/qt/main_window.h2
-rw-r--r--ui/qt/main_window_slots.cpp7
21 files changed, 983 insertions, 169 deletions
diff --git a/capture_opts.h b/capture_opts.h
index 704242f0f0..f9bdf89eb6 100644
--- a/capture_opts.h
+++ b/capture_opts.h
@@ -125,6 +125,7 @@ typedef struct interface_tag {
remote_options remote_opts;
#endif
guint32 last_packets;
+ guint32 packet_diff;
if_info_t if_info;
gboolean selected;
gboolean hidden;
diff --git a/capture_ui_utils.c b/capture_ui_utils.c
index d184ab1c77..ccd94b3549 100644
--- a/capture_ui_utils.c
+++ b/capture_ui_utils.c
@@ -101,7 +101,7 @@ capture_dev_user_descr_find(const gchar *if_name)
gint
capture_dev_user_linktype_find(const gchar *if_name)
{
- gchar *p, *next;
+ gchar *p, *next, *tmpname;
long linktype;
if ((prefs.capture_devices_linktypes == NULL) ||
@@ -109,13 +109,13 @@ capture_dev_user_linktype_find(const gchar *if_name)
/* There are no link-layer header types */
return -1;
}
-
- if ((p = strstr(prefs.capture_devices_linktypes, if_name)) == NULL) {
+ tmpname = g_strdup_printf(",%s(", if_name);
+ if ((p = strstr(prefs.capture_devices_linktypes, tmpname)) == NULL) {
/* There are, but there isn't one for this interface. */
return -1;
}
- p += strlen(if_name) + 1;
+ p += strlen(if_name) + 2;
linktype = strtol(p, &next, 10);
if (next == p || *next != ')' || linktype < 0) {
/* Syntax error */
@@ -133,7 +133,7 @@ capture_dev_user_linktype_find(const gchar *if_name)
gint
capture_dev_user_buffersize_find(const gchar *if_name)
{
- gchar *p, *next;
+ gchar *p, *next, *tmpname;
gint buffersize;
if ((prefs.capture_devices_buffersize == NULL) ||
@@ -141,13 +141,13 @@ capture_dev_user_buffersize_find(const gchar *if_name)
/* There are no buffersizes defined */
return -1;
}
-
- if ((p = strstr(prefs.capture_devices_buffersize, if_name)) == NULL) {
+ tmpname = g_strdup_printf(",%s(", if_name);
+ if ((p = strstr(prefs.capture_devices_buffersize, tmpname)) == NULL) {
/* There are, but there isn't one for this interface. */
return -1;
}
- p += strlen(if_name) + 1;
+ p += strlen(if_name) + 2;
buffersize = (gint)strtol(p, &next, 10);
if (next == p || *next != ')' || buffersize < 0) {
/* Syntax error */
@@ -165,7 +165,7 @@ capture_dev_user_buffersize_find(const gchar *if_name)
gint
capture_dev_user_snaplen_find(const gchar *if_name)
{
- gchar *p, *next;
+ gchar *p, *next, *tmpname;
gint snaplen;
if ((prefs.capture_devices_snaplen == NULL) ||
@@ -173,13 +173,13 @@ capture_dev_user_snaplen_find(const gchar *if_name)
/* There is no snap length defined */
return -1;
}
-
- if ((p = strstr(prefs.capture_devices_snaplen, if_name)) == NULL) {
+ tmpname = g_strdup_printf(",%s:", if_name);
+ if ((p = strstr(prefs.capture_devices_snaplen, tmpname)) == NULL) {
/* There are, but there isn't one for this interface. */
return -1;
}
- p += strlen(if_name) + 3;
+ p += strlen(if_name) + 4;
snaplen = (gint)strtol(p, &next, 10);
if (next == p || *next != ')' || snaplen < 0) {
/* Syntax error */
@@ -196,7 +196,7 @@ capture_dev_user_snaplen_find(const gchar *if_name)
gboolean
capture_dev_user_hassnap_find(const gchar *if_name)
{
- gchar *p, *next;
+ gchar *p, *next, *tmpname;
gboolean hassnap;
if ((prefs.capture_devices_snaplen == NULL) ||
@@ -204,13 +204,13 @@ capture_dev_user_hassnap_find(const gchar *if_name)
/* There is no snap length defined */
return -1;
}
-
- if ((p = strstr(prefs.capture_devices_snaplen, if_name)) == NULL) {
+ tmpname = g_strdup_printf(",%s:", if_name);
+ if ((p = strstr(prefs.capture_devices_snaplen, tmpname)) == NULL) {
/* There are, but there isn't one for this interface. */
return -1;
}
- p += strlen(if_name) + 1;
+ p += strlen(if_name) + 2;
hassnap = (gboolean)strtol(p, &next, 10);
if (next == p || *next != '(') {
/* Syntax error */
@@ -223,7 +223,7 @@ capture_dev_user_hassnap_find(const gchar *if_name)
gboolean
capture_dev_user_pmode_find(const gchar *if_name)
{
- gchar *p, *next;
+ gchar *p, *next, *tmpname;
gboolean pmode;
if ((prefs.capture_devices_pmode == NULL) ||
@@ -231,13 +231,13 @@ capture_dev_user_pmode_find(const gchar *if_name)
/* There is no promiscuous mode defined */
return -1;
}
-
- if ((p = strstr(prefs.capture_devices_pmode, if_name)) == NULL) {
+ tmpname = g_strdup_printf(",%s(", if_name);
+ if ((p = strstr(prefs.capture_devices_pmode, tmpname)) == NULL) {
/* There are, but there isn't one for this interface. */
return -1;
}
- p += strlen(if_name) + 1;
+ p += strlen(if_name) + 2;
pmode = (gboolean)strtol(p, &next, 10);
if (next == p || *next != ')') {
/* Syntax error */
@@ -246,6 +246,32 @@ capture_dev_user_pmode_find(const gchar *if_name)
return (gboolean)pmode;
}
+gchar*
+capture_dev_user_cfilter_find(const gchar *if_name)
+{
+ gchar *p, q[MAX_VAL_LEN], *tmpname;
+ int i = 0;
+
+ if ((prefs.capture_devices_filter == NULL) ||
+ (*prefs.capture_devices_filter == '\0')) {
+ /* There is no capture filter defined */
+ return NULL;
+ }
+ tmpname = g_strdup_printf(",%s(", if_name);
+ if ((p = strstr(prefs.capture_devices_filter, tmpname)) == NULL) {
+ /* There are, but there isn't one for this interface. */
+ return NULL;
+ }
+
+ p += strlen(if_name) + 2;
+ while (p[i+1] != ',' && p[i+1] != '\0') {
+ q[i] = p[i];
+ i++;
+ }
+ q[i] = '\0';
+ return g_strdup(q);
+}
+
/*
* Return as descriptive a name for an interface as we can get.
* If the user has specified a comment, use that. Otherwise,
diff --git a/capture_ui_utils.h b/capture_ui_utils.h
index a09db8d7ea..fd2a4e4b1e 100644
--- a/capture_ui_utils.h
+++ b/capture_ui_utils.h
@@ -66,6 +66,12 @@ gboolean capture_dev_user_hassnap_find(const gchar *if_name);
*/
gboolean capture_dev_user_pmode_find(const gchar *if_name);
+/**
+ * Find user-specified capture filter that matches interface
+ * name, if any.
+ */
+gchar* capture_dev_user_cfilter_find(const gchar *if_name);
+
/** Return as descriptive a name for an interface as we can get.
* If the user has specified a comment, use that. Otherwise,
* if capture_interface_list() supplies a description, use that,
diff --git a/epan/prefs.c b/epan/prefs.c
index 6bfe314dd4..0cc1ff92d4 100644
--- a/epan/prefs.c
+++ b/epan/prefs.c
@@ -2431,6 +2431,10 @@ prefs_register_modules(void)
prefs_register_bool_preference(capture_module, "prom_mode", "Capture in promiscuous mode",
"Capture in promiscuous mode?", &prefs.capture_prom_mode);
+ prefs_register_string_preference(capture_module, "devices_filter", "Interface capture filter",
+ "Interface capture filter (Ex: en0(tcp),en1(udp),...)",
+ (const char **)&prefs.capture_devices_filter);
+
prefs_register_bool_preference(capture_module, "pcap_ng", "Capture in Pcap-NG format",
"Capture in Pcap-NG format?", &prefs.capture_pcap_ng);
diff --git a/epan/prefs.h b/epan/prefs.h
index f757bbc818..12093ecd43 100644
--- a/epan/prefs.h
+++ b/epan/prefs.h
@@ -193,6 +193,7 @@ typedef struct _e_prefs {
#endif
gchar *capture_devices_snaplen;
gchar *capture_devices_pmode;
+ gchar *capture_devices_filter;
gboolean capture_prom_mode;
gboolean capture_pcap_ng;
gboolean capture_real_time;
diff --git a/image/status.qrc b/image/status.qrc
index 3b1a653fd2..5d9fb3db4e 100644
--- a/image/status.qrc
+++ b/image/status.qrc
@@ -5,5 +5,6 @@
<file>expert_none.png</file>
<file>expert_note.png</file>
<file>expert_warn.png</file>
+ <file>expert_ok.png</file>
</qresource>
</RCC>
diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt
index 8f3702f7cd..5b4e51e2bd 100644
--- a/ui/qt/CMakeLists.txt
+++ b/ui/qt/CMakeLists.txt
@@ -37,6 +37,7 @@ set(WIRESHARK_QT_HEADERS
color_dialog.h
color_utils.h
column_preferences_frame.h
+ compiled_filter_output.h
decode_as_dialog.h
display_filter_combo.h
display_filter_edit.h
@@ -117,6 +118,7 @@ set(WIRESHARK_QT_SRC
color_utils.cpp
capture_preferences_frame.cpp
column_preferences_frame.cpp
+ compiled_filter_output.cpp
decode_as_dialog.cpp
display_filter_combo.cpp
display_filter_edit.cpp
@@ -197,6 +199,7 @@ set(WIRESHARK_QT_UI
capture_preferences_frame.ui
capture_interfaces_dialog.ui
column_preferences_frame.ui
+ compiled_filter_output.ui
decode_as_dialog.ui
export_object_dialog.ui
export_pdu_dialog.ui
diff --git a/ui/qt/Makefile.am b/ui/qt/Makefile.am
index 71175e8b92..24d346ac55 100644
--- a/ui/qt/Makefile.am
+++ b/ui/qt/Makefile.am
@@ -133,6 +133,8 @@ capture_preferences_frame.cpp capture_preferences_frame.h: ui_capture_preference
column_preferences_frame.cpp column_preferences_frame.h: ui_column_preferences_frame.h
+compiled_filter_output.cpp compiled_filter_output.h: ui_compiled_filter_output.h
+
decode_as_dialog.cpp decode_as_dialog.h: ui_decode_as_dialog.h
export_object_dialog.cpp export_object_dialog.h: ui_export_object_dialog.h
diff --git a/ui/qt/Makefile.common b/ui/qt/Makefile.common
index 7dac9f025d..bce1c96575 100644
--- a/ui/qt/Makefile.common
+++ b/ui/qt/Makefile.common
@@ -33,6 +33,7 @@ NODIST_GENERATED_HEADER_FILES = \
ui_capture_interfaces_dialog.h \
ui_capture_preferences_frame.h \
ui_column_preferences_frame.h \
+ ui_compiled_filter_output.h \
ui_decode_as_dialog.h \
ui_export_object_dialog.h \
ui_export_pdu_dialog.h \
@@ -121,6 +122,7 @@ MOC_HDRS = \
color_utils.h \
capture_preferences_frame.h \
column_preferences_frame.h \
+ compiled_filter_output.h \
decode_as_dialog.h \
display_filter_combo.h \
display_filter_edit.h \
@@ -189,6 +191,7 @@ UI_FILES = \
capture_interfaces_dialog.ui \
capture_preferences_frame.ui \
column_preferences_frame.ui \
+ compiled_filter_output.ui \
decode_as_dialog.ui \
export_object_dialog.ui \
export_pdu_dialog.ui \
@@ -293,6 +296,7 @@ WIRESHARK_QT_SRC = \
color_utils.cpp \
capture_preferences_frame.cpp \
column_preferences_frame.cpp \
+ compiled_filter_output.cpp \
decode_as_dialog.cpp \
display_filter_combo.cpp \
display_filter_edit.cpp \
diff --git a/ui/qt/QtShark.pro b/ui/qt/QtShark.pro
index 5566eb9596..50d1da8a28 100644
--- a/ui/qt/QtShark.pro
+++ b/ui/qt/QtShark.pro
@@ -223,6 +223,7 @@ FORMS += \
capture_preferences_frame.ui \
capture_interfaces_dialog.ui \
column_preferences_frame.ui \
+ compiled_filter_output.ui \
decode_as_dialog.ui \
export_object_dialog.ui \
export_pdu_dialog.ui \
@@ -268,6 +269,7 @@ HEADERS += $$HEADERS_WS_C \
capture_interfaces_dialog.h \
capture_preferences_frame.h \
column_preferences_frame.h \
+ compiled_filter_output.h \
decode_as_dialog.h \
elided_label.h \
export_dissection_dialog.h \
@@ -582,6 +584,7 @@ SOURCES += \
color_dialog.cpp \
color_utils.cpp \
column_preferences_frame.cpp \
+ compiled_filter_output.cpp \
decode_as_dialog.cpp \
display_filter_combo.cpp \
display_filter_edit.cpp \
diff --git a/ui/qt/capture_interfaces_dialog.cpp b/ui/qt/capture_interfaces_dialog.cpp
index effdf1a311..173faf1269 100644
--- a/ui/qt/capture_interfaces_dialog.cpp
+++ b/ui/qt/capture_interfaces_dialog.cpp
@@ -24,13 +24,16 @@
#include <glib.h>
#include "capture_interfaces_dialog.h"
+#include "capture_filter_combo.h"
#include "ui_capture_interfaces_dialog.h"
+#include "compiled_filter_output.h"
#include "wireshark_application.h"
#ifdef HAVE_LIBPCAP
#include <QTimer>
+#include <QMessageBox>
#include "capture_ui_utils.h"
#include "ui/capture_globals.h"
@@ -38,6 +41,7 @@
#include "ui/ui_util.h"
#include "ui/utf8_entities.h"
+#include "ui/preference_utils.h"
#include <cstdio>
#include <epan/prefs.h>
@@ -59,14 +63,51 @@ CaptureInterfacesDialog::CaptureInterfacesDialog(QWidget *parent) :
// XXX - Enable / disable as needed
start_bt_ = ui->buttonBox->addButton(tr("Start"), QDialogButtonBox::YesRole);
- connect(start_bt_, SIGNAL(clicked()), this, SLOT(on_bStart_clicked()));
- stop_bt_ = ui->buttonBox->addButton(tr("Stop"), QDialogButtonBox::NoRole);
- stop_bt_->setEnabled(false);
- connect(stop_bt_, SIGNAL(clicked()), this, SLOT(on_bStop_clicked()));
+ start_bt_->setEnabled((global_capture_opts.num_selected > 0)? true: false);
+ connect(start_bt_, SIGNAL(clicked(bool)), this, SLOT(start_button_clicked()));
- //connect(ui->tbInterfaces,SIGNAL(itemPressed(QTableWidgetItem *)),this,SLOT(tableItemPressed(QTableWidgetItem *)));
connect(ui->tbInterfaces,SIGNAL(itemClicked(QTableWidgetItem *)),this,SLOT(tableItemClicked(QTableWidgetItem *)));
+ connect(ui->tbInterfaces, SIGNAL(itemSelectionChanged()), this, SLOT(tableSelected()));
+ connect(ui->allFilterComboBox, SIGNAL(captureFilterSyntaxChanged(bool)), this, SLOT(allFilterChanged()));
+ connect(this, SIGNAL(interfacesChanged()), ui->allFilterComboBox, SIGNAL(interfacesChanged()));
+}
+
+void CaptureInterfacesDialog::allFilterChanged()
+{
+ QList<QTableWidgetItem*> selected = ui->tbInterfaces->selectedItems();
+ for (int row = 0; row < ui->tbInterfaces->rowCount(); row++)
+ {
+ QTableWidgetItem *it = ui->tbInterfaces->item(row, FILTER);
+ if (selected.contains(it)) {
+ QString str = ui->allFilterComboBox->currentText();
+ it->setText(str);
+ }
+ }
+}
+
+void CaptureInterfacesDialog::tableSelected()
+{
+ interface_t device;
+
+ if (!ui->tbInterfaces->selectedItems().size()) {
+ for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
+ device.selected = false;
+ device.locked = true;
+ global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
+ g_array_insert_val(global_capture_opts.all_ifaces, i, device);
+ }
+ global_capture_opts.num_selected = 0;
+ start_bt_->setEnabled(false);
+ emit setSelectedInterfaces();
+ for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
+ device.locked = false;
+ global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
+ g_array_insert_val(global_capture_opts.all_ifaces, i, device);
+ }
+ }
}
void CaptureInterfacesDialog::tableItemClicked(QTableWidgetItem * item)
@@ -74,28 +115,39 @@ void CaptureInterfacesDialog::tableItemClicked(QTableWidgetItem * item)
Q_UNUSED(item)
interface_t device;
+ guint i;
global_capture_opts.num_selected = 0;
+ QString filter = ui->allFilterComboBox->currentText();
+ QList<QTableWidgetItem*> selected = ui->tbInterfaces->selectedItems();
for (int row = 0; row < ui->tbInterfaces->rowCount(); row++)
{
- bool checked = (ui->tbInterfaces->item(row, 0)->checkState() == Qt::Checked) ? true : false;
- QString interface_name = ui->tbInterfaces->item(row, 1)->text();
-
- device = g_array_index(global_capture_opts.all_ifaces, interface_t, row);
+ QTableWidgetItem *it = ui->tbInterfaces->item(row, INTERFACE);
+ QString interface_name = it->text();
- if (checked == true)
- {
- device.selected = TRUE;
+ for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
+ if (interface_name.compare(device.display_name)) {
+ continue;
+ } else {
+ break;
+ }
+ }
+ if (selected.contains(it)) {
+ device.selected = true;
global_capture_opts.num_selected++;
- global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, row);
- g_array_insert_val(global_capture_opts.all_ifaces, row, device);
+ } else {
+ device.selected = false;
}
- else
- {
- device.selected = FALSE;
- global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, row);
- g_array_insert_val(global_capture_opts.all_ifaces, row, device);
+ global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
+ g_array_insert_val(global_capture_opts.all_ifaces, i, device);
+
+ start_bt_->setEnabled((global_capture_opts.num_selected > 0)? true: false);
+
+ if (filter.compare(QString(""))) {
+ emit interfacesChanged();
}
+ emit setSelectedInterfaces();
}
}
@@ -111,7 +163,17 @@ void CaptureInterfacesDialog::SetTab(int index)
void CaptureInterfacesDialog::on_capturePromModeCheckBox_toggled(bool checked)
{
+ interface_t device;
prefs.capture_prom_mode = checked;
+ for (int row = 0; row < ui->tbInterfaces->rowCount(); row++){
+ device = g_array_index(global_capture_opts.all_ifaces, interface_t, deviceMap[row]);
+ QString device_name = ui->tbInterfaces->item(row, INTERFACE)->text();
+ device.pmode = checked;
+ global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, deviceMap[row]);
+ g_array_insert_val(global_capture_opts.all_ifaces, deviceMap[row], device);
+ QTableWidgetItem *it = ui->tbInterfaces->item(row, PMODE);
+ it->setText(checked? tr("enabled"):tr("disabled"));
+ }
}
void CaptureInterfacesDialog::on_gbStopCaptureAuto_toggled(bool checked)
@@ -155,25 +217,20 @@ void CaptureInterfacesDialog::on_cbResolveTransportNames_toggled(bool checked)
gbl_resolv_flags.transport_name = checked;
}
-void CaptureInterfacesDialog::on_bStart_clicked()
+void CaptureInterfacesDialog::start_button_clicked()
{
qDebug("Starting capture");
- emit startCapture();
+ saveOptionsToPreferences();
+ emit setFilterValid(true);
accept();
}
-void CaptureInterfacesDialog::on_bStop_clicked()
-{
- qDebug("Stop capture");
-
- emit stopCapture();
-}
-
// Not sure why we have to do this manually.
void CaptureInterfacesDialog::on_buttonBox_rejected()
{
+ saveOptionsToPreferences();
reject();
}
@@ -205,27 +262,17 @@ void CaptureInterfacesDialog::UpdateInterfaces()
ui->tbInterfaces->setRowCount(0);
- GList *if_list;
- int err;
- gchar *err_str = NULL;
GList *list;
char *snaplen_string, *linkname;
- //guint i;
link_row *linkr = NULL;
- //interface_t device;
#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
gint buffer;
#endif
gint snaplen;
gboolean hassnap, pmode;
- if_list = capture_interface_list(&err, &err_str,main_window_update);
- if_list = g_list_sort(if_list, if_list_comparator_alph);
-
- // XXX Do we need to check for this? capture_interface_list returns an error if the length is 0.
- if (g_list_length(if_list) > 0) {
+ if (global_capture_opts.all_ifaces->len > 0) {
interface_t device;
- //setDisabled(false);
for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
QList<int> *points;
@@ -236,22 +283,20 @@ void CaptureInterfacesDialog::UpdateInterfaces()
if (device.hidden) {
continue;
}
-
+ deviceMap[ui->tbInterfaces->rowCount()] = i;
QString output;
ui->tbInterfaces->setRowCount(ui->tbInterfaces->rowCount() + 1);
- QTableWidgetItem *cbSelected = new QTableWidgetItem();
- cbSelected->setCheckState(device.selected ? Qt::Checked : Qt::Unchecked);
- ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, CAPTURE, cbSelected);
-
// traffic lines
ui->tbInterfaces->setItemDelegateForColumn(TRAFFIC, new SparkLineDelegate());
points = new QList<int>();
QTableWidgetItem *ti = new QTableWidgetItem();
+ ti->setFlags(Qt::NoItemFlags);
ti->setData(Qt::UserRole, qVariantFromValue(points));
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, TRAFFIC, ti);
+ ui->tbInterfaces->setItemDelegateForColumn(INTERFACE, &combobox_item_delegate_);
output = QString(device.display_name);
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, INTERFACE, new QTableWidgetItem(output));
@@ -300,38 +345,61 @@ void CaptureInterfacesDialog::UpdateInterfaces()
}
#endif
+ combobox_item_delegate_.setTable(ui->tbInterfaces);
+ ui->tbInterfaces->setColumnWidth(LINK, 100);
+ ui->tbInterfaces->setItemDelegateForColumn(LINK, &combobox_item_delegate_);
output = QString(linkname);
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, LINK, new QTableWidgetItem(output));
- output = QString(device.pmode ? "true" : "false");
+ ui->tbInterfaces->setItemDelegateForColumn(PMODE, &combobox_item_delegate_);
+ output = QString(device.pmode ? tr("enabled") : tr("disabled"));
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, PMODE, new QTableWidgetItem(output));
+ ui->tbInterfaces->setItemDelegateForColumn(SNAPLEN, &combobox_item_delegate_);
output = QString(snaplen_string);
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, SNAPLEN, new QTableWidgetItem(output));
-
+#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
+ ui->tbInterfaces->setItemDelegateForColumn(BUFFER, &combobox_item_delegate_);
output = QString().sprintf("%d", device.buffer);
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, BUFFER, new QTableWidgetItem(output));
-
+#else
+ ui->tbInterfaces->setColumnHidden(SNAPLEN+1, true);
+#endif
#if defined (HAVE_PCAP_CREATE)
- output = QString(device.monitor_mode_enabled ? "true" : "false");
+ ui->tbInterfaces->setItemDelegateForColumn(MONITOR, &combobox_item_delegate_);
+ output = QString(device.monitor_mode_supported? (device.monitor_mode_enabled ? tr("enabled") : tr("disabled")) : tr("n/a"));
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, MONITOR, new QTableWidgetItem(output));
-#else
+#elif defined (_WIN32)
ui->tbInterfaces->setColumnHidden(BUFFER+1, true);
+#else
+ ui->tbInterfaces->setColumnHidden(SNAPLEN+2, true);
#endif
+ ui->tbInterfaces->setItemDelegateForColumn(FILTER, &combobox_item_delegate_);
+ gchar* prefFilter = capture_dev_user_cfilter_find(device.name);
+ if (prefFilter) {
+ device.cfilter = g_strdup(prefFilter);
+ }
+ output = QString(device.cfilter);
+ ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, FILTER, new QTableWidgetItem(output));
if (strstr(prefs.capture_device, device.name) != NULL) {
device.selected = TRUE;
global_capture_opts.num_selected++;
- global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
- g_array_insert_val(global_capture_opts.all_ifaces, i, device);
}
if (device.selected) {
- ui->tbInterfaces->item(ui->tbInterfaces->rowCount()-1, 0)->setSelected(true);
+ for (int j = 0; j < NUM_COLUMNS; j++) {
+ if (ui->tbInterfaces->isColumnHidden(j))
+ continue;
+ else
+ ui->tbInterfaces->item(ui->tbInterfaces->rowCount()-1, j)->setSelected(true);
+ }
}
+ global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
+ g_array_insert_val(global_capture_opts.all_ifaces, i, device);
}
}
- free_interface_list(if_list);
resizeEvent(NULL);
+ start_bt_->setEnabled((global_capture_opts.num_selected > 0)? true: false);
if (!stat_timer_) {
updateStatistics();
@@ -343,76 +411,419 @@ void CaptureInterfacesDialog::UpdateInterfaces()
void CaptureInterfacesDialog::updateStatistics(void)
{
- //guint diff;
QList<int> *points = NULL;
+ interface_t device;
+ for (int row = 0; row < ui->tbInterfaces->rowCount(); row++) {
+ points = new QList<int>();
- if (!stat_cache_) {
- // Start gathering statistics using dumpcap
- // We crash (on OS X at least) if we try to do this from ::showEvent.
- stat_cache_ = capture_stat_start(&global_capture_opts);
+ for (guint if_idx = 0; if_idx < global_capture_opts.all_ifaces->len; if_idx++) {
+ device = g_array_index(global_capture_opts.all_ifaces, interface_t, if_idx);
+ QString device_name = ui->tbInterfaces->item(row, INTERFACE)->text();
+ if (device_name.compare(device.display_name) || device.hidden || device.type == IF_PIPE) {
+ continue;
+ }
+ points = ui->tbInterfaces->item(row, TRAFFIC)->data(Qt::UserRole).value<QList<int> *>();
+ points->append(device.packet_diff);
+ QTableWidgetItem *ti = new QTableWidgetItem();
+ ti = ui->tbInterfaces->item(row, TRAFFIC);
+ ti->setData(Qt::UserRole, qVariantFromValue(points));
+ ui->tbInterfaces->viewport()->update();
+ }
}
- if (!stat_cache_) return;
-
+}
+void CaptureInterfacesDialog::on_compileBPF_clicked()
+{
+ QString filter = ui->allFilterComboBox->currentText();
+ if (!filter.compare(QString(""))) {
+ QMessageBox::warning(this, tr("Error"),
+ tr("Set a filter string to compile."));
+ return;
+ }
+ QList<QTableWidgetItem*> selected = ui->tbInterfaces->selectedItems();
+ if (selected.length() == 0) {
+ QMessageBox::warning(this, tr("Error"),
+ tr("No interfaces selected."));
+ return;
+ }
+ QStringList *interfaces = new QStringList();
for (int row = 0; row < ui->tbInterfaces->rowCount(); row++)
{
- //bool checked = (ui->tbInterfaces->item(row, 0)->checkState() == Qt::Checked) ? true : false;
+ QTableWidgetItem *it = ui->tbInterfaces->item(row, INTERFACE);
+ if (selected.contains(it)) {
+ QString str = it->text();
+ interfaces->append(it->text());
+ }
+ }
- //points = new QList<int>();
+ CompiledFilterOutput *cfo = new CompiledFilterOutput(this, interfaces, filter);
-// for (if_idx = 0; if_idx < global_capture_opts.all_ifaces->len; if_idx++) {
-// device = g_array_index(global_capture_opts.all_ifaces, interface_t, if_idx);
-// QString device_name = ui->tbInterfaces->item(row, INTERFACE)->text();
-// if (device_name.compare(device.name) || device.hidden || device.type == IF_PIPE)
-// continue;
+ cfo->show();
+}
- //diff = 0;
-// if (capture_stats(stat_cache_, device.name, &stats)) {
-// if ((int)(stats.ps_recv - device.last_packets) >= 0) {
-// diff = stats.ps_recv - device.last_packets;
-// }
-// device.last_packets = stats.ps_recv;
-// }
+void CaptureInterfacesDialog::saveOptionsToPreferences()
+{
+ interface_t device;
+ gchar *new_prefs, *tmp_prefs;
- points = ui->tbInterfaces->item(row, TRAFFIC)->data(Qt::UserRole).value<QList<int> *>();
- emit getPoints(row, points);
- //ui->tbInterfaces->item
+ for (int col = LINK; col <= FILTER; col++){
+ if (ui->tbInterfaces->isColumnHidden(col)) {
+ continue;
+ }
+ /* All entries are separated by comma. There is also one before the first interface to be able to identify
+ word boundaries. As 'lo' is part of 'nflog' an exact match is necessary. */
+ switch (col) {
+ case LINK:
+ new_prefs = (gchar *)g_malloc0(MAX_VAL_LEN);
+
+ for (int row = 0; row < ui->tbInterfaces->rowCount(); row++) {
+ device = g_array_index(global_capture_opts.all_ifaces, interface_t, deviceMap[row]);
+ if (device.active_dlt == -1) {
+ continue;
+ }
+ g_strlcat(new_prefs, ",", MAX_VAL_LEN);
+ tmp_prefs = g_strdup_printf("%s(%d)", device.name, device.active_dlt);
+ g_strlcat(new_prefs, tmp_prefs, MAX_VAL_LEN);
+ g_free(tmp_prefs);
+ }
+ g_free(prefs.capture_devices_linktypes);
+ prefs.capture_devices_linktypes = new_prefs;
+ break;
+#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
+ case BUFFER:
+ new_prefs = (gchar *)g_malloc0(MAX_VAL_LEN);
+
+ for (int row = 0; row < ui->tbInterfaces->rowCount(); row++) {
+ device = g_array_index(global_capture_opts.all_ifaces, interface_t, deviceMap[row]);
+ if (device.buffer == -1) {
+ continue;
+ }
+ g_strlcat(new_prefs, ",", MAX_VAL_LEN);
+ tmp_prefs = g_strdup_printf("%s(%d)", device.name, device.buffer);
+ g_strlcat(new_prefs, tmp_prefs, MAX_VAL_LEN);
+ g_free(tmp_prefs);
+ }
+ g_free(prefs.capture_devices_buffersize);
+ prefs.capture_devices_buffersize = new_prefs;
+ break;
+#endif
+ case SNAPLEN:
+ new_prefs = (gchar *)g_malloc0(MAX_VAL_LEN);
+
+ for (int row = 0; row < ui->tbInterfaces->rowCount(); row++) {
+ device = g_array_index(global_capture_opts.all_ifaces, interface_t, deviceMap[row]);
+ g_strlcat(new_prefs, ",", MAX_VAL_LEN);
+ tmp_prefs = g_strdup_printf("%s:%d(%d)", device.name, device.has_snaplen, (device.has_snaplen?device.snaplen:WTAP_MAX_PACKET_SIZE));
+ g_strlcat(new_prefs, tmp_prefs, MAX_VAL_LEN);
+ g_free(tmp_prefs);
+ }
+ g_free(prefs.capture_devices_snaplen);
+ prefs.capture_devices_snaplen = new_prefs;
+ break;
+ case PMODE:
+ new_prefs = (gchar *)g_malloc0(MAX_VAL_LEN);
+
+ for (int row = 0; row < ui->tbInterfaces->rowCount(); row++) {
+ device = g_array_index(global_capture_opts.all_ifaces, interface_t, deviceMap[row]);
+ if (device.pmode == -1) {
+ continue;
+ }
+ g_strlcat(new_prefs, ",", MAX_VAL_LEN);
+ tmp_prefs = g_strdup_printf("%s(%d)", device.name, device.pmode);
+ g_strlcat(new_prefs, tmp_prefs, MAX_VAL_LEN);
+ g_free(tmp_prefs);
+ }
+ g_free(prefs.capture_devices_pmode);
+ prefs.capture_devices_pmode = new_prefs;
+ break;
+#ifdef HAVE_PCAP_CREATE
+ case MONITOR:
+ new_prefs = (gchar *)g_malloc0(MAX_VAL_LEN);
+
+ for (int row = 0; row < ui->tbInterfaces->rowCount(); row++) {
+ device = g_array_index(global_capture_opts.all_ifaces, interface_t, deviceMap[row]);
+ if (!device.monitor_mode_supported || (device.monitor_mode_supported && !device.monitor_mode_enabled)) {
+ continue;
+ }
+ g_strlcat(new_prefs, ",", MAX_VAL_LEN);
+ tmp_prefs = g_strdup_printf("%s", device.name);
+ g_strlcat(new_prefs, tmp_prefs, MAX_VAL_LEN);
+ g_free(tmp_prefs);
+ }
+ g_free(prefs.capture_devices_monitor_mode);
+ prefs.capture_devices_monitor_mode = new_prefs;
+ break;
+#endif
+ case FILTER:
+ new_prefs = (gchar *)g_malloc0(MAX_VAL_LEN);
+
+ for (int row = 0; row < ui->tbInterfaces->rowCount(); row++) {
+ device = g_array_index(global_capture_opts.all_ifaces, interface_t, deviceMap[row]);
+ if (!device.cfilter) {
+ continue;
+ }
+ g_strlcat(new_prefs, ",", MAX_VAL_LEN);
+ tmp_prefs = g_strdup_printf("%s(%s)", device.name, device.cfilter);
+ g_strlcat(new_prefs, tmp_prefs, MAX_VAL_LEN);
+ g_free(tmp_prefs);
+ }
+ g_free(prefs.capture_devices_filter);
+ prefs.capture_devices_filter = new_prefs;
+ break;
+ }
+ }
+ if (!prefs.gui_use_pref_save) {
+ prefs_main_write();
+ }
+}
- //ui->tbInterfaces->setItemDelegateForColumn(TRAFFIC, new SparkLineDelegate());
- //points = new QList<int>();
- //QTableWidgetItem *ti = new QTableWidgetItem();
- //ti->setData(Qt::UserRole, qVariantFromValue(points));
- QTableWidgetItem *ti = ui->tbInterfaces->item(ui->tbInterfaces->rowCount()-1, TRAFFIC);
- ti->setData(Qt::UserRole, qVariantFromValue(points));
- //ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, TRAFFIC, ti);
+#include <QComboBox>
- //points->append(diff);
- ui->tbInterfaces->viewport()->update();
-// global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, if_idx);
-// g_array_insert_val(global_capture_opts.all_ifaces, if_idx, device);
+TbInterfacesDelegate::TbInterfacesDelegate(QObject *parent)
+ : QStyledItemDelegate(parent)
+{
+}
+
+
+TbInterfacesDelegate::~TbInterfacesDelegate()
+{
+}
+
+
+QWidget* TbInterfacesDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const
+{
+ Q_UNUSED(option);
+ QWidget *w = NULL;
+#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
+ gint buffer = DEFAULT_CAPTURE_BUFFER_SIZE;
+#endif
+ guint snap = WTAP_MAX_PACKET_SIZE;
+ if (index.column() > 1) {
+ interface_t device;
+ QTableWidgetItem *it = table->item(index.row(), INTERFACE);
+ QString interface_name = it->text();
+ for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
+#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
+ buffer = device.buffer;
+#endif
+ snap = device.snaplen;
+ if (interface_name.compare(device.display_name) || device.hidden || device.type == IF_PIPE) {
+ continue;
+ } else {
+ break;
+ }
+ }
+ switch (index.column()) {
+ case INTERFACE:
+ break;
+ case LINK:
+ {
+ GList *list;
+ link_row *temp;
+ QComboBox *cb = new QComboBox(parent);
+ for (list=device.links; list!=NULL; list=g_list_next(list)) {
+ temp = (link_row*)(list->data);
+ cb->addItem(QString("%1").arg(temp->name));
+ }
+ connect(cb, SIGNAL(currentIndexChanged(QString)), this, SLOT(link_changed(QString)));
+ w = (QWidget*) cb;
+ break;
+ }
+ case PMODE:
+ {
+ // Create the combobox and populate it
+ QComboBox *cb = new QComboBox(parent);
+ cb->addItem(QString(tr("enabled")));
+ cb->addItem(QString(tr("disabled")));
+ connect(cb, SIGNAL(currentIndexChanged(QString)), this, SLOT(pmode_changed(QString)));
+ w = (QWidget*) cb;
+ break;
+ }
+#if defined (HAVE_PCAP_CREATE)
+ case MONITOR:
+ {
+ if (index.data().toString().compare(QString("n/a"))) {
+ QComboBox *cb = new QComboBox(parent);
+ cb->addItem(QString(tr("enabled")));
+ cb->addItem(QString(tr("disabled")));
+ connect(cb, SIGNAL(currentIndexChanged(QString)), this, SLOT(monitor_changed(QString)));
+ w = (QWidget*) cb;
+ }
+ break;
+ }
+#endif
+ case SNAPLEN:
+ {
+ QSpinBox *sb = new QSpinBox(parent);
+ sb->setRange(1, 65535);
+ sb->setValue(snap);
+ sb->setWrapping(true);
+ connect(sb, SIGNAL(valueChanged(int)), this, SLOT(snaplen_changed(int)));
+ w = (QWidget*) sb;
+ break;
+ }
+#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
+ case BUFFER:
+ {
+ QSpinBox *sb = new QSpinBox(parent);
+ sb->setRange(1, 65535);
+ sb->setValue(buffer);
+ sb->setWrapping(true);
+ connect(sb, SIGNAL(valueChanged(int)), this, SLOT(buffer_changed(int)));
+ w = (QWidget*) sb;
+ break;
+ }
+#endif
+ case FILTER:
+ {
+ CaptureFilterCombo *cf = new CaptureFilterCombo(parent);
+ w = (QWidget*) cf;
+ }
+ }
}
+ return w;
}
-/*
-void CaptureInterfacesDialog::on_tbInterfaces_hideEvent(QHideEvent *evt)
+bool TbInterfacesDelegate::eventFilter(QObject *object, QEvent *event)
{
- Q_UNUSED(evt);
- if (stat_timer_) stat_timer_->stop();
- if (stat_cache_) {
- capture_stat_stop(stat_cache_);
- stat_cache_ = NULL;
+ QComboBox * comboBox = dynamic_cast<QComboBox*>(object);
+ if (comboBox) {
+ if (event->type() == QEvent::MouseButtonRelease) {
+ comboBox->showPopup();
+ return true;
+ }
+ } else {
+ return QStyledItemDelegate::eventFilter( object, event );
}
+ return false;
}
-void CaptureInterfacesDialog::on_tbInterfaces_showEvent(QShowEvent *evt)
+void TbInterfacesDelegate::pmode_changed(QString index)
{
- Q_UNUSED(evt);
- if (stat_timer_) stat_timer_->start(stat_update_interval_);
+ interface_t device;
+ guint i;
+ QTableWidgetItem *it = table->item(table->currentRow(), INTERFACE);
+ QString interface_name = it->text();
+ for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
+ if (interface_name.compare(device.display_name) || device.hidden || device.type == IF_PIPE) {
+ continue;
+ } else {
+ break;
+ }
+ }
+ if (!index.compare(QString(tr("enabled")))) {
+ device.pmode = true;
+ } else {
+ device.pmode = false;
+ }
+
+ global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
+ g_array_insert_val(global_capture_opts.all_ifaces, i, device);
+}
+
+#if defined (HAVE_PCAP_CREATE)
+void TbInterfacesDelegate::monitor_changed(QString index)
+{
+ interface_t device;
+ guint i;
+ QTableWidgetItem *it = table->item(table->currentRow(), INTERFACE);
+ QString interface_name = it->text();
+ for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
+ if (interface_name.compare(device.display_name) || device.hidden || device.type == IF_PIPE) {
+ continue;
+ } else {
+ break;
+ }
+ }
+ if (!index.compare(QString(tr("enabled")))) {
+ device.monitor_mode_enabled = true;
+ } else {
+ device.monitor_mode_enabled = false;
+ }
+ global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
+ g_array_insert_val(global_capture_opts.all_ifaces, i, device);
}
-*/
+#endif
+
+void TbInterfacesDelegate::link_changed(QString index)
+{
+ GList *list;
+ link_row *temp;
+ interface_t device;
+ guint i;
+
+ QTableWidgetItem *it = table->item(table->currentRow(), INTERFACE);
+ QString interface_name = it->text();
+ for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
+ if (interface_name.compare(device.display_name) || device.hidden || device.type == IF_PIPE) {
+ continue;
+ } else {
+ break;
+ }
+ }
+ for (list = device.links; list != NULL; list = g_list_next(list)) {
+ temp = (link_row*) (list->data);
+ if (!index.compare(temp->name)) {
+ device.active_dlt = temp->dlt;
+ }
+ }
+ global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
+ g_array_insert_val(global_capture_opts.all_ifaces, i, device);
+}
+
+void TbInterfacesDelegate::snaplen_changed(int value)
+{
+ interface_t device;
+ guint i;
+ QTableWidgetItem *it = table->item(table->currentRow(), INTERFACE);
+ QString interface_name = it->text();
+ for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
+ if (interface_name.compare(device.display_name) || device.hidden || device.type == IF_PIPE) {
+ continue;
+ } else {
+ break;
+ }
+ }
+ if (value != WTAP_MAX_PACKET_SIZE) {
+ device.has_snaplen = true;
+ device.snaplen = value;
+ } else {
+ device.has_snaplen = false;
+ device.snaplen = WTAP_MAX_PACKET_SIZE;
+ }
+ global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
+ g_array_insert_val(global_capture_opts.all_ifaces, i, device);
+}
+
+void TbInterfacesDelegate::buffer_changed(int value)
+{
+#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
+ interface_t device;
+ guint i;
+ QTableWidgetItem *it = table->item(table->currentRow(), INTERFACE);
+ QString interface_name = it->text();
+ for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
+ if (interface_name.compare(device.display_name) || device.hidden || device.type == IF_PIPE) {
+ continue;
+ } else {
+ break;
+ }
+ }
+ device.buffer = value;
+ global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
+ g_array_insert_val(global_capture_opts.all_ifaces, i, device);
+#endif
+}
+
#endif /* HAVE_LIBPCAP */
/*
diff --git a/ui/qt/capture_interfaces_dialog.h b/ui/qt/capture_interfaces_dialog.h
index 0adb046166..32f5b71604 100644
--- a/ui/qt/capture_interfaces_dialog.h
+++ b/ui/qt/capture_interfaces_dialog.h
@@ -41,18 +41,13 @@ typedef struct if_stat_cache_s if_stat_cache_t;
*/
enum
{
- CAPTURE = 0,
- INTERFACE,
+ INTERFACE = 0,
TRAFFIC,
LINK,
PMODE,
SNAPLEN,
-#if defined(HAVE_PCAP_CREATE)
BUFFER,
MONITOR,
-#elif defined(_WIN32) && !defined(HAVE_PCAP_CREATE)
- BUFFER,
-#endif
FILTER,
NUM_COLUMNS
};
@@ -62,6 +57,32 @@ namespace Ui {
class CaptureInterfacesDialog;
}
+#include <QStyledItemDelegate>
+
+class TbInterfacesDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+private:
+ QTableWidget* table;
+
+public:
+ TbInterfacesDelegate(QObject *parent = 0);
+ ~TbInterfacesDelegate();
+
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+ void setTable(QTableWidget* tb) { table = tb; };
+ bool eventFilter(QObject *object, QEvent *event);
+
+private slots:
+ void pmode_changed(QString index);
+#if defined (HAVE_PCAP_CREATE)
+ void monitor_changed(QString index);
+#endif
+ void link_changed(QString index);
+ void snaplen_changed(int value);
+ void buffer_changed(int value);
+};
+
class CaptureInterfacesDialog : public QDialog
{
Q_OBJECT
@@ -72,7 +93,6 @@ public:
void SetTab(int index);
void UpdateInterfaces();
- //void updateStatistics(void);
private slots:
void on_capturePromModeCheckBox_toggled(bool checked);
@@ -82,21 +102,24 @@ private slots:
void on_gbNewFileAuto_toggled(bool checked);
void on_cbExtraCaptureInfo_toggled(bool checked);
void on_cbResolveMacAddresses_toggled(bool checked);
+ void on_compileBPF_clicked();
void on_cbResolveNetworkNames_toggled(bool checked);
void on_cbResolveTransportNames_toggled(bool checked);
- void on_bStart_clicked();
- void on_bStop_clicked();
+ void start_button_clicked();
void on_buttonBox_rejected();
void on_buttonBox_helpRequested();
void tableItemClicked(QTableWidgetItem * item);
+ void tableSelected();
void updateStatistics(void);
- //void on_tbInterfaces_hideEvent(QHideEvent *evt);
- //void on_tbInterfaces_showEvent(QShowEvent *evt);
+ void allFilterChanged();
signals:
void startCapture();
void stopCapture();
void getPoints(int row, PointList *pts);
+ void setSelectedInterfaces();
+ void setFilterValid(bool valid);
+ void interfacesChanged();
private:
Ui::CaptureInterfacesDialog *ui;
@@ -106,6 +129,10 @@ private:
QPushButton *stop_bt_;
if_stat_cache_t *stat_cache_;
QTimer *stat_timer_;
+ TbInterfacesDelegate combobox_item_delegate_;
+ QMap<int, int> deviceMap;
+
+ void saveOptionsToPreferences();
};
#endif /* HAVE_LIBPCAP */
diff --git a/ui/qt/capture_interfaces_dialog.ui b/ui/qt/capture_interfaces_dialog.ui
index df3e77b8e9..96d48893a2 100644
--- a/ui/qt/capture_interfaces_dialog.ui
+++ b/ui/qt/capture_interfaces_dialog.ui
@@ -27,7 +27,7 @@
<item>
<widget class="QTableWidget" name="tbInterfaces">
<property name="editTriggers">
- <set>QAbstractItemView::NoEditTriggers</set>
+ <set>QAbstractItemView::DoubleClicked</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
@@ -45,15 +45,10 @@
<number>0</number>
</property>
<property name="columnCount">
- <number>9</number>
+ <number>8</number>
</property>
<column>
<property name="text">
- <string>Capture</string>
- </property>
- </column>
- <column>
- <property name="text">
<string>Interface</string>
</property>
</column>
@@ -104,36 +99,47 @@
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;You probably want to enable this. Usually a network card will only capture the traffic sent to its own network address. If you want to capture all traffic that the network card can &amp;quot;see&amp;quot;, mark this option. See the FAQ for some more details of capturing packets from a switched network.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
- <string>Capture packets in promiscuous mode</string>
+ <string>Capture packets in promiscuous mode on all interfaces</string>
</property>
</widget>
</item>
<item>
- <widget class="QCheckBox" name="captureShowInfoCheckBox">
- <property name="toolTip">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Show the capture summary dialog while capturing.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
- <property name="text">
- <string>Show the capture summary dialog while capturing</string>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>13</width>
+ <height>3</height>
+ </size>
</property>
- </widget>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Capture Filter for selected Interfaces:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="CaptureFilterCombo" name="allFilterComboBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
</layout>
</item>
<item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>48</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QPushButton" name="bClose_2">
@@ -141,22 +147,16 @@
<bool>false</bool>
</property>
<property name="text">
- <string>Add pipe...</string>
+ <string>Manage Interfaces...</string>
</property>
</widget>
</item>
<item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>18</height>
- </size>
+ <widget class="QPushButton" name="compileBPF">
+ <property name="text">
+ <string>Compile BPFs</string>
</property>
- </spacer>
+ </widget>
</item>
</layout>
</item>
@@ -629,6 +629,13 @@
</item>
</layout>
</widget>
+ <customwidgets>
+ <customwidget>
+ <class>CaptureFilterCombo</class>
+ <extends>QComboBox</extends>
+ <header location="global">capture_filter_combo.h</header>
+ </customwidget>
+ </customwidgets>
<resources/>
<connections/>
</ui>
diff --git a/ui/qt/compiled_filter_output.cpp b/ui/qt/compiled_filter_output.cpp
new file mode 100644
index 0000000000..63265cd450
--- /dev/null
+++ b/ui/qt/compiled_filter_output.cpp
@@ -0,0 +1,115 @@
+/* compiled_filter_output.cpp
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+#include "ui_compiled_filter_output.h"
+#include "compiled_filter_output.h"
+
+#include "capture_opts.h"
+#include "wtap.h"
+#include <pcap.h>
+#include "ui/capture_globals.h"
+
+CompiledFilterOutput::CompiledFilterOutput(QWidget *parent, QStringList *intList, QString &compile_filter) :
+ QDialog(parent),
+ intList_(intList),
+ compile_filter_(compile_filter),
+ ui(new Ui::CompiledFilterOutput)
+{
+ ui->setupUi(this);
+
+ interface_list_ = ui->interfaceList;
+#if GLIB_CHECK_VERSION(2,31,0)
+ pcap_compile_mtx = g_new(GMutex,1);
+ g_mutex_init(pcap_compile_mtx);
+#else
+ pcap_compile_mtx = g_mutex_new();
+#endif
+ compileFilter();
+ connect(interface_list_, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), this, SLOT(compile_clicked(QListWidgetItem*, QListWidgetItem*)));
+}
+
+CompiledFilterOutput::~CompiledFilterOutput()
+{
+ delete ui;
+}
+
+
+void CompiledFilterOutput::compileFilter()
+{
+ struct bpf_program fcode;
+
+ foreach (QString interfaces, *intList_) {
+ for (guint 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 (interfaces.compare(device.display_name)) {
+ continue;
+ } else {
+ pcap_t *pd = pcap_open_dead(device.active_dlt, WTAP_MAX_PACKET_SIZE);
+ g_mutex_lock(pcap_compile_mtx);
+ if (pcap_compile(pd, &fcode, compile_filter_.toUtf8().constData(), 1, 0) < 0) {
+ compile_results.insert(interfaces, QString("%1").arg(g_strdup(pcap_geterr(pd))));
+ g_mutex_unlock(pcap_compile_mtx);
+ ui->interfaceList->addItem(new QListWidgetItem(QIcon(":expert/expert_error.png"),interfaces));
+ } else {
+ GString *bpf_code_dump = g_string_new("");
+ struct bpf_insn *insn = fcode.bf_insns;
+ int ii, n = fcode.bf_len;
+ gchar *bpf_code_str;
+ for (ii = 0; ii < n; ++insn, ++ii) {
+ g_string_append(bpf_code_dump, bpf_image(insn, ii));
+ g_string_append(bpf_code_dump, "\n");
+ }
+ bpf_code_str = g_string_free(bpf_code_dump, FALSE);
+ g_mutex_unlock(pcap_compile_mtx);
+ compile_results.insert(interfaces, QString("%1").arg(g_strdup(bpf_code_str)));
+ ui->interfaceList->addItem(new QListWidgetItem(QIcon(":expert/expert_ok.png"),interfaces));
+ }
+ break;
+ }
+ }
+ }
+}
+
+
+void CompiledFilterOutput::compile_clicked(QListWidgetItem *current, QListWidgetItem *previous)
+{
+ Q_UNUSED(previous);
+
+ QString interface = current->text();
+ QHash<QString, QString>::const_iterator iter = compile_results.find(interface);
+ ui->filterList->clear();
+ ui->filterList->setText(iter.value());
+}
+
+//
+// Editor modelines - http://www.wireshark.org/tools/modelines.html
+//
+// Local variables:
+// c-basic-offset: 4
+// tab-width: 4
+// indent-tabs-mode: nil
+// End:
+//
+// vi: set shiftwidth=4 tabstop=4 expandtab:
+// :indentSize=4:tabSize=4:noTabs=true:
+//
diff --git a/ui/qt/compiled_filter_output.h b/ui/qt/compiled_filter_output.h
new file mode 100644
index 0000000000..3da688d3f7
--- /dev/null
+++ b/ui/qt/compiled_filter_output.h
@@ -0,0 +1,72 @@
+/* compiled_filter_output.h
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef COMPILEDFILTEROUTPUT_H
+#define COMPILEDFILTEROUTPUT_H
+
+#include "config.h"
+#include <QDialog>
+#include <QList>
+#include <QHash>
+#include <QListWidgetItem>
+
+#include <glib.h>
+
+namespace Ui {
+class CompiledFilterOutput;
+}
+
+class CompiledFilterOutput : public QDialog
+{
+ Q_OBJECT
+
+private:
+ QStringList *intList_;
+ QString &compile_filter_;
+ Ui::CompiledFilterOutput *ui;
+ GMutex *pcap_compile_mtx;
+ QHash<QString, QString> compile_results;
+ QListWidget *interface_list_;
+ void compileFilter();
+
+public:
+ explicit CompiledFilterOutput(QWidget *parent = 0, QStringList *intList = new QStringList(), QString &filter = *new QString());
+
+ ~CompiledFilterOutput();
+
+private slots:
+ void compile_clicked(QListWidgetItem* current, QListWidgetItem* previous);
+};
+
+#endif // COMPILEDFILTEROUTPUT_H
+
+//
+// Editor modelines - http://www.wireshark.org/tools/modelines.html
+//
+// Local variables:
+// c-basic-offset: 4
+// tab-width: 4
+// indent-tabs-mode: nil
+// End:
+//
+// vi: set shiftwidth=4 tabstop=4 expandtab:
+// :indentSize=4:tabSize=4:noTabs=true:
+//
diff --git a/ui/qt/compiled_filter_output.ui b/ui/qt/compiled_filter_output.ui
new file mode 100644
index 0000000000..9a3b057f4a
--- /dev/null
+++ b/ui/qt/compiled_filter_output.ui
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>CompiledFilterOutput</class>
+ <widget class="QDialog" name="CompiledFilterOutput">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>654</width>
+ <height>380</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Compiled Filter Output</string>
+ </property>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>340</y>
+ <width>631</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Ok</set>
+ </property>
+ <property name="centerButtons">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QListWidget" name="interfaceList">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>20</y>
+ <width>241</width>
+ <height>311</height>
+ </rect>
+ </property>
+ <property name="editTriggers">
+ <set>QAbstractItemView::NoEditTriggers</set>
+ </property>
+ </widget>
+ <widget class="QTextBrowser" name="filterList">
+ <property name="geometry">
+ <rect>
+ <x>260</x>
+ <y>20</y>
+ <width>381</width>
+ <height>311</height>
+ </rect>
+ </property>
+ </widget>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>CompiledFilterOutput</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>CompiledFilterOutput</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/ui/qt/interface_tree.cpp b/ui/qt/interface_tree.cpp
index ca0daae526..20fcd6c791 100644
--- a/ui/qt/interface_tree.cpp
+++ b/ui/qt/interface_tree.cpp
@@ -254,6 +254,7 @@ void InterfaceTree::updateStatistics(void) {
if (capture_stats(stat_cache_, device.name, &stats)) {
if ((int)(stats.ps_recv - device.last_packets) >= 0) {
diff = stats.ps_recv - device.last_packets;
+ device.packet_diff = diff;
}
device.last_packets = stats.ps_recv;
}
@@ -306,6 +307,30 @@ void InterfaceTree::updateSelectedInterfaces()
#endif // HAVE_LIBPCAP
}
+void InterfaceTree::setSelectedInterfaces()
+{
+#ifdef HAVE_LIBPCAP
+ interface_t device;
+ QTreeWidgetItemIterator iter(this);
+
+ while (*iter) {
+ QString device_name = (*iter)->data(0, Qt::UserRole).value<QString>();
+ for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
+ if (device_name.compare(QString().fromUtf8(device.name)) == 0) {
+ (*iter)->setSelected(device.selected);
+ global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
+ g_array_insert_val(global_capture_opts.all_ifaces, i, device);
+ break;
+ }
+ global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
+ g_array_insert_val(global_capture_opts.all_ifaces, i, device);
+ }
+ iter++;
+ }
+#endif // HAVE_LIBPCAP
+}
+
/*
* Editor modelines
*
diff --git a/ui/qt/interface_tree.h b/ui/qt/interface_tree.h
index a6c883d3b5..6a63590221 100644
--- a/ui/qt/interface_tree.h
+++ b/ui/qt/interface_tree.h
@@ -64,6 +64,7 @@ public slots:
// change_interface_selection_for_all
//void getPoints(int row, QList<int> *pts);
void getPoints(int row, PointList *pts);
+ void setSelectedInterfaces();
private slots:
void getInterfaceList();
diff --git a/ui/qt/main_window.cpp b/ui/qt/main_window.cpp
index e862f01d99..9a4adce43e 100644
--- a/ui/qt/main_window.cpp
+++ b/ui/qt/main_window.cpp
@@ -299,6 +299,8 @@ MainWindow::MainWindow(QWidget *parent) :
connect(&capture_interfaces_dialog_, SIGNAL(getPoints(int,PointList*)),
this->main_welcome_->getInterfaceTree(), SLOT(getPoints(int,PointList*)));
+ connect(&capture_interfaces_dialog_, SIGNAL(setSelectedInterfaces()),
+ this->main_welcome_->getInterfaceTree(), SLOT(setSelectedInterfaces()));
#endif
main_ui_->mainStack->setCurrentWidget(main_welcome_);
@@ -1392,7 +1394,7 @@ void MainWindow::setMenusForFollowStream()
main_ui_->actionAnalyzeFollowSSLStream->setEnabled(false);
proto_get_frame_protocols(cap_file_->edt->pi.layers, NULL, &is_tcp, &is_udp, NULL, NULL);
-
+
if (is_tcp)
{
main_ui_->actionAnalyzeFollowTCPStream->setEnabled(true);
diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h
index 87b3ac5a2d..9534d6b2f5 100644
--- a/ui/qt/main_window.h
+++ b/ui/qt/main_window.h
@@ -205,6 +205,8 @@ private slots:
void redissectPackets();
void recreatePacketList();
+ void startInterfaceCapture(bool valid);
+
void setFeaturesEnabled(bool enabled = true);
void addDisplayFilterButton(QString df_text);
diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp
index e9d8166743..69f5d61f1a 100644
--- a/ui/qt/main_window_slots.cpp
+++ b/ui/qt/main_window_slots.cpp
@@ -1101,6 +1101,12 @@ void MainWindow::captureFilterSyntaxChanged(bool valid)
interfaceSelectionChanged();
}
+void MainWindow::startInterfaceCapture(bool valid)
+{
+ capture_filter_valid_ = valid;
+ startCapture();
+}
+
void MainWindow::redissectPackets()
{
if (cap_file_)
@@ -2320,6 +2326,7 @@ void MainWindow::on_actionSummary_triggered()
#ifdef HAVE_LIBPCAP
void MainWindow::on_actionCaptureInterfaces_triggered()
{
+ connect(&capture_interfaces_dialog_, SIGNAL(setFilterValid(bool)), this, SLOT(startInterfaceCapture(bool)));
capture_interfaces_dialog_.SetTab(0);
capture_interfaces_dialog_.UpdateInterfaces();