From Thomas ERSFELD (GSoC13)

Add TCP/UDP/SSL Follow feature to QtShark

Known issue :
* Duplicate code with GTK (function need follow_info_t struct but in GTK there is some GWidget variable in struct)
* Sometimes TCP Follow fail...

svn path=/trunk/; revision=51883
This commit is contained in:
Alexis La Goutte 2013-09-09 19:30:30 +00:00
parent 41174fa490
commit 80f9326b2f
20 changed files with 1945 additions and 128 deletions

View File

@ -28,6 +28,7 @@ set(COMMON_UI_SRC
export_object_dicom.c
export_object_http.c
export_object_smb.c
follow.c
help_url.c
packet_list_utils.c
iface_lists.c

View File

@ -49,6 +49,7 @@ WIRESHARK_UI_SRC = \
export_object_dicom.c \
export_object_http.c \
export_object_smb.c \
follow.c \
iface_lists.c \
help_url.c \
packet_list_utils.c \
@ -70,6 +71,7 @@ noinst_HEADERS = \
export_object.h \
last_open_dir.h \
file_dialog.h \
follow.h \
help_url.h \
packet_list_utils.h \
iface_lists.h \

125
ui/follow.c Normal file
View File

@ -0,0 +1,125 @@
/* follow.c
*
* $Id$
*
* 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 "config.h"
#include <string.h>
#include <glib.h>
#include <epan/filesystem.h>
#include <epan/dfilter/dfilter.h>
#include "ui/follow.h"
#ifdef HAVE_LIBZ
char *
sgetline(char *str, int *next)
{
char *end;
end = strstr(str, "\r\n");
if (!end) {
*next = (int)strlen(str);
return NULL;
}
*end = '\0';
*next = (int)(end-str+2);
return str;
}
gboolean
parse_http_header(char *data, size_t len, size_t *content_start)
{
char *tmp, *copy, *line;
size_t pos = 0;
int next_line;
gboolean is_gzipped;
/* XXX handle case where only partial header is passed in here.
* we should pass something back to indicate whether header is complete.
* (if not, is_gzipped is may still be unknown)
*/
/*
* In order to parse header, we duplicate data and tokenize lines.
* We aren't interested in actual data, so use g_strndup instead of memcpy
* to (possibly) copy fewer bytes (e.g., if a nul byte exists in data)
* This also ensures that we have a terminated string for futher processing.
*/
tmp = copy = g_strndup(data, len);
if (!tmp) {
*content_start = 0;
return FALSE;
}
/* skip HTTP... line*/
/*line = */sgetline(tmp, &next_line);
tmp += next_line;
pos += next_line;
is_gzipped = FALSE;
*content_start = -1;
while ((line = sgetline(tmp, &next_line))) {
char *key, *val, *c;
tmp += next_line;
pos += next_line;
if (strlen(line) == 0) {
/* end of header*/
break;
}
c = strchr(line, ':');
if (!c) break;
key = line;
*c = '\0';
val = c+2;
if (!strcmp(key, "Content-Encoding") && strstr(val, "gzip")) {
is_gzipped = TRUE;
}
}
*content_start = pos;
g_free(copy);
return is_gzipped;
}
#endif
/*
* Editor modelines
*
* Local Variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* ex: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/

128
ui/follow.h Normal file
View File

@ -0,0 +1,128 @@
/* follow.h
* Common routines for following data streams (qt/gtk)
*
* $Id$
*
* 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 __FOLLOW__H__
#define __FOLLOW__H__
#include "glib.h"
#include <epan/follow.h>
#include <epan/dissectors/packet-ipv6.h>
#include <epan/prefs.h>
#include <epan/addr_resolv.h>
#include <epan/charsets.h>
#include <epan/epan_dissect.h>
#include <epan/filesystem.h>
#include <epan/ipproto.h>
#include <epan/charsets.h>
#include "config.h"
#include "globals.h"
#include "file.h"
#include "version_info.h"
#ifdef HAVE_LIBZ
#include <zlib.h>
#endif
#ifdef SSL_PLUGIN
#include "packet-ssl-utils.h"
#else
#include <epan/dissectors/packet-ssl-utils.h>
#endif
#ifndef QT_CORE_LIB
#include <gtk/gtk.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct {
gboolean is_from_server;
StringInfo data;
} SslDecryptedRecord;
/* Type of follow we are doing */
typedef enum {
FOLLOW_TCP,
FOLLOW_SSL,
FOLLOW_UDP
} follow_type_t;
/* Show Stream */
typedef enum {
FROM_CLIENT,
FROM_SERVER,
BOTH_HOSTS
} show_stream_t;
/* Show Type */
typedef enum {
SHOW_ASCII,
SHOW_EBCDIC,
SHOW_HEXDUMP,
SHOW_CARRAY,
SHOW_RAW
} show_type_t;
typedef enum {
FRS_OK,
FRS_OPEN_ERROR,
FRS_READ_ERROR,
FRS_PRINT_ERROR
} frs_return_t;
typedef struct {
gboolean is_server;
GByteArray *data;
} follow_record_t;
char *
sgetline(char *str, int *next);
gboolean
parse_http_header(char *data, size_t len, size_t *content_start);
#ifdef __cplusplus
}
#endif
#endif
/*
* Editor modelines
*
* Local Variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* ex: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/

View File

@ -57,6 +57,7 @@
#include "ui/gtk/keys.h"
#include "ui/gtk/gui_utils.h"
#include "ui/gtk/font_utils.h"
#include "ui/follow.h"
#include "ui/gtk/follow_ssl.h"
#include "ui/gtk/follow_stream.h"
@ -66,12 +67,6 @@
#include <epan/dissectors/packet-ssl-utils.h>
#endif
typedef struct {
gboolean is_from_server;
StringInfo data;
} SslDecryptedRecord;
static int
ssl_queue_packet_data(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, const void *ssl)
{
@ -130,7 +125,6 @@ ssl_queue_packet_data(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_
return 0;
}
/* Follow the SSL stream, if any, to which the last packet that we called
a dissection routine on belongs (this might be the most recently
selected packet, or it might be the last packet in the file). */

