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;
#endif
guint32 last_packets;
guint32 packet_diff;
if_info_t if_info;
gboolean selected;
gboolean hidden;

View File

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

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);
/**
* 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,

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

@ -24,13 +24,16 @@
#include <glib.h>
#include "capture_interfaces_dialog.h"
#include "capture_filter_combo.h"
#include "ui_capture_interfaces_dialog.h"
#include "compiled_filter_output.h"
#include "wireshark_application.h"
#ifdef HAVE_LIBPCAP
#include <QTimer>
#include <QMessageBox>
#include "capture_ui_utils.h"
#include "ui/capture_globals.h"
@ -38,6 +41,7 @@
#include "ui/ui_util.h"
#include "ui/utf8_entities.h"
#include "ui/preference_utils.h"
#include <cstdio>
#include <epan/prefs.h>
@ -59,14 +63,51 @@ CaptureInterfacesDialog::CaptureInterfacesDialog(QWidget *parent) :
// XXX - Enable / disable as needed
start_bt_ = ui->buttonBox->addButton(tr("Start"), QDialogButtonBox::YesRole);
connect(start_bt_, SIGNAL(clicked()), this, SLOT(on_bStart_clicked()));
stop_bt_ = ui->buttonBox->addButton(tr("Stop"), QDialogButtonBox::NoRole);
stop_bt_->setEnabled(false);
connect(stop_bt_, SIGNAL(clicked()), this, SLOT(on_bStop_clicked()));
start_bt_->setEnabled((global_capture_opts.num_selected > 0)? true: false);
connect(start_bt_, SIGNAL(clicked(bool)), this, SLOT(start_button_clicked()));
//connect(ui->tbInterfaces,SIGNAL(itemPressed(QTableWidgetItem *)),this,SLOT(tableItemPressed(QTableWidgetItem *)));
connect(ui->tbInterfaces,SIGNAL(itemClicked(QTableWidgetItem *)),this,SLOT(tableItemClicked(QTableWidgetItem *)));
connect(ui->tbInterfaces, SIGNAL(itemSelectionChanged()), this, SLOT(tableSelected()));
connect(ui->allFilterComboBox, SIGNAL(captureFilterSyntaxChanged(bool)), this, SLOT(allFilterChanged()));
connect(this, SIGNAL(interfacesChanged()), ui->allFilterComboBox, SIGNAL(interfacesChanged()));
}
void CaptureInterfacesDialog::allFilterChanged()
{
QList<QTableWidgetItem*> selected = ui->tbInterfaces->selectedItems();
for (int row = 0; row < ui->tbInterfaces->rowCount(); row++)
{
QTableWidgetItem *it = ui->tbInterfaces->item(row, FILTER);
if (selected.contains(it)) {
QString str = ui->allFilterComboBox->currentText();
it->setText(str);
}
}
}
void CaptureInterfacesDialog::tableSelected()
{
interface_t device;
if (!ui->tbInterfaces->selectedItems().size()) {
for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
device.selected = false;
device.locked = true;
global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
g_array_insert_val(global_capture_opts.all_ifaces, i, device);
}
global_capture_opts.num_selected = 0;
start_bt_->setEnabled(false);
emit setSelectedInterfaces();
for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
device.locked = false;
global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
g_array_insert_val(global_capture_opts.all_ifaces, i, device);
}
}
}
void CaptureInterfacesDialog::tableItemClicked(QTableWidgetItem * item)
@ -74,28 +115,39 @@ void CaptureInterfacesDialog::tableItemClicked(QTableWidgetItem * item)
Q_UNUSED(item)
interface_t device;
guint i;
global_capture_opts.num_selected = 0;
QString filter = ui->allFilterComboBox->currentText();
QList<QTableWidgetItem*> selected = ui->tbInterfaces->selectedItems();
for (int row = 0; row < ui->tbInterfaces->rowCount(); row++)
{
bool checked = (ui->tbInterfaces->item(row, 0)->checkState() == Qt::Checked) ? true : false;
QString interface_name = ui->tbInterfaces->item(row, 1)->text();
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<int> *points;
@ -236,22 +283,20 @@ void CaptureInterfacesDialog::UpdateInterfaces()
if (device.hidden) {
continue;
}
deviceMap[ui->tbInterfaces->rowCount()] = i;
QString output;
ui->tbInterfaces->setRowCount(ui->tbInterfaces->rowCount() + 1);
QTableWidgetItem *cbSelected = new QTableWidgetItem();
cbSelected->setCheckState(device.selected ? Qt::Checked : Qt::Unchecked);
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, CAPTURE, cbSelected);
// traffic lines
ui->tbInterfaces->setItemDelegateForColumn(TRAFFIC, new SparkLineDelegate());
points = new QList<int>();
QTableWidgetItem *ti = new QTableWidgetItem();
ti->setFlags(Qt::NoItemFlags);
ti->setData(Qt::UserRole, qVariantFromValue(points));
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, TRAFFIC, ti);
ui->tbInterfaces->setItemDelegateForColumn(INTERFACE, &combobox_item_delegate_);
output = QString(device.display_name);
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, INTERFACE, new QTableWidgetItem(output));
@ -300,38 +345,61 @@ void CaptureInterfacesDialog::UpdateInterfaces()
}
#endif
combobox_item_delegate_.setTable(ui->tbInterfaces);
ui->tbInterfaces->setColumnWidth(LINK, 100);
ui->tbInterfaces->setItemDelegateForColumn(LINK, &combobox_item_delegate_);
output = QString(linkname);
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, LINK, new QTableWidgetItem(output));
output = QString(device.pmode ? "true" : "false");
ui->tbInterfaces->setItemDelegateForColumn(PMODE, &combobox_item_delegate_);
output = QString(device.pmode ? tr("enabled") : tr("disabled"));
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, PMODE, new QTableWidgetItem(output));
ui->tbInterfaces->setItemDelegateForColumn(SNAPLEN, &combobox_item_delegate_);
output = QString(snaplen_string);
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, SNAPLEN, new QTableWidgetItem(output));
#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
ui->tbInterfaces->setItemDelegateForColumn(BUFFER, &combobox_item_delegate_);
output = QString().sprintf("%d", device.buffer);
ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, BUFFER, new QTableWidgetItem(output));
#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<int> *points = NULL;
interface_t device;
for (int row = 0; row < ui->tbInterfaces->rowCount(); row++) {
points = new QList<int>();
if (!stat_cache_) {
// Start gathering statistics using dumpcap
// We crash (on OS X at least) if we try to do this from ::showEvent.
stat_cache_ = capture_stat_start(&global_capture_opts);
for (guint if_idx = 0; if_idx < global_capture_opts.all_ifaces->len; if_idx++) {
device = g_array_index(global_capture_opts.all_ifaces, interface_t, if_idx);
QString device_name = ui->tbInterfaces->item(row, INTERFACE)->text();
if (device_name.compare(device.display_name) || device.hidden || device.type == IF_PIPE) {
continue;
}
points = ui->tbInterfaces->item(row, TRAFFIC)->data(Qt::UserRole).value<QList<int> *>();
points->append(device.packet_diff);
QTableWidgetItem *ti = new QTableWidgetItem();
ti = ui->tbInterfaces->item(row, TRAFFIC);
ti->setData(Qt::UserRole, qVariantFromValue(points));
ui->tbInterfaces->viewport()->update();
}
}
if (!stat_cache_) return;
}
void CaptureInterfacesDialog::on_compileBPF_clicked()
{
QString filter = ui->allFilterComboBox->currentText();
if (!filter.compare(QString(""))) {
QMessageBox::warning(this, tr("Error"),
tr("Set a filter string to compile."));
return;
}
QList<QTableWidgetItem*> selected = ui->tbInterfaces->selectedItems();
if (selected.length() == 0) {
QMessageBox::warning(this, tr("Error"),
tr("No interfaces selected."));
return;
}
QStringList *interfaces = new QStringList();
for (int row = 0; row < ui->tbInterfaces->rowCount(); row++)
{
//bool checked = (ui->tbInterfaces->item(row, 0)->checkState() == Qt::Checked) ? true : false;
QTableWidgetItem *it = ui->tbInterfaces->item(row, INTERFACE);
if (selected.contains(it)) {
QString str = it->text();
interfaces->append(it->text());
}
}
//points = new QList<int>();
CompiledFilterOutput *cfo = new CompiledFilterOutput(this, interfaces, filter);
// for (if_idx = 0; if_idx < global_capture_opts.all_ifaces->len; if_idx++) {
// device = g_array_index(global_capture_opts.all_ifaces, interface_t, if_idx);
// QString device_name = ui->tbInterfaces->item(row, INTERFACE)->text();
// if (device_name.compare(device.name) || device.hidden || device.type == IF_PIPE)
// continue;
cfo->show();
}
//diff = 0;
// if (capture_stats(stat_cache_, device.name, &stats)) {
// if ((int)(stats.ps_recv - device.last_packets) >= 0) {
// diff = stats.ps_recv - device.last_packets;
// }
// device.last_packets = stats.ps_recv;
// }
void CaptureInterfacesDialog::saveOptionsToPreferences()
{
interface_t device;
gchar *new_prefs, *tmp_prefs;
points = ui->tbInterfaces->item(row, TRAFFIC)->data(Qt::UserRole).value<QList<int> *>();
emit getPoints(row, points);
//ui->tbInterfaces->item
for (int col = LINK; col <= FILTER; col++){
if (ui->tbInterfaces->isColumnHidden(col)) {
continue;
}
/* All entries are separated by comma. There is also one before the first interface to be able to identify
word boundaries. As 'lo' is part of 'nflog' an exact match is necessary. */
switch (col) {
case LINK:
new_prefs = (gchar *)g_malloc0(MAX_VAL_LEN);
//ui->tbInterfaces->setItemDelegateForColumn(TRAFFIC, new SparkLineDelegate());
//points = new QList<int>();
//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 <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 */
/*

View File

@ -41,18 +41,13 @@ typedef struct if_stat_cache_s if_stat_cache_t;
*/
enum
{
CAPTURE = 0,
INTERFACE,
INTERFACE = 0,
TRAFFIC,
LINK,
PMODE,
SNAPLEN,
#if defined(HAVE_PCAP_CREATE)
BUFFER,
MONITOR,
#elif defined(_WIN32) && !defined(HAVE_PCAP_CREATE)
BUFFER,
#endif
FILTER,
NUM_COLUMNS
};
@ -62,6 +57,32 @@ namespace Ui {
class CaptureInterfacesDialog;
}
#include <QStyledItemDelegate>
class TbInterfacesDelegate : public QStyledItemDelegate
{
Q_OBJECT
private:
QTableWidget* table;
public:
TbInterfacesDelegate(QObject *parent = 0);
~TbInterfacesDelegate();
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void setTable(QTableWidget* tb) { table = tb; };
bool eventFilter(QObject *object, QEvent *event);
private slots:
void pmode_changed(QString index);
#if defined (HAVE_PCAP_CREATE)
void monitor_changed(QString index);
#endif
void link_changed(QString index);
void snaplen_changed(int value);
void buffer_changed(int value);
};
class CaptureInterfacesDialog : public QDialog
{
Q_OBJECT
@ -72,7 +93,6 @@ public:
void SetTab(int index);
void UpdateInterfaces();
//void updateStatistics(void);
private slots:
void on_capturePromModeCheckBox_toggled(bool checked);
@ -82,21 +102,24 @@ private slots:
void on_gbNewFileAuto_toggled(bool checked);
void on_cbExtraCaptureInfo_toggled(bool checked);
void on_cbResolveMacAddresses_toggled(bool checked);
void on_compileBPF_clicked();
void on_cbResolveNetworkNames_toggled(bool checked);
void on_cbResolveTransportNames_toggled(bool checked);
void on_bStart_clicked();
void on_bStop_clicked();
void start_button_clicked();
void on_buttonBox_rejected();
void on_buttonBox_helpRequested();
void tableItemClicked(QTableWidgetItem * item);
void tableSelected();
void updateStatistics(void);
//void on_tbInterfaces_hideEvent(QHideEvent *evt);
//void on_tbInterfaces_showEvent(QShowEvent *evt);
void allFilterChanged();
signals:
void startCapture();
void stopCapture();
void getPoints(int row, PointList *pts);
void setSelectedInterfaces();
void setFilterValid(bool valid);
void interfacesChanged();
private:
Ui::CaptureInterfacesDialog *ui;
@ -106,6 +129,10 @@ private:
QPushButton *stop_bt_;
if_stat_cache_t *stat_cache_;
QTimer *stat_timer_;
TbInterfacesDelegate combobox_item_delegate_;
QMap<int, int> deviceMap;
void saveOptionsToPreferences();
};
#endif /* HAVE_LIBPCAP */

View File

@ -27,7 +27,7 @@
<item>
<widget class="QTableWidget" name="tbInterfaces">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
<set>QAbstractItemView::DoubleClicked</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
@ -45,13 +45,8 @@
<number>0</number>
</property>
<property name="columnCount">
<number>9</number>
<number>8</number>
</property>
<column>
<property name="text">
<string>Capture</string>
</property>
</column>
<column>
<property name="text">
<string>Interface</string>
@ -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>
</property>
<property name="text">
<string>Capture packets in promiscuous mode</string>
<string>Capture packets in promiscuous mode on all interfaces</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="captureShowInfoCheckBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Show the capture summary dialog while capturing.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="text">
<string>Show the capture summary dialog while capturing</string>
<property name="sizeHint" stdset="0">
<size>
<width>13</width>
<height>3</height>
</size>
</property>
</widget>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Capture Filter for selected Interfaces:</string>
</property>
</widget>
</item>
<item>
<widget class="CaptureFilterCombo" name="allFilterComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>48</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
@ -141,22 +147,16 @@
<bool>false</bool>
</property>
<property name="text">
<string>Add pipe...</string>
<string>Manage Interfaces...</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<widget class="QPushButton" name="compileBPF">
<property name="text">
<string>Compile BPFs</string>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>18</height>
</size>
</property>
</spacer>
</widget>
</item>
</layout>
</item>
@ -629,6 +629,13 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>CaptureFilterCombo</class>
<extends>QComboBox</extends>
<header location="global">capture_filter_combo.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

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 ((int)(stats.ps_recv - device.last_packets) >= 0) {
diff = stats.ps_recv - device.last_packets;
device.packet_diff = diff;
}
device.last_packets = stats.ps_recv;
}
@ -306,6 +307,30 @@ void InterfaceTree::updateSelectedInterfaces()
#endif // HAVE_LIBPCAP
}
void InterfaceTree::setSelectedInterfaces()
{
#ifdef HAVE_LIBPCAP
interface_t device;
QTreeWidgetItemIterator iter(this);
while (*iter) {
QString device_name = (*iter)->data(0, Qt::UserRole).value<QString>();
for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
if (device_name.compare(QString().fromUtf8(device.name)) == 0) {
(*iter)->setSelected(device.selected);
global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
g_array_insert_val(global_capture_opts.all_ifaces, i, device);
break;
}
global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
g_array_insert_val(global_capture_opts.all_ifaces, i, device);
}
iter++;
}
#endif // HAVE_LIBPCAP
}
/*
* Editor modelines
*

View File

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

View File

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

View File

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

View File

@ -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();