forked from osmocom/wireshark
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:
parent
41174fa490
commit
80f9326b2f
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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:
|
||||
*/
|
|
@ -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:
|
||||
*/
|
|
@ -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). */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
/*
|
||||
|
|
|
@ -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). */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
@ -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:
|
||||
*/
|
|
@ -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>
|
|
@ -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. */
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue