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 @@
expert_none.png
expert_note.png
expert_warn.png
+ expert_ok.png
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
#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
+#include
#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
#include
@@ -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 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 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();
+ QTableWidgetItem *it = ui->tbInterfaces->item(row, INTERFACE);
+ QString interface_name = it->text();
- device = g_array_index(global_capture_opts.all_ifaces, interface_t, row);
-
- 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 *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();
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));
-
-#if defined (HAVE_PCAP_CREATE)
- output = QString(device.monitor_mode_enabled ? "true" : "false");
- ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, MONITOR, new QTableWidgetItem(output));
#else
- ui->tbInterfaces->setColumnHidden(BUFFER+1, true);
+ ui->tbInterfaces->setColumnHidden(SNAPLEN+1, true);
#endif
+#if defined (HAVE_PCAP_CREATE)
+ 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));
+#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 *points = NULL;
+ interface_t device;
+ for (int row = 0; row < ui->tbInterfaces->rowCount(); row++) {
+ points = new QList();
- 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 *>();
+ 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 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();
+ 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 *>();
- 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);
- //ui->tbInterfaces->setItemDelegateForColumn(TRAFFIC, new SparkLineDelegate());
- //points = new QList();
- //QTableWidgetItem *ti = new QTableWidgetItem();
- //ti->setData(Qt::UserRole, qVariantFromValue(points));
+ 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);
- 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);
+ 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);
- //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);
+ 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();
}
}
-/*
-void CaptureInterfacesDialog::on_tbInterfaces_hideEvent(QHideEvent *evt)
+
+#include
+
+TbInterfacesDelegate::TbInterfacesDelegate(QObject *parent)
+ : QStyledItemDelegate(parent)
{
- Q_UNUSED(evt);
- if (stat_timer_) stat_timer_->stop();
- if (stat_cache_) {
- capture_stat_stop(stat_cache_);
- stat_cache_ = NULL;
- }
}
-void CaptureInterfacesDialog::on_tbInterfaces_showEvent(QShowEvent *evt)
+
+TbInterfacesDelegate::~TbInterfacesDelegate()
{
- Q_UNUSED(evt);
- if (stat_timer_) stat_timer_->start(stat_update_interval_);
}
-*/
+
+
+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;
+}
+
+bool TbInterfacesDelegate::eventFilter(QObject *object, QEvent *event)
+{
+ QComboBox * comboBox = dynamic_cast(object);
+ if (comboBox) {
+ if (event->type() == QEvent::MouseButtonRelease) {
+ comboBox->showPopup();
+ return true;
+ }
+ } else {
+ return QStyledItemDelegate::eventFilter( object, event );
+ }
+ return false;
+}
+
+void TbInterfacesDelegate::pmode_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.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
+
+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 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 @@
-
- QAbstractItemView::NoEditTriggers
+ QAbstractItemView::DoubleClicked
true
@@ -45,13 +45,8 @@
0
- 9
+ 8
-
-
- Capture
-
-
Interface
@@ -104,35 +99,46 @@
<html><head/><body><p>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 "see", mark this option. See the FAQ for some more details of capturing packets from a switched network.</p></body></html>
- Capture packets in promiscuous mode
+ Capture packets in promiscuous mode on all interfaces
-
-
-
- <html><head/><body><p>Show the capture summary dialog while capturing.</p></body></html>
+
+
+ Qt::Horizontal
-
- Show the capture summary dialog while capturing
+
+
+ 13
+ 3
+
-
+
+
+ -
+
+
-
+
+
+ Capture Filter for selected Interfaces:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 48
-
-
-
-
-
-
@@ -141,22 +147,16 @@
false
- Add pipe...
+ Manage Interfaces...
-
-
-
- Qt::Vertical
+
+
+ Compile BPFs
-
-
- 20
- 18
-
-
-
+
@@ -629,6 +629,13 @@
+
+
+ CaptureFilterCombo
+ QComboBox
+
+
+
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
+ * 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
+#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::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
+ * 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
+#include
+#include
+#include
+
+#include
+
+namespace Ui {
+class CompiledFilterOutput;
+}
+
+class CompiledFilterOutput : public QDialog
+{
+ Q_OBJECT
+
+private:
+ QStringList *intList_;
+ QString &compile_filter_;
+ Ui::CompiledFilterOutput *ui;
+ GMutex *pcap_compile_mtx;
+ QHash 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 @@
+
+
+ CompiledFilterOutput
+
+
+
+ 0
+ 0
+ 654
+ 380
+
+
+
+ Compiled Filter Output
+
+
+
+
+ 10
+ 340
+ 631
+ 32
+
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Ok
+
+
+ true
+
+
+
+
+
+ 10
+ 20
+ 241
+ 311
+
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+
+
+
+ 260
+ 20
+ 381
+ 311
+
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ CompiledFilterOutput
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+
+
+ buttonBox
+ rejected()
+ CompiledFilterOutput
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+
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();
+ 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 *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();