Add Flow Graph functionality to TShark
Add flow graph functionality to tshark through -z option. Output is same as ASCII format saved from GUI. Change-Id: Iee0bfea7215858e6488b4728581be28287e9ea1a Reviewed-on: https://code.wireshark.org/review/23652 Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
parent
620d54b1e3
commit
5f667694d3
|
@ -1621,6 +1621,7 @@ set(TSHARK_TAP_SRC
|
|||
ui/cli/tap-expert.c
|
||||
ui/cli/tap-exportobject.c
|
||||
ui/cli/tap-endpoints.c
|
||||
ui/cli/tap-flow.c
|
||||
ui/cli/tap-follow.c
|
||||
ui/cli/tap-funnel.c
|
||||
ui/cli/tap-gsm_astat.c
|
||||
|
|
|
@ -1109,6 +1109,26 @@ on those calls that match that filter.
|
|||
Example: B<-z "expert,note,tcp"> will only collect expert items for frames that
|
||||
include the tcp protocol, with a severity of note or higher.
|
||||
|
||||
=item B<-z> flow,I<name>,I<mode>,[I<filter>]
|
||||
|
||||
Displays the flow of data between two nodes. Output is the same as ASCII format
|
||||
saved from GUI.
|
||||
|
||||
I<name> specifies the flow name. It can be one of:
|
||||
|
||||
any All frames
|
||||
icmp ICMP
|
||||
icmpv6 ICMPv6
|
||||
lbm_uim UIM
|
||||
tcp TCP
|
||||
|
||||
I<mode> specifies the address type. It can be one of:
|
||||
|
||||
standard Any address
|
||||
network Network address
|
||||
|
||||
Example: B<-z flow,tcp,network> will show data flow for all TCP frames
|
||||
|
||||
=item B<-z> follow,I<prot>,I<mode>,I<filter>[I<,range>]
|
||||
|
||||
Displays the contents of a TCP or UDP stream between two nodes. The data
|
||||
|
|
|
@ -50,6 +50,7 @@ since version 2.4.0:
|
|||
* Improved NetMon .cap support with comments, event tracing, network filter,
|
||||
network info types and some Message Analyzer exported types.
|
||||
* Personal plugins folder on Linux/Unix is now ~/.local/lib/wireshark/plugins.
|
||||
* Add Flow Graph functionality to TShark using -z
|
||||
|
||||
//=== Removed Dissectors
|
||||
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include "column-info.h"
|
||||
#include "tap.h"
|
||||
#include "wmem/wmem.h"
|
||||
#include "wsutil/file_util.h"
|
||||
|
||||
#define NODE_OVERFLOW MAX_NUM_NODES+1
|
||||
|
||||
|
@ -191,7 +190,8 @@ void sequence_analysis_info_free(seq_analysis_info_t *sainfo)
|
|||
sequence_analysis_list_free(sainfo);
|
||||
|
||||
g_queue_free(sainfo->items);
|
||||
g_hash_table_destroy(sainfo->ht);
|
||||
if (sainfo->ht != NULL)
|
||||
g_hash_table_destroy(sainfo->ht);
|
||||
|
||||
g_free(sainfo);
|
||||
}
|
||||
|
@ -241,7 +241,8 @@ sequence_analysis_list_free(seq_analysis_info_t *sainfo)
|
|||
/* free the graph data items */
|
||||
|
||||
#if GLIB_CHECK_VERSION (2, 32, 0)
|
||||
g_queue_free_full(sainfo->items, sequence_analysis_item_free);
|
||||
if (sainfo->items != NULL)
|
||||
g_queue_free_full(sainfo->items, sequence_analysis_item_free);
|
||||
sainfo->items = g_queue_new();
|
||||
#else
|
||||
{
|
||||
|
@ -399,8 +400,8 @@ static void overwrite (GString *gstr, char *text_to_insert, guint32 p1, guint32
|
|||
}
|
||||
|
||||
|
||||
gboolean
|
||||
sequence_analysis_dump_to_file(const char *pathname, seq_analysis_info_t *sainfo, unsigned int first_node)
|
||||
void
|
||||
sequence_analysis_dump_to_file(FILE *of, seq_analysis_info_t *sainfo, unsigned int first_node)
|
||||
{
|
||||
guint32 i, display_items, display_nodes;
|
||||
guint32 start_position, end_position, item_width, header_length;
|
||||
|
@ -412,18 +413,13 @@ sequence_analysis_dump_to_file(const char *pathname, seq_analysis_info_t *sainfo
|
|||
GString *label_string, *empty_line, *separator_line, *tmp_str, *tmp_str2;
|
||||
const char *empty_header;
|
||||
char src_port[8], dst_port[8];
|
||||
GList *list;
|
||||
GList *list = NULL;
|
||||
char *addr_str;
|
||||
|
||||
FILE *of;
|
||||
|
||||
of = ws_fopen(pathname, "w");
|
||||
if (of==NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
display_items = 0;
|
||||
list = g_queue_peek_nth_link(sainfo->items, 0);
|
||||
if (sainfo->items != NULL)
|
||||
list = g_queue_peek_nth_link(sainfo->items, 0);
|
||||
|
||||
while (list)
|
||||
{
|
||||
sai = (seq_analysis_item_t *)list->data;
|
||||
|
@ -444,8 +440,7 @@ sequence_analysis_dump_to_file(const char *pathname, seq_analysis_info_t *sainfo
|
|||
|
||||
/* if not items to display */
|
||||
if (display_items == 0) {
|
||||
fclose (of);
|
||||
return TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
label_string = g_string_new("");
|
||||
|
@ -610,9 +605,6 @@ sequence_analysis_dump_to_file(const char *pathname, seq_analysis_info_t *sainfo
|
|||
g_string_free(separator_line, TRUE);
|
||||
g_string_free(tmp_str, TRUE);
|
||||
g_string_free(tmp_str2, TRUE);
|
||||
fclose (of);
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "packet_info.h"
|
||||
#include "tap.h"
|
||||
#include "address.h"
|
||||
#include "wsutil/file_util.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -202,12 +203,11 @@ WS_DLL_PUBLIC void sequence_analysis_free_nodes(seq_analysis_info_t *sainfo);
|
|||
|
||||
/** Write an ASCII version of the sequence diagram to a file.
|
||||
*
|
||||
* @param pathname Pathname of the file to write.
|
||||
* @param of File to write.
|
||||
* @param sainfo Sequence analysis information.
|
||||
* @param first_node Start drawing at this node.
|
||||
* @return TRUE on success, FALSE on failure.
|
||||
*/
|
||||
WS_DLL_PUBLIC gboolean sequence_analysis_dump_to_file(const char *pathname, seq_analysis_info_t *sainfo, unsigned int first_node);
|
||||
WS_DLL_PUBLIC void sequence_analysis_dump_to_file(FILE *of, seq_analysis_info_t *sainfo, unsigned int first_node);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ TSHARK_TAP_SRC = \
|
|||
tap-endpoints.c \
|
||||
tap-expert.c \
|
||||
tap-exportobject.c \
|
||||
tap-flow.c \
|
||||
tap-follow.c \
|
||||
tap-funnel.c \
|
||||
tap-gsm_astat.c \
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
/* tap-flow.c
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* This module provides udp and tcp follow stream capabilities to tshark.
|
||||
* It is only used by tshark and not wireshark.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <epan/sequence_analysis.h>
|
||||
#include <epan/stat_tap_ui.h>
|
||||
#include <epan/tap.h>
|
||||
|
||||
void register_tap_listener_follow(void);
|
||||
|
||||
#define STR_FLOW "flow,"
|
||||
#define STR_STANDARD ",standard"
|
||||
#define STR_NETWORK ",network"
|
||||
|
||||
WS_NORETURN static void flow_exit(const char *strp)
|
||||
{
|
||||
fprintf(stderr, "tshark: flow - %s\n", strp);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
flow_draw(void *arg)
|
||||
{
|
||||
seq_analysis_info_t* flow_info = (seq_analysis_info_t*)arg;
|
||||
|
||||
sequence_analysis_get_nodes(flow_info);
|
||||
|
||||
sequence_analysis_dump_to_file(stdout, flow_info, 0);
|
||||
|
||||
//clean up the data
|
||||
sequence_analysis_list_free(flow_info);
|
||||
sequence_analysis_info_free(flow_info);
|
||||
}
|
||||
|
||||
static gboolean flow_arg_strncmp(const char **opt_argp, const char *strp)
|
||||
{
|
||||
size_t len = strlen(strp);
|
||||
|
||||
if (strncmp(*opt_argp, strp, len) == 0)
|
||||
{
|
||||
*opt_argp += len;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
flow_arg_mode(const char **opt_argp, seq_analysis_info_t *flow_info)
|
||||
{
|
||||
if (flow_arg_strncmp(opt_argp, STR_STANDARD))
|
||||
{
|
||||
flow_info->any_addr = 1;
|
||||
}
|
||||
else if (flow_arg_strncmp(opt_argp, STR_NETWORK))
|
||||
{
|
||||
flow_info->any_addr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
flow_exit("Invalid address type.");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
flow_init(const char *opt_argp, void *userdata)
|
||||
{
|
||||
seq_analysis_info_t *flow_info = g_new0(seq_analysis_info_t, 1);
|
||||
GString *errp;
|
||||
register_analysis_t* analysis = (register_analysis_t*)userdata;
|
||||
const char *filter=NULL;
|
||||
|
||||
opt_argp += strlen(STR_FLOW);
|
||||
opt_argp += strlen(sequence_analysis_get_name(analysis));
|
||||
|
||||
flow_arg_mode(&opt_argp, flow_info);
|
||||
if (*opt_argp == ',') {
|
||||
filter = opt_argp + 1;
|
||||
}
|
||||
|
||||
flow_info->all_packets = TRUE;
|
||||
|
||||
sequence_analysis_list_free(flow_info);
|
||||
|
||||
errp = register_tap_listener(sequence_analysis_get_tap_listener_name(analysis), flow_info, filter, sequence_analysis_get_tap_flags(analysis),
|
||||
NULL, sequence_analysis_get_packet_func(analysis), flow_draw);
|
||||
|
||||
if (errp != NULL)
|
||||
{
|
||||
sequence_analysis_list_free(flow_info);
|
||||
sequence_analysis_info_free(flow_info);
|
||||
g_string_free(errp, TRUE);
|
||||
flow_exit("Error registering tap listener.");
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
flow_register(const void *key _U_, void *value, void *userdata _U_)
|
||||
{
|
||||
register_analysis_t* analysis = (register_analysis_t*)value;
|
||||
stat_tap_ui flow_ui;
|
||||
GString *cmd_str = g_string_new(STR_FLOW);
|
||||
|
||||
g_string_append(cmd_str, sequence_analysis_get_name(analysis));
|
||||
|
||||
flow_ui.group = REGISTER_STAT_GROUP_GENERIC;
|
||||
flow_ui.title = NULL; /* construct this from the protocol info? */
|
||||
flow_ui.cli_string = g_string_free(cmd_str, FALSE);
|
||||
flow_ui.tap_init_cb = flow_init;
|
||||
flow_ui.nparams = 0;
|
||||
flow_ui.params = NULL;
|
||||
register_stat_tap_ui(&flow_ui, analysis);
|
||||
g_free((char*)flow_ui.cli_string);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
register_tap_listener_flow(void)
|
||||
{
|
||||
sequence_analysis_table_iterate_tables(flow_register, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local Variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* ex: set shiftwidth=2 tabstop=8 expandtab:
|
||||
* :indentSize=2:tabSize=8:noTabs=true:
|
||||
*/
|
|
@ -255,6 +255,7 @@ on_save_bt_clicked (GtkWidget *button _U_,
|
|||
graph_analysis_data_t *user_data)
|
||||
{
|
||||
char *pathname;
|
||||
FILE *outfile;
|
||||
|
||||
/*
|
||||
* Loop until the user either selects a file or gives up.
|
||||
|
@ -265,8 +266,10 @@ on_save_bt_clicked (GtkWidget *button _U_,
|
|||
/* User gave up. */
|
||||
break;
|
||||
}
|
||||
if (sequence_analysis_dump_to_file(pathname, user_data->graph_info, user_data->dlg.first_node)) {
|
||||
/* We succeeded. */
|
||||
outfile = ws_fopen(pathname, "w");
|
||||
if (outfile != NULL) {
|
||||
sequence_analysis_dump_to_file(outfile, user_data->graph_info, user_data->dlg.first_node);
|
||||
fclose (outfile);
|
||||
g_free(pathname);
|
||||
break;
|
||||
} else {
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "file.h"
|
||||
#include "wsutil/nstime.h"
|
||||
#include "wsutil/utf8_entities.h"
|
||||
#include "wsutil/file_util.h"
|
||||
|
||||
#include <ui/qt/utils/color_utils.h>
|
||||
#include "progress_frame.h"
|
||||
|
@ -400,7 +401,13 @@ void SequenceDialog::on_buttonBox_accepted()
|
|||
} else if (extension.compare(jpeg_filter) == 0) {
|
||||
save_ok = ui->sequencePlot->saveJpg(file_name);
|
||||
} else if (extension.compare(ascii_filter) == 0 && !file_closed_ && info_->sainfo()) {
|
||||
save_ok = sequence_analysis_dump_to_file(file_name.toUtf8().constData(), info_->sainfo(), 0);
|
||||
FILE *outfile = ws_fopen(file_name.toUtf8().constData(), "w");
|
||||
if (outfile != NULL) {
|
||||
sequence_analysis_dump_to_file(outfile, info_->sainfo(), 0);
|
||||
save_ok = true;
|
||||
} else {
|
||||
save_ok = false;
|
||||
}
|
||||
}
|
||||
// else error dialog?
|
||||
if (save_ok) {
|
||||
|
|
Loading…
Reference in New Issue