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>
This commit is contained in:
Irene Ruengeler 2014-06-04 11:03:59 +02:00 committed by Anders Broman
parent 428c5b9448
commit df8c4bf264
21 changed files with 986 additions and 172 deletions

View File

@ -125,6 +125,7 @@ typedef struct interface_tag {
remote_options remote_opts; remote_options remote_opts;
#endif #endif
guint32 last_packets; guint32 last_packets;
guint32 packet_diff;
if_info_t if_info; if_info_t if_info;
gboolean selected; gboolean selected;
gboolean hidden; gboolean hidden;

View File

@ -101,7 +101,7 @@ capture_dev_user_descr_find(const gchar *if_name)
gint gint
capture_dev_user_linktype_find(const gchar *if_name) capture_dev_user_linktype_find(const gchar *if_name)
{ {
gchar *p, *next; gchar *p, *next, *tmpname;
long linktype; long linktype;
if ((prefs.capture_devices_linktypes == NULL) || 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 */ /* There are no link-layer header types */
return -1; return -1;
} }
tmpname = g_strdup_printf(",%s(", if_name);
if ((p = strstr(prefs.capture_devices_linktypes, if_name)) == NULL) { if ((p = strstr(prefs.capture_devices_linktypes, tmpname)) == NULL) {
/* There are, but there isn't one for this interface. */ /* There are, but there isn't one for this interface. */
return -1; return -1;
} }
p += strlen(if_name) + 1; p += strlen(if_name) + 2;
linktype = strtol(p, &next, 10); linktype = strtol(p, &next, 10);
if (next == p || *next != ')' || linktype < 0) { if (next == p || *next != ')' || linktype < 0) {
/* Syntax error */ /* Syntax error */
@ -133,7 +133,7 @@ capture_dev_user_linktype_find(const gchar *if_name)
gint gint
capture_dev_user_buffersize_find(const gchar *if_name) capture_dev_user_buffersize_find(const gchar *if_name)
{ {
gchar *p, *next; gchar *p, *next, *tmpname;
gint buffersize; gint buffersize;
if ((prefs.capture_devices_buffersize == NULL) || if ((prefs.capture_devices_buffersize == NULL) ||
@ -141,13 +141,13 @@ capture_dev_user_buffersize_find(const gchar *if_name)
/* There are no buffersizes defined */ /* There are no buffersizes defined */
return -1; return -1;
} }
tmpname = g_strdup_printf(",%s(", if_name);
if ((p = strstr(prefs.capture_devices_buffersize, if_name)) == NULL) { if ((p = strstr(prefs.capture_devices_buffersize, tmpname)) == NULL) {
/* There are, but there isn't one for this interface. */ /* There are, but there isn't one for this interface. */
return -1; return -1;
} }
p += strlen(if_name) + 1; p += strlen(if_name) + 2;
buffersize = (gint)strtol(p, &next, 10); buffersize = (gint)strtol(p, &next, 10);
if (next == p || *next != ')' || buffersize < 0) { if (next == p || *next != ')' || buffersize < 0) {
/* Syntax error */ /* Syntax error */
@ -165,7 +165,7 @@ capture_dev_user_buffersize_find(const gchar *if_name)
gint gint
capture_dev_user_snaplen_find(const gchar *if_name) capture_dev_user_snaplen_find(const gchar *if_name)
{ {
gchar *p, *next; gchar *p, *next, *tmpname;
gint snaplen; gint snaplen;
if ((prefs.capture_devices_snaplen == NULL) || 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 */ /* There is no snap length defined */
return -1; return -1;
} }
tmpname = g_strdup_printf(",%s:", if_name);
if ((p = strstr(prefs.capture_devices_snaplen, if_name)) == NULL) { if ((p = strstr(prefs.capture_devices_snaplen, tmpname)) == NULL) {
/* There are, but there isn't one for this interface. */ /* There are, but there isn't one for this interface. */
return -1; return -1;
} }
p += strlen(if_name) + 3; p += strlen(if_name) + 4;
snaplen = (gint)strtol(p, &next, 10); snaplen = (gint)strtol(p, &next, 10);
if (next == p || *next != ')' || snaplen < 0) { if (next == p || *next != ')' || snaplen < 0) {
/* Syntax error */ /* Syntax error */
@ -196,7 +196,7 @@ capture_dev_user_snaplen_find(const gchar *if_name)
gboolean gboolean
capture_dev_user_hassnap_find(const gchar *if_name) capture_dev_user_hassnap_find(const gchar *if_name)
{ {
gchar *p, *next; gchar *p, *next, *tmpname;
gboolean hassnap; gboolean hassnap;
if ((prefs.capture_devices_snaplen == NULL) || 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 */ /* There is no snap length defined */
return -1; return -1;
} }
tmpname = g_strdup_printf(",%s:", if_name);
if ((p = strstr(prefs.capture_devices_snaplen, if_name)) == NULL) { if ((p = strstr(prefs.capture_devices_snaplen, tmpname)) == NULL) {
/* There are, but there isn't one for this interface. */ /* There are, but there isn't one for this interface. */
return -1; return -1;
} }
p += strlen(if_name) + 1; p += strlen(if_name) + 2;
hassnap = (gboolean)strtol(p, &next, 10); hassnap = (gboolean)strtol(p, &next, 10);
if (next == p || *next != '(') { if (next == p || *next != '(') {
/* Syntax error */ /* Syntax error */
@ -223,7 +223,7 @@ capture_dev_user_hassnap_find(const gchar *if_name)
gboolean gboolean
capture_dev_user_pmode_find(const gchar *if_name) capture_dev_user_pmode_find(const gchar *if_name)
{ {
gchar *p, *next; gchar *p, *next, *tmpname;
gboolean pmode; gboolean pmode;
if ((prefs.capture_devices_pmode == NULL) || 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 */ /* There is no promiscuous mode defined */
return -1; return -1;
} }
tmpname = g_strdup_printf(",%s(", if_name);
if ((p = strstr(prefs.capture_devices_pmode, if_name)) == NULL) { if ((p = strstr(prefs.capture_devices_pmode, tmpname)) == NULL) {
/* There are, but there isn't one for this interface. */ /* There are, but there isn't one for this interface. */
return -1; return -1;
} }
p += strlen(if_name) + 1; p += strlen(if_name) + 2;
pmode = (gboolean)strtol(p, &next, 10); pmode = (gboolean)strtol(p, &next, 10);
if (next == p || *next != ')') { if (next == p || *next != ')') {
/* Syntax error */ /* Syntax error */
@ -246,6 +246,32 @@ capture_dev_user_pmode_find(const gchar *if_name)
return (gboolean)pmode; 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. * Return as descriptive a name for an interface as we can get.
* If the user has specified a comment, use that. Otherwise, * If the user has specified a comment, use that. Otherwise,

View File

@ -66,6 +66,12 @@ gboolean capture_dev_user_hassnap_find(const gchar *if_name);
*/ */
gboolean capture_dev_user_pmode_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. /** Return as descriptive a name for an interface as we can get.
* If the user has specified a comment, use that. Otherwise, * If the user has specified a comment, use that. Otherwise,
* if capture_interface_list() supplies a description, use that, * if capture_interface_list() supplies a description, use that,

View File

@ -2431,6 +2431,10 @@ prefs_register_modules(void)
prefs_register_bool_preference(capture_module, "prom_mode", "Capture in promiscuous mode", prefs_register_bool_preference(capture_module, "prom_mode", "Capture in promiscuous mode",
"Capture in promiscuous mode?", &prefs.capture_prom_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", prefs_register_bool_preference(capture_module, "pcap_ng", "Capture in Pcap-NG format",
"Capture in Pcap-NG format?", &prefs.capture_pcap_ng); "Capture in Pcap-NG format?", &prefs.capture_pcap_ng);

View File

@ -193,6 +193,7 @@ typedef struct _e_prefs {
#endif #endif
gchar *capture_devices_snaplen; gchar *capture_devices_snaplen;
gchar *capture_devices_pmode; gchar *capture_devices_pmode;
gchar *capture_devices_filter;
gboolean capture_prom_mode; gboolean capture_prom_mode;
gboolean capture_pcap_ng; gboolean capture_pcap_ng;
gboolean capture_real_time; gboolean capture_real_time;

View File

@ -5,5 +5,6 @@
<file>expert_none.png</file> <file>expert_none.png</file>
<file>expert_note.png</file> <file>expert_note.png</file>
<file>expert_warn.png</file> <file>expert_warn.png</file>
<file>expert_ok.png</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -37,6 +37,7 @@ set(WIRESHARK_QT_HEADERS
color_dialog.h color_dialog.h
color_utils.h color_utils.h
column_preferences_frame.h column_preferences_frame.h
compiled_filter_output.h
decode_as_dialog.h decode_as_dialog.h
display_filter_combo.h display_filter_combo.h
display_filter_edit.h display_filter_edit.h
@ -117,6 +118,7 @@ set(WIRESHARK_QT_SRC
color_utils.cpp color_utils.cpp
capture_preferences_frame.cpp capture_preferences_frame.cpp
column_preferences_frame.cpp column_preferences_frame.cpp
compiled_filter_output.cpp
decode_as_dialog.cpp decode_as_dialog.cpp
display_filter_combo.cpp display_filter_combo.cpp
display_filter_edit.cpp display_filter_edit.cpp
@ -197,6 +199,7 @@ set(WIRESHARK_QT_UI
capture_preferences_frame.ui capture_preferences_frame.ui
capture_interfaces_dialog.ui capture_interfaces_dialog.ui
column_preferences_frame.ui column_preferences_frame.ui
compiled_filter_output.ui
decode_as_dialog.ui decode_as_dialog.ui
export_object_dialog.ui export_object_dialog.ui
export_pdu_dialog.ui export_pdu_dialog.ui

View File

@ -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 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 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 export_object_dialog.cpp export_object_dialog.h: ui_export_object_dialog.h

View File

@ -33,6 +33,7 @@ NODIST_GENERATED_HEADER_FILES = \
ui_capture_interfaces_dialog.h \ ui_capture_interfaces_dialog.h \
ui_capture_preferences_frame.h \ ui_capture_preferences_frame.h \
ui_column_preferences_frame.h \ ui_column_preferences_frame.h \
ui_compiled_filter_output.h \
ui_decode_as_dialog.h \ ui_decode_as_dialog.h \
ui_export_object_dialog.h \ ui_export_object_dialog.h \
ui_export_pdu_dialog.h \ ui_export_pdu_dialog.h \
@ -121,6 +122,7 @@ MOC_HDRS = \
color_utils.h \ color_utils.h \
capture_preferences_frame.h \ capture_preferences_frame.h \
column_preferences_frame.h \ column_preferences_frame.h \
compiled_filter_output.h \
decode_as_dialog.h \ decode_as_dialog.h \
display_filter_combo.h \ display_filter_combo.h \
display_filter_edit.h \ display_filter_edit.h \
@ -189,6 +191,7 @@ UI_FILES = \
capture_interfaces_dialog.ui \ capture_interfaces_dialog.ui \
capture_preferences_frame.ui \ capture_preferences_frame.ui \
column_preferences_frame.ui \ column_preferences_frame.ui \
compiled_filter_output.ui \
decode_as_dialog.ui \ decode_as_dialog.ui \
export_object_dialog.ui \ export_object_dialog.ui \
export_pdu_dialog.ui \ export_pdu_dialog.ui \
@ -293,6 +296,7 @@ WIRESHARK_QT_SRC = \
color_utils.cpp \ color_utils.cpp \
capture_preferences_frame.cpp \ capture_preferences_frame.cpp \
column_preferences_frame.cpp \ column_preferences_frame.cpp \
compiled_filter_output.cpp \
decode_as_dialog.cpp \ decode_as_dialog.cpp \
display_filter_combo.cpp \ display_filter_combo.cpp \
display_filter_edit.cpp \ display_filter_edit.cpp \

View File

@ -223,6 +223,7 @@ FORMS += \
capture_preferences_frame.ui \ capture_preferences_frame.ui \
capture_interfaces_dialog.ui \ capture_interfaces_dialog.ui \
column_preferences_frame.ui \ column_preferences_frame.ui \
compiled_filter_output.ui \
decode_as_dialog.ui \ decode_as_dialog.ui \
export_object_dialog.ui \ export_object_dialog.ui \
export_pdu_dialog.ui \ export_pdu_dialog.ui \
@ -268,6 +269,7 @@ HEADERS += $$HEADERS_WS_C \
capture_interfaces_dialog.h \ capture_interfaces_dialog.h \
capture_preferences_frame.h \ capture_preferences_frame.h \
column_preferences_frame.h \ column_preferences_frame.h \
compiled_filter_output.h \
decode_as_dialog.h \ decode_as_dialog.h \
elided_label.h \ elided_label.h \
export_dissection_dialog.h \ export_dissection_dialog.h \
@ -582,6 +584,7 @@ SOURCES += \
color_dialog.cpp \ color_dialog.cpp \
color_utils.cpp \ color_utils.cpp \
column_preferences_frame.cpp \ column_preferences_frame.cpp \
compiled_filter_output.cpp \
decode_as_dialog.cpp \ decode_as_dialog.cpp \
display_filter_combo.cpp \ display_filter_combo.cpp \
display_filter_edit.cpp \ display_filter_edit.cpp \

View File

@ -24,13 +24,16 @@
#include <glib.h> #include <glib.h>
#include "capture_interfaces_dialog.h" #include "capture_interfaces_dialog.h"
#include "capture_filter_combo.h"
#include "ui_capture_interfaces_dialog.h" #include "ui_capture_interfaces_dialog.h"
#include "compiled_filter_output.h"
#include "wireshark_application.h" #include "wireshark_application.h"
#ifdef HAVE_LIBPCAP #ifdef HAVE_LIBPCAP
#include <QTimer> #include <QTimer>
#include <QMessageBox>
#include "capture_ui_utils.h" #include "capture_ui_utils.h"
#include "ui/capture_globals.h" #include "ui/capture_globals.h"
@ -38,6 +41,7 @@
#include "ui/ui_util.h" #include "ui/ui_util.h"
#include "ui/utf8_entities.h" #include "ui/utf8_entities.h"
#include "ui/preference_utils.h"
#include <cstdio> #include <cstdio>
#include <epan/prefs.h> #include <epan/prefs.h>
@ -59,14 +63,51 @@ CaptureInterfacesDialog::CaptureInterfacesDialog(QWidget *parent) :
// XXX - Enable / disable as needed // XXX - Enable / disable as needed
start_bt_ = ui->buttonBox->addButton(tr("Start"), QDialogButtonBox::YesRole); 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); start_bt_->setEnabled((global_capture_opts.num_selected > 0)? true: false);
stop_bt_->setEnabled(false); connect(start_bt_, SIGNAL(clicked(bool)), this, SLOT(start_button_clicked()));
connect(stop_bt_, SIGNAL(clicked()), this, SLOT(on_bStop_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(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) void CaptureInterfacesDialog::tableItemClicked(QTableWidgetItem * item)
@ -74,28 +115,39 @@ void CaptureInterfacesDialog::tableItemClicked(QTableWidgetItem * item)
Q_UNUSED(item) Q_UNUSED(item)
interface_t device; interface_t device;
guint i;
global_capture_opts.num_selected = 0; 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++) 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);
QString interface_name = ui->tbInterfaces->item(row, 1)->text(); QString interface_name = it->text();
device = g_array_index(global_capture_opts.all_ifaces, interface_t, row); for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
if (checked == true) if (interface_name.compare(device.display_name)) {
{ continue;
device.selected = TRUE; } else {
break;
}
}
if (selected.contains(it)) {
device.selected = true;
global_capture_opts.num_selected++; global_capture_opts.num_selected++;
global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, row); } else {
g_array_insert_val(global_capture_opts.all_ifaces, row, device); device.selected = false;
} }
else 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);
device.selected = FALSE;
global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, row); start_bt_->setEnabled((global_capture_opts.num_selected > 0)? true: false);
g_array_insert_val(global_capture_opts.all_ifaces, row, device);
if (filter.compare(QString(""))) {
emit interfacesChanged();
} }
emit setSelectedInterfaces();
} }
} }
@ -111,7 +163,17 @@ void CaptureInterfacesDialog::SetTab(int index)
void CaptureInterfacesDialog::on_capturePromModeCheckBox_toggled(bool checked) void CaptureInterfacesDialog::on_capturePromModeCheckBox_toggled(bool checked)
{ {
interface_t device;
prefs.capture_prom_mode = checked; 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) void CaptureInterfacesDialog::on_gbStopCaptureAuto_toggled(bool checked)
@ -155,25 +217,20 @@ void CaptureInterfacesDialog::on_cbResolveTransportNames_toggled(bool checked)
gbl_resolv_flags.transport_name = checked; gbl_resolv_flags.transport_name = checked;
} }
void CaptureInterfacesDialog::on_bStart_clicked() void CaptureInterfacesDialog::start_button_clicked()
{ {
qDebug("Starting capture"); qDebug("Starting capture");
emit startCapture(); saveOptionsToPreferences();
emit setFilterValid(true);
accept(); accept();
} }
void CaptureInterfacesDialog::on_bStop_clicked()
{
qDebug("Stop capture");
emit stopCapture();
}
// Not sure why we have to do this manually. // Not sure why we have to do this manually.
void CaptureInterfacesDialog::on_buttonBox_rejected() void CaptureInterfacesDialog::on_buttonBox_rejected()
{ {
saveOptionsToPreferences();
reject(); reject();
} }
@ -205,27 +262,17 @@ void CaptureInterfacesDialog::UpdateInterfaces()
ui->tbInterfaces->setRowCount(0); ui->tbInterfaces->setRowCount(0);
GList *if_list;
int err;
gchar *err_str = NULL;
GList *list; GList *list;
char *snaplen_string, *linkname; char *snaplen_string, *linkname;
//guint i;
link_row *linkr = NULL; link_row *linkr = NULL;
//interface_t device;
#if defined(_WIN32) || defined(HAVE_PCAP_CREATE) #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
gint buffer; gint buffer;
#endif #endif
gint snaplen; gint snaplen;
gboolean hassnap, pmode; gboolean hassnap, pmode;
if_list = capture_interface_list(&err, &err_str,main_window_update); if (global_capture_opts.all_ifaces->len > 0) {
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) {
interface_t device; interface_t device;
//setDisabled(false);
for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) { for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
QList<int> *points; QList<int> *points;
@ -236,22 +283,20 @@ void CaptureInterfacesDialog::UpdateInterfaces()
if (device.hidden) { if (device.hidden) {
continue; continue;
} }
deviceMap[ui->tbInterfaces->rowCount()] = i;
QString output; QString output;
ui->tbInterfaces->setRowCount(ui->tbInterfaces->rowCount() + 1); 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 // traffic lines
ui->tbInterfaces->setItemDelegateForColumn(TRAFFIC, new SparkLineDelegate()); ui->tbInterfaces->setItemDelegateForColumn(TRAFFIC, new SparkLineDelegate());
points = new QList<int>(); points = new QList<int>();
QTableWidgetItem *ti = new QTableWidgetItem(); QTableWidgetItem *ti = new QTableWidgetItem();
ti->setFlags(Qt::NoItemFlags);
ti->setData(Qt::UserRole, qVariantFromValue(points)); ti->setData(Qt::UserRole, qVariantFromValue(points));
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, TRAFFIC, ti); ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, TRAFFIC, ti);
ui->tbInterfaces->setItemDelegateForColumn(INTERFACE, &combobox_item_delegate_);
output = QString(device.display_name); output = QString(device.display_name);
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, INTERFACE, new QTableWidgetItem(output)); ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, INTERFACE, new QTableWidgetItem(output));
@ -300,38 +345,61 @@ void CaptureInterfacesDialog::UpdateInterfaces()
} }
#endif #endif
combobox_item_delegate_.setTable(ui->tbInterfaces);
ui->tbInterfaces->setColumnWidth(LINK, 100);
ui->tbInterfaces->setItemDelegateForColumn(LINK, &combobox_item_delegate_);
output = QString(linkname); output = QString(linkname);
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, LINK, new QTableWidgetItem(output)); 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->setItem(ui->tbInterfaces->rowCount()-1, PMODE, new QTableWidgetItem(output));
ui->tbInterfaces->setItemDelegateForColumn(SNAPLEN, &combobox_item_delegate_);
output = QString(snaplen_string); output = QString(snaplen_string);
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, SNAPLEN, new QTableWidgetItem(output)); 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); output = QString().sprintf("%d", device.buffer);
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, BUFFER, new QTableWidgetItem(output)); 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 #else
ui->tbInterfaces->setColumnHidden(BUFFER+1, true); ui->tbInterfaces->setColumnHidden(SNAPLEN+1, true);
#endif #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) { if (strstr(prefs.capture_device, device.name) != NULL) {
device.selected = TRUE; device.selected = TRUE;
global_capture_opts.num_selected++; 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) { 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); resizeEvent(NULL);
start_bt_->setEnabled((global_capture_opts.num_selected > 0)? true: false);
if (!stat_timer_) { if (!stat_timer_) {
updateStatistics(); updateStatistics();
@ -343,76 +411,419 @@ void CaptureInterfacesDialog::UpdateInterfaces()
void CaptureInterfacesDialog::updateStatistics(void) void CaptureInterfacesDialog::updateStatistics(void)
{ {
//guint diff;
QList<int> *points = NULL; QList<int> *points = NULL;
interface_t device;
for (int row = 0; row < ui->tbInterfaces->rowCount(); row++) {
points = new QList<int>();
if (!stat_cache_) { for (guint if_idx = 0; if_idx < global_capture_opts.all_ifaces->len; if_idx++) {
// Start gathering statistics using dumpcap device = g_array_index(global_capture_opts.all_ifaces, interface_t, if_idx);
// We crash (on OS X at least) if we try to do this from ::showEvent. QString device_name = ui->tbInterfaces->item(row, INTERFACE)->text();
stat_cache_ = capture_stat_start(&global_capture_opts); 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++) 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++) { cfo->show();
// 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;
//diff = 0; void CaptureInterfacesDialog::saveOptionsToPreferences()
// if (capture_stats(stat_cache_, device.name, &stats)) { {
// if ((int)(stats.ps_recv - device.last_packets) >= 0) { interface_t device;
// diff = stats.ps_recv - device.last_packets; gchar *new_prefs, *tmp_prefs;
// }
// device.last_packets = stats.ps_recv;
// }
points = ui->tbInterfaces->item(row, TRAFFIC)->data(Qt::UserRole).value<QList<int> *>(); for (int col = LINK; col <= FILTER; col++){
emit getPoints(row, points); if (ui->tbInterfaces->isColumnHidden(col)) {
//ui->tbInterfaces->item 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()); for (int row = 0; row < ui->tbInterfaces->rowCount(); row++) {
//points = new QList<int>(); device = g_array_index(global_capture_opts.all_ifaces, interface_t, deviceMap[row]);
//QTableWidgetItem *ti = new QTableWidgetItem(); if (device.active_dlt == -1) {
//ti->setData(Qt::UserRole, qVariantFromValue(points)); 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); for (int row = 0; row < ui->tbInterfaces->rowCount(); row++) {
ti->setData(Qt::UserRole, qVariantFromValue(points)); device = g_array_index(global_capture_opts.all_ifaces, interface_t, deviceMap[row]);
//ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, TRAFFIC, ti); 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); for (int row = 0; row < ui->tbInterfaces->rowCount(); row++) {
ui->tbInterfaces->viewport()->update(); device = g_array_index(global_capture_opts.all_ifaces, interface_t, deviceMap[row]);
// global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, if_idx); g_strlcat(new_prefs, ",", MAX_VAL_LEN);
// g_array_insert_val(global_capture_opts.all_ifaces, if_idx, device); 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 <QComboBox>
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<QComboBox*>(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 */ #endif /* HAVE_LIBPCAP */
/* /*

View File

@ -41,18 +41,13 @@ typedef struct if_stat_cache_s if_stat_cache_t;
*/ */
enum enum
{ {
CAPTURE = 0, INTERFACE = 0,
INTERFACE,
TRAFFIC, TRAFFIC,
LINK, LINK,
PMODE, PMODE,
SNAPLEN, SNAPLEN,
#if defined(HAVE_PCAP_CREATE)
BUFFER, BUFFER,
MONITOR, MONITOR,
#elif defined(_WIN32) && !defined(HAVE_PCAP_CREATE)
BUFFER,
#endif
FILTER, FILTER,
NUM_COLUMNS NUM_COLUMNS
}; };
@ -62,6 +57,32 @@ namespace Ui {
class CaptureInterfacesDialog; 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 class CaptureInterfacesDialog : public QDialog
{ {
Q_OBJECT Q_OBJECT
@ -72,7 +93,6 @@ public:
void SetTab(int index); void SetTab(int index);
void UpdateInterfaces(); void UpdateInterfaces();
//void updateStatistics(void);
private slots: private slots:
void on_capturePromModeCheckBox_toggled(bool checked); void on_capturePromModeCheckBox_toggled(bool checked);
@ -82,21 +102,24 @@ private slots:
void on_gbNewFileAuto_toggled(bool checked); void on_gbNewFileAuto_toggled(bool checked);
void on_cbExtraCaptureInfo_toggled(bool checked); void on_cbExtraCaptureInfo_toggled(bool checked);
void on_cbResolveMacAddresses_toggled(bool checked); void on_cbResolveMacAddresses_toggled(bool checked);
void on_compileBPF_clicked();
void on_cbResolveNetworkNames_toggled(bool checked); void on_cbResolveNetworkNames_toggled(bool checked);
void on_cbResolveTransportNames_toggled(bool checked); void on_cbResolveTransportNames_toggled(bool checked);
void on_bStart_clicked(); void start_button_clicked();
void on_bStop_clicked();
void on_buttonBox_rejected(); void on_buttonBox_rejected();
void on_buttonBox_helpRequested(); void on_buttonBox_helpRequested();
void tableItemClicked(QTableWidgetItem * item); void tableItemClicked(QTableWidgetItem * item);
void tableSelected();
void updateStatistics(void); void updateStatistics(void);
//void on_tbInterfaces_hideEvent(QHideEvent *evt); void allFilterChanged();
//void on_tbInterfaces_showEvent(QShowEvent *evt);
signals: signals:
void startCapture(); void startCapture();
void stopCapture(); void stopCapture();
void getPoints(int row, PointList *pts); void getPoints(int row, PointList *pts);
void setSelectedInterfaces();
void setFilterValid(bool valid);
void interfacesChanged();
private: private:
Ui::CaptureInterfacesDialog *ui; Ui::CaptureInterfacesDialog *ui;
@ -106,6 +129,10 @@ private:
QPushButton *stop_bt_; QPushButton *stop_bt_;
if_stat_cache_t *stat_cache_; if_stat_cache_t *stat_cache_;
QTimer *stat_timer_; QTimer *stat_timer_;
TbInterfacesDelegate combobox_item_delegate_;
QMap<int, int> deviceMap;
void saveOptionsToPreferences();
}; };
#endif /* HAVE_LIBPCAP */ #endif /* HAVE_LIBPCAP */

View File

@ -27,7 +27,7 @@
<item> <item>
<widget class="QTableWidget" name="tbInterfaces"> <widget class="QTableWidget" name="tbInterfaces">
<property name="editTriggers"> <property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set> <set>QAbstractItemView::DoubleClicked</set>
</property> </property>
<property name="alternatingRowColors"> <property name="alternatingRowColors">
<bool>true</bool> <bool>true</bool>
@ -45,13 +45,8 @@
<number>0</number> <number>0</number>
</property> </property>
<property name="columnCount"> <property name="columnCount">
<number>9</number> <number>8</number>
</property> </property>
<column>
<property name="text">
<string>Capture</string>
</property>
</column>
<column> <column>
<property name="text"> <property name="text">
<string>Interface</string> <string>Interface</string>
@ -104,35 +99,46 @@
<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> <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>
<property name="text"> <property name="text">
<string>Capture packets in promiscuous mode</string> <string>Capture packets in promiscuous mode on all interfaces</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QCheckBox" name="captureShowInfoCheckBox"> <spacer name="horizontalSpacer_2">
<property name="toolTip"> <property name="orientation">
<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> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="text"> <property name="sizeHint" stdset="0">
<string>Show the capture summary dialog while capturing</string> <size>
<width>13</width>
<height>3</height>
</size>
</property> </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> </item>
</layout> </layout>
</item> </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> <item>
<layout class="QVBoxLayout" name="verticalLayout_4"> <layout class="QVBoxLayout" name="verticalLayout_4">
<item> <item>
@ -141,22 +147,16 @@
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="text"> <property name="text">
<string>Add pipe...</string> <string>Manage Interfaces...</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="verticalSpacer"> <widget class="QPushButton" name="compileBPF">
<property name="orientation"> <property name="text">
<enum>Qt::Vertical</enum> <string>Compile BPFs</string>
</property> </property>
<property name="sizeHint" stdset="0"> </widget>
<size>
<width>20</width>
<height>18</height>
</size>
</property>
</spacer>
</item> </item>
</layout> </layout>
</item> </item>
@ -629,6 +629,13 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<customwidgets>
<customwidget>
<class>CaptureFilterCombo</class>
<extends>QComboBox</extends>
<header location="global">capture_filter_combo.h</header>
</customwidget>
</customwidgets>
<resources/> <resources/>
<connections/> <connections/>
</ui> </ui>

View File

@ -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:
//

View File

@ -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:
//

View File

@ -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>

View File

@ -254,6 +254,7 @@ void InterfaceTree::updateStatistics(void) {
if (capture_stats(stat_cache_, device.name, &stats)) { if (capture_stats(stat_cache_, device.name, &stats)) {
if ((int)(stats.ps_recv - device.last_packets) >= 0) { if ((int)(stats.ps_recv - device.last_packets) >= 0) {
diff = stats.ps_recv - device.last_packets; diff = stats.ps_recv - device.last_packets;
device.packet_diff = diff;
} }
device.last_packets = stats.ps_recv; device.last_packets = stats.ps_recv;
} }
@ -306,6 +307,30 @@ void InterfaceTree::updateSelectedInterfaces()
#endif // HAVE_LIBPCAP #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 * Editor modelines
* *

View File

@ -64,6 +64,7 @@ public slots:
// change_interface_selection_for_all // change_interface_selection_for_all
//void getPoints(int row, QList<int> *pts); //void getPoints(int row, QList<int> *pts);
void getPoints(int row, PointList *pts); void getPoints(int row, PointList *pts);
void setSelectedInterfaces();
private slots: private slots:
void getInterfaceList(); void getInterfaceList();

View File

@ -299,6 +299,8 @@ MainWindow::MainWindow(QWidget *parent) :
connect(&capture_interfaces_dialog_, SIGNAL(getPoints(int,PointList*)), connect(&capture_interfaces_dialog_, SIGNAL(getPoints(int,PointList*)),
this->main_welcome_->getInterfaceTree(), SLOT(getPoints(int,PointList*))); this->main_welcome_->getInterfaceTree(), SLOT(getPoints(int,PointList*)));
connect(&capture_interfaces_dialog_, SIGNAL(setSelectedInterfaces()),
this->main_welcome_->getInterfaceTree(), SLOT(setSelectedInterfaces()));
#endif #endif
main_ui_->mainStack->setCurrentWidget(main_welcome_); main_ui_->mainStack->setCurrentWidget(main_welcome_);
@ -1392,7 +1394,7 @@ void MainWindow::setMenusForFollowStream()
main_ui_->actionAnalyzeFollowSSLStream->setEnabled(false); main_ui_->actionAnalyzeFollowSSLStream->setEnabled(false);
proto_get_frame_protocols(cap_file_->edt->pi.layers, NULL, &is_tcp, &is_udp, NULL, NULL); proto_get_frame_protocols(cap_file_->edt->pi.layers, NULL, &is_tcp, &is_udp, NULL, NULL);
if (is_tcp) if (is_tcp)
{ {
main_ui_->actionAnalyzeFollowTCPStream->setEnabled(true); main_ui_->actionAnalyzeFollowTCPStream->setEnabled(true);

View File

@ -205,6 +205,8 @@ private slots:
void redissectPackets(); void redissectPackets();
void recreatePacketList(); void recreatePacketList();
void startInterfaceCapture(bool valid);
void setFeaturesEnabled(bool enabled = true); void setFeaturesEnabled(bool enabled = true);
void addDisplayFilterButton(QString df_text); void addDisplayFilterButton(QString df_text);

View File

@ -1101,6 +1101,12 @@ void MainWindow::captureFilterSyntaxChanged(bool valid)
interfaceSelectionChanged(); interfaceSelectionChanged();
} }
void MainWindow::startInterfaceCapture(bool valid)
{
capture_filter_valid_ = valid;
startCapture();
}
void MainWindow::redissectPackets() void MainWindow::redissectPackets()
{ {
if (cap_file_) if (cap_file_)
@ -2320,6 +2326,7 @@ void MainWindow::on_actionSummary_triggered()
#ifdef HAVE_LIBPCAP #ifdef HAVE_LIBPCAP
void MainWindow::on_actionCaptureInterfaces_triggered() void MainWindow::on_actionCaptureInterfaces_triggered()
{ {
connect(&capture_interfaces_dialog_, SIGNAL(setFilterValid(bool)), this, SLOT(startInterfaceCapture(bool)));
capture_interfaces_dialog_.SetTab(0); capture_interfaces_dialog_.SetTab(0);
capture_interfaces_dialog_.UpdateInterfaces(); capture_interfaces_dialog_.UpdateInterfaces();