View File

@ -27,41 +27,7 @@
#define __FOLLOW_STREAM_H__
#include <gtk/gtk.h>
/* Type of follow we are doing */
typedef enum {
FOLLOW_TCP,
FOLLOW_SSL,
FOLLOW_UDP
} follow_type_t;
/* Show Stream */
typedef enum {
FROM_CLIENT,
FROM_SERVER,
BOTH_HOSTS
} show_stream_t;
/* Show Type */
typedef enum {
SHOW_ASCII,
SHOW_EBCDIC,
SHOW_HEXDUMP,
SHOW_CARRAY,
SHOW_RAW
} show_type_t;
typedef enum {
FRS_OK,
FRS_OPEN_ERROR,
FRS_READ_ERROR,
FRS_PRINT_ERROR
} frs_return_t;
typedef struct {
gboolean is_server;
GByteArray *data;
} follow_record_t;
#include <ui/follow.h>
typedef struct {
follow_type_t follow_type;

View File

@ -316,84 +316,6 @@ follow_tcp_stream_cb(GtkWidget * w _U_, gpointer data _U_)
data_out_file = NULL;
}
#ifdef HAVE_LIBZ
static char *
sgetline(char *str, int *next)
{
char *end;
end = strstr(str, "\r\n");
if (!end) {
*next = (int)strlen(str);
return NULL;
}
*end = '\0';
*next = (int)(end-str+2);
return str;
}
static gboolean
parse_http_header(char *data, size_t len, size_t *content_start)
{
char *tmp, *copy, *line;
size_t pos = 0;
int next_line;
gboolean is_gzipped;
/* XXX handle case where only partial header is passed in here.
* we should pass something back to indicate whether header is complete.
* (if not, is_gzipped is may still be unknown)
*/
/*
* In order to parse header, we duplicate data and tokenize lines.
* We aren't interested in actual data, so use g_strndup instead of memcpy
* to (possibly) copy fewer bytes (e.g., if a nul byte exists in data)
* This also ensures that we have a terminated string for futher processing.
*/
tmp = copy = g_strndup(data, len);
if (!tmp) {
*content_start = 0;
return FALSE;
}
/* skip HTTP... line*/
/*line = */sgetline(tmp, &next_line);
tmp += next_line;
pos += next_line;
is_gzipped = FALSE;
*content_start = -1;
while ((line = sgetline(tmp, &next_line))) {
char *key, *val, *c;
tmp += next_line;
pos += next_line;
if (strlen(line) == 0) {
/* end of header*/
break;
}
c = strchr(line, ':');
if (!c) break;
key = line;
*c = '\0';
val = c+2;
if (!strcmp(key, "Content-Encoding") && strstr(val, "gzip")) {
is_gzipped = TRUE;
}
}
*content_start = pos;
g_free(copy);
return is_gzipped;
}
#endif
#define FLT_BUF_SIZE 1024
/*

View File

@ -39,6 +39,7 @@
#include <ui/utf8_entities.h>
#include "gtkglobals.h"
#include "ui/follow.h"
#include "ui/gtk/follow_stream.h"
#include "ui/gtk/keys.h"
#include "ui/gtk/main.h"
@ -76,7 +77,6 @@ udp_queue_packet_data(void *tapdata, packet_info *pinfo,
return 0;
}
/* Follow the UDP stream, if any, to which the last packet that we called
a dissection routine on belongs (this might be the most recently
selected packet, or it might be the last packet in the file). */

View File

@ -44,6 +44,7 @@ set(QTSHARK_H_SRC
export_object_dialog.h
file_set_dialog.h
filter_expressions_preferences_frame.h
follow_stream_dialog.h
font_color_preferences_frame.h
import_text_dialog.h
interface_tree.h
@ -104,6 +105,7 @@ set(CLEAN_FILES
export_object_dialog.cpp
file_set_dialog.cpp
filter_expressions_preferences_frame.cpp
follow_stream_dialog.cpp
font_color_preferences_frame.cpp
import_text_dialog.cpp
interface_tree.cpp
@ -152,6 +154,7 @@ set(QTSHARK_UI
export_object_dialog.ui
file_set_dialog.ui
filter_expressions_preferences_frame.ui
follow_stream_dialog.ui
font_color_preferences_frame.ui
import_text_dialog.ui
layout_preferences_frame.ui

View File

@ -35,8 +35,9 @@ NODIST_GENERATED_HEADER_FILES = \
ui_column_preferences_frame.h \
ui_export_object_dialog.h \
ui_file_set_dialog.h \
ui_font_color_preferences_frame.h \
ui_filter_expressions_preferences_frame.h \
ui_follow_stream_dialog.h \
ui_font_color_preferences_frame.h \
ui_import_text_dialog.h \
ui_layout_preferences_frame.h \
ui_main_welcome.h \
@ -50,8 +51,8 @@ NODIST_GENERATED_HEADER_FILES = \
ui_print_dialog.h \
ui_profile_dialog.h \
ui_search_frame.h \
ui_summary_dialog.h \
ui_splash_overlay.h \
ui_summary_dialog.h \
ui_tcp_stream_dialog.h \
ui_time_shift_dialog.h \
ui_uat_dialog.h
@ -109,6 +110,7 @@ MOC_HDRS = \
export_object_dialog.h \
file_set_dialog.h \
filter_expressions_preferences_frame.h \
follow_stream_dialog.h \
font_color_preferences_frame.h \
import_text_dialog.h \
interface_tree.h \
@ -134,9 +136,9 @@ MOC_HDRS = \
related_packet_delegate.h \
search_frame.h \
simple_dialog_qt.h \
summary_dialog.h \
sparkline_delegate.h \
splash_overlay.h \
summary_dialog.h \
syntax_line_edit.h \
tcp_stream_dialog.h \
time_shift_dialog.h \
@ -153,6 +155,7 @@ UI_FILES = \
export_object_dialog.ui \
file_set_dialog.ui \
filter_expressions_preferences_frame.ui \
follow_stream_dialog.ui \
font_color_preferences_frame.ui \
import_text_dialog.ui \
layout_preferences_frame.ui \
@ -167,8 +170,8 @@ UI_FILES = \
print_dialog.ui \
profile_dialog.ui \
search_frame.ui \
summary_dialog.ui \
splash_overlay.ui \
summary_dialog.ui \
tcp_stream_dialog.ui \
time_shift_dialog.ui \
uat_dialog.ui
@ -239,6 +242,7 @@ WIRESHARK_QT_SRC = \
export_object_dialog.cpp \
file_set_dialog.cpp \
filter_expressions_preferences_frame.cpp \
follow_stream_dialog.cpp \
font_color_preferences_frame.cpp \
import_text_dialog.cpp \
interface_tree.cpp \

View File

@ -210,6 +210,7 @@ FORMS += \
export_object_dialog.ui \
file_set_dialog.ui \
filter_expressions_preferences_frame.ui \
follow_stream_dialog.ui \
font_color_preferences_frame.ui \
import_text_dialog.ui \
layout_preferences_frame.ui \
@ -230,7 +231,6 @@ FORMS += \
uat_dialog.ui \
tcp_stream_dialog.ui
win32 { ## These should be in config.pri ??
!isEmpty(PORTAUDIO_DIR) {
PA_OBJECTS = \
@ -260,6 +260,7 @@ HEADERS += $$HEADERS_WS_C \
export_dissection_dialog.h \
export_object_dialog.h \
filter_expressions_preferences_frame.h \
follow_stream_dialog.h \
font_color_preferences_frame.h \
layout_preferences_frame.h \
main_window_preferences_frame.h \
@ -551,6 +552,7 @@ SOURCES += \
export_object_dialog.cpp \
file_set_dialog.cpp \
filter_expressions_preferences_frame.cpp \
follow_stream_dialog.cpp \
font_color_preferences_frame.cpp \
import_text_dialog.cpp \
interface_tree.cpp \

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,161 @@
/* follow_stream_dialog.h
*
* $Id$
*
* 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 FOLLOW_STREAM_DIALOG_H
#define FOLLOW_STREAM_DIALOG_H
#include <QDialog>
#include <QMessageBox>
#include <unistd.h>
#include "config.h"
#include "qt_ui_utils.h"
#include <epan/follow.h>
#include <epan/dissectors/packet-ipv6.h>
#include <epan/dissectors/packet-tcp.h>
#include <epan/prefs.h>
#include <epan/addr_resolv.h>
#include <epan/charsets.h>
#include <epan/epan_dissect.h>
#include <epan/filesystem.h>
#include <epan/ipproto.h>
#include <epan/charsets.h>
#include <epan/plugins.h>
#include <epan/tap.h>
#include "../file.h"
#include "ui/alert_box.h"
#include "ui/simple_dialog.h"
#include "ui/utf8_entities.h"
#include "wsutil/tempfile.h"
#include <wsutil/file_util.h>
#include "ws_symbol_export.h"
#include "globals.h"
#include "file.h"
#include "version_info.h"
#include <QtGui>
#include "../follow.h"
WS_DLL_PUBLIC FILE *data_out_file;
typedef struct {
follow_type_t follow_type;
show_stream_t show_stream;
show_type_t show_type;
char *data_out_filename;
gboolean is_ipv6;
char *filter_out_filter;
GList *payload;
guint bytes_written[2]; /* Index with FROM_CLIENT or FROM_SERVER for readability. */
guint client_port;
address client_ip;
} follow_info_t;
namespace Ui {
class FollowStreamDialog;
}
class FollowStreamDialog : public QDialog
{
Q_OBJECT
public:
explicit FollowStreamDialog(QWidget *parent = 0);
~FollowStreamDialog();
bool Follow(QString previous_filter_, follow_type_t type);
frs_return_t
follow_show(char *buffer, size_t nchars, gboolean is_from_server,
guint32 *global_pos, guint32 *server_packet_count,
guint32 *client_packet_count);
frs_return_t
follow_read_stream();
frs_return_t
follow_read_tcp_stream();
frs_return_t
follow_read_udp_stream();
frs_return_t
follow_read_ssl_stream();
void
follow_stream();
void add_text(char *buffer, size_t nchars, gboolean is_from_server);
private slots:
void on_cbCharset_currentIndexChanged(int index);
void on_cbDirections_currentIndexChanged(int index);
void HelpButton();
void FilterOut();
void FindText();
void SaveAs();
void Print();
// void on_bNext_clicked();
// void on_bPrevious_clicked();
signals:
void updateFilter(QString &filter, bool force);
private:
Ui::FollowStreamDialog *ui;
QPushButton *bFilterOut;
QPushButton *bFind;
QPushButton *bPrint;
QPushButton *bSave;
follow_info_t *follow_info;
bool save_as;
QFile file;
};
#endif // FOLLOW_STREAM_DIALOG_H
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/

View File

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FollowStreamDialog</class>
<widget class="QDialog" name="FollowStreamDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>667</width>
<height>426</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>10</x>
<y>0</y>
<width>651</width>
<height>381</height>
</rect>
</property>
<property name="title">
<string>Stream contents</string>
</property>
<widget class="QComboBox" name="cbDirections">
<property name="geometry">
<rect>
<x>11</x>
<y>352</y>
<width>461</width>
<height>27</height>
</rect>
</property>
</widget>
<widget class="QTextEdit" name="teStreamContent">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>631</width>
<height>321</height>
</rect>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>480</x>
<y>350</y>
<width>158</width>
<height>29</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Charset</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cbCharset">
<property name="currentIndex">
<number>4</number>
</property>
<item>
<property name="text">
<string>ASCII</string>
</property>
</item>
<item>
<property name="text">
<string>EBCDIC</string>
</property>
</item>
<item>
<property name="text">
<string>C Arrays</string>
</property>
</item>
<item>
<property name="text">
<string>Hex dump</string>
</property>
</item>
<item>
<property name="text">
<string>Raw</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>20</x>
<y>390</y>
<width>631</width>
<height>27</height>
</rect>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Help</set>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -111,6 +111,7 @@ MainWindow::MainWindow(QWidget *parent) :
updateRecentFiles();
connect(&summary_dialog_, SIGNAL(captureCommentChanged()), this, SLOT(updateForUnsavedChanges()));
connect(&follow_stream_dialog_, SIGNAL(updateFilter(QString&, bool)), this, SLOT(filterPackets(QString&, bool)));
const DisplayFilterEdit *df_edit = dynamic_cast<DisplayFilterEdit *>(df_combo_box_->lineEdit());
connect(df_edit, SIGNAL(pushFilterSyntaxStatus(QString&)), main_ui_->statusBar, SLOT(pushFilterStatus(QString&)));
@ -263,6 +264,8 @@ MainWindow::MainWindow(QWidget *parent) :
this, SLOT(setMenusForSelectedPacket()));
connect(packet_list_, SIGNAL(packetDissectionChanged()),
this, SLOT(redissectPackets()));
connect(packet_list_, SIGNAL(setMenusFollowStream()),
this, SLOT(setMenusForFollowStream()));
connect(proto_tree_, SIGNAL(protoItemSelected(QString&)),
main_ui_->statusBar, SLOT(pushFieldStatus(QString&)));
@ -289,6 +292,11 @@ MainWindow::~MainWindow()
delete main_ui_;
}
QString MainWindow::getFilter()
{
return df_combo_box_->itemText(df_combo_box_->count());
}
void MainWindow::setPipeInputHandler(gint source, gpointer user_data, int *child_process, pipe_input_cb_t input_cb)
{
pipe_source_ = source;
@ -1272,6 +1280,34 @@ void MainWindow::setTitlebarForCaptureInProgress()
// Menu state
void MainWindow::setMenusForFollowStream()
{
if (!cap_file_)
return;
if (!cap_file_->edt)
return;
main_ui_->actionAnalyzeFollowTCPStream->setEnabled(false);
main_ui_->actionAnalyzeFollowUDPStream->setEnabled(false);
main_ui_->actionAnalyzeFollowSSLStream->setEnabled(false);
if (cap_file_->edt->pi.ipproto == IP_PROTO_TCP)
{
main_ui_->actionAnalyzeFollowTCPStream->setEnabled(true);
}
if (cap_file_->edt->pi.ipproto == IP_PROTO_UDP)
{
main_ui_->actionAnalyzeFollowUDPStream->setEnabled(true);
}
if ( epan_dissect_packet_contains_field(cap_file_->edt, "ssl") )
{
main_ui_->actionAnalyzeFollowSSLStream->setEnabled(true);
}
}
/* Enable or disable menu items based on whether you have a capture file
you've finished reading and, if you have one, whether it's been saved
and whether it could be saved except by copying the raw packet data. */

View File

@ -57,6 +57,7 @@
#include "file_set_dialog.h"
#include "capture_file_dialog.h"
#include "summary_dialog.h"
#include "follow_stream_dialog.h"
class QAction;
@ -73,6 +74,8 @@ public:
~MainWindow();
void setPipeInputHandler(gint source, gpointer user_data, int *child_process, pipe_input_cb_t input_cb);
QString getFilter();
protected:
bool eventFilter(QObject *obj, QEvent *event);
void keyPressEvent(QKeyEvent *event);
@ -108,6 +111,7 @@ private:
SummaryDialog summary_dialog_;
ByteViewTab *byte_view_tab_;
QWidget *empty_pane_;
FollowStreamDialog follow_stream_dialog
bool capture_stopping_;
bool capture_filter_valid_;
@ -188,6 +192,7 @@ private slots:
void updateRecentFiles();
void recentActionTriggered();
void setMenusForFollowStream();
void setMenusForSelectedPacket();
void setMenusForSelectedTreeRow(field_info *fi = NULL);
void interfaceSelectionChanged();
@ -269,6 +274,9 @@ private slots:
void on_actionAnalyzePAFOrSelected_triggered();
void on_actionAnalyzePAFAndNotSelected_triggered();
void on_actionAnalyzePAFOrNotSelected_triggered();
void on_actionAnalyzeFollowTCPStream_triggered();
void on_actionAnalyzeFollowUDPStream_triggered();
void on_actionAnalyzeFollowSSLStream_triggered();
void on_actionHelpContents_triggered();
void on_actionHelpMPWireshark_triggered();

View File

@ -219,6 +219,7 @@
<addaction name="actionCaptureRestart"/>
<addaction name="actionCaptureCaptureFilters"/>
<addaction name="actionCaptureRefreshInterfaces"/>
<addaction name="separator"/>
</widget>
<widget class="QMenu" name="menuHelp">
<property name="title">
@ -307,6 +308,10 @@
<addaction name="actionApplyAsColumn"/>
<addaction name="menuApplyAsFilter"/>
<addaction name="menuPrepareAFilter"/>
<addaction name="separator"/>
<addaction name="actionAnalyzeFollowTCPStream"/>
<addaction name="actionAnalyzeFollowUDPStream"/>
<addaction name="actionAnalyzeFollowSSLStream"/>
</widget>
<widget class="QMenu" name="menuStatistics">
<property name="enabled">
@ -1283,6 +1288,30 @@
<string>TCP window scaling</string>
</property>
</action>
<action name="actionAnalyzeFollowTCPStream">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Follow TCP Stream</string>
</property>
</action>
<action name="actionAnalyzeFollowUDPStream">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Follow UDP Stream</string>
</property>
</action>
<action name="actionAnalyzeFollowSSLStream">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Follow SSL Stream</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>

View File

@ -199,8 +199,13 @@ void MainWindow::filterPackets(QString& new_filter, bool force)
if (cf_status == CF_OK) {
emit displayFilterSuccess(true);
if (new_filter.length() > 0) {
if (df_combo_box_->findText(new_filter) < 0) {
int index = df_combo_box_->findText(new_filter);
if (index == -1) {
df_combo_box_->insertItem(0, new_filter);
df_combo_box_->setCurrentIndex(0);
}
else {
df_combo_box_->setCurrentIndex(index);
}
}
} else {
@ -463,6 +468,12 @@ void MainWindow::captureFileClosed(const capture_file *cf) {
summary_dialog_.close();
if (df_combo_box_)
{
df_combo_box_->lineEdit()->setText("");
df_combo_box_->applyDisplayFilter();
}
setTitlebarForSelectedTreeRow();
setMenusForSelectedTreeRow();
}
@ -1690,6 +1701,57 @@ void MainWindow::on_actionAnalyzePAFOrNotSelected_triggered()
matchSelectedFilter(MatchSelectedOrNot, false, false);
}
void MainWindow::on_actionAnalyzeFollowTCPStream_triggered()
{
follow_stream_dialog_.Follow(getFilter(), FOLLOW_TCP);
if (follow_stream_dialog_.isMinimized() == true)
{
follow_stream_dialog_.showNormal();
}
else
{
follow_stream_dialog_.show();
}
follow_stream_dialog_.raise();
follow_stream_dialog_.activateWindow();
}
void MainWindow::on_actionAnalyzeFollowUDPStream_triggered()
{
follow_stream_dialog_.Follow(getFilter(), FOLLOW_UDP);
if (follow_stream_dialog_.isMinimized() == true)
{
follow_stream_dialog_.showNormal();
}
else
{
follow_stream_dialog_.show();
}
follow_stream_dialog_.raise();
follow_stream_dialog_.activateWindow();
}
void MainWindow::on_actionAnalyzeFollowSSLStream_triggered()
{
follow_stream_dialog_.Follow(getFilter(), FOLLOW_SSL);
if (follow_stream_dialog_.isMinimized() == true)
{
follow_stream_dialog_.showNormal();
}
else
{
follow_stream_dialog_.show();
}
follow_stream_dialog_.raise();
follow_stream_dialog_.activateWindow();
}
// Next / previous / first / last slots in packet_list
// Statistics Menu

View File

@ -35,6 +35,7 @@
#include "packet_list.h"
#include "proto_tree.h"
#include "wireshark_application.h"
#include <epan/ipproto.h>
#include "qt_ui_utils.h"
@ -246,6 +247,17 @@ PacketList::PacketList(QWidget *parent) :
ctx_menu_.addAction(window()->findChild<QAction *>("actionEditTimeShift"));
ctx_menu_.addAction(window()->findChild<QAction *>("actionEditPacketComment"));
ctx_menu_.addSeparator();
submenu = new QMenu(tr("Follow..."));
ctx_menu_.addMenu(submenu);
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowTCPStream"));
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowUDPStream"));
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowSSLStream"));
filter_actions_ << submenu->actions();
// " <menuitem name='FollowTCPStream' action='/Follow TCP Stream'/>\n"
// " <menuitem name='FollowUDPStream' action='/Follow UDP Stream'/>\n"
// " <menuitem name='FollowSSLStream' action='/Follow SSL Stream'/>\n"
ctx_menu_.addSeparator();
// " <menuitem name='ManuallyResolveAddress' action='/ManuallyResolveAddress'/>\n"
ctx_menu_.addSeparator();
@ -414,6 +426,7 @@ void PacketList::selectionChanged (const QItemSelection & selected, const QItemS
int row = selected.first().top();
cf_select_packet(cap_file_, row);
related_packet_delegate_.clear();
emit setMenusFollowStream();
if (!cap_file_->edt) return;
@ -447,8 +460,50 @@ void PacketList::contextMenuEvent(QContextMenuEvent *event)
bool fa_enabled = filter_actions_[0]->isEnabled();
QAction *act;
foreach (act, filter_actions_) {
foreach (act, filter_actions_)
{
act->setEnabled(true);
// check follow stream
if (act->text().contains("TCP"))
{
if (cap_file_->edt->pi.ipproto == IP_PROTO_TCP)
{
act->setEnabled(true);
}
else
{
act->setEnabled(false);
}
}
if (act->text().contains("UDP"))
{
if (cap_file_->edt->pi.ipproto == IP_PROTO_UDP)
{
act->setEnabled(true);
}
else
{
act->setEnabled(false);
}
}
if (act->text().contains("SSL"))
{
if (epan_dissect_packet_contains_field(cap_file_->edt, "ssl"))
{
act->setEnabled(true);
}
else
{
act->setEnabled(false);
}
}
}
ctx_column_ = columnAt(event->x());
ctx_menu_.exec(event->globalPos());

View File

@ -56,6 +56,7 @@ protected:
void selectionChanged (const QItemSelection & selected, const QItemSelection & deselected);
void contextMenuEvent(QContextMenuEvent *event);
private:
PacketListModel *packet_list_model_;
ProtoTree *proto_tree_;
@ -74,6 +75,7 @@ private:
signals:
void packetDissectionChanged();
void setMenusFollowStream();
public slots:
void setCaptureFile(capture_file *cf);