diff options
Diffstat (limited to 'ui/gtk')
-rw-r--r-- | ui/gtk/CMakeLists.txt | 4 | ||||
-rw-r--r-- | ui/gtk/Makefile.common | 8 | ||||
-rw-r--r-- | ui/gtk/conversations_table.c | 3 | ||||
-rw-r--r-- | ui/gtk/follow_http.c | 313 | ||||
-rw-r--r-- | ui/gtk/follow_http.h | 44 | ||||
-rw-r--r-- | ui/gtk/follow_ssl.c | 352 | ||||
-rw-r--r-- | ui/gtk/follow_ssl.h | 45 | ||||
-rw-r--r-- | ui/gtk/follow_stream.c | 517 | ||||
-rw-r--r-- | ui/gtk/follow_stream.h | 60 | ||||
-rw-r--r-- | ui/gtk/follow_tcp.c | 327 | ||||
-rw-r--r-- | ui/gtk/follow_tcp.h | 55 | ||||
-rw-r--r-- | ui/gtk/follow_udp.c | 313 | ||||
-rw-r--r-- | ui/gtk/follow_udp.h | 45 | ||||
-rw-r--r-- | ui/gtk/font_utils.c | 4 | ||||
-rw-r--r-- | ui/gtk/main.c | 1 | ||||
-rw-r--r-- | ui/gtk/main_menubar.c | 5 | ||||
-rw-r--r-- | ui/gtk/prefs_font_color.c | 4 |
17 files changed, 437 insertions, 1663 deletions
diff --git a/ui/gtk/CMakeLists.txt b/ui/gtk/CMakeLists.txt index b32db52c87..1d11eebac3 100644 --- a/ui/gtk/CMakeLists.txt +++ b/ui/gtk/CMakeLists.txt @@ -53,11 +53,7 @@ set(WIRESHARK_GTK_SRC filter_utils.c find_dlg.c firewall_dlg.c - follow_http.c - follow_ssl.c follow_stream.c - follow_tcp.c - follow_udp.c font_utils.c goto_dlg.c graph_analysis.c diff --git a/ui/gtk/Makefile.common b/ui/gtk/Makefile.common index ffdb84e707..29675839f7 100644 --- a/ui/gtk/Makefile.common +++ b/ui/gtk/Makefile.common @@ -72,11 +72,7 @@ WIRESHARK_COMMON_GTK_SRC = \ filter_utils.c \ find_dlg.c \ firewall_dlg.c \ - follow_http.c \ - follow_ssl.c \ follow_stream.c \ - follow_tcp.c \ - follow_udp.c \ font_utils.c \ goto_dlg.c \ graph_analysis.c \ @@ -200,11 +196,7 @@ noinst_HEADERS = \ filter_utils.h \ find_dlg.h \ firewall_dlg.h \ - follow_http.h \ - follow_ssl.h \ follow_stream.h \ - follow_tcp.h \ - follow_udp.h \ font_utils.h \ goto_dlg.h \ graph_analysis.h \ diff --git a/ui/gtk/conversations_table.c b/ui/gtk/conversations_table.c index f34085cb0b..91e4ab13b0 100644 --- a/ui/gtk/conversations_table.c +++ b/ui/gtk/conversations_table.c @@ -44,8 +44,7 @@ #include "ui/gtk/help_dlg.h" #include "ui/gtk/main.h" #include "ui/gtk/stock_icons.h" -#include "ui/gtk/follow_tcp.h" -#include "ui/gtk/follow_udp.h" +#include "ui/gtk/follow_stream.h" #include "ui/gtk/keys.h" diff --git a/ui/gtk/follow_http.c b/ui/gtk/follow_http.c deleted file mode 100644 index cf651f2018..0000000000 --- a/ui/gtk/follow_http.c +++ /dev/null @@ -1,313 +0,0 @@ -/* follow_http.c - * HTTP specific routines for following traffic streams - * - * 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 <gtk/gtk.h> - -#include <epan/addr_resolv.h> -#include <epan/epan_dissect.h> -#include <epan/follow.h> -#include <epan/tap.h> - -#include <ui/simple_dialog.h> -#include <wsutil/utf8_entities.h> - -#include "gtkglobals.h" -#include "ui/gtk/follow_stream.h" -#include "ui/gtk/keys.h" -#include "ui/gtk/main.h" -#include "ui/gtk/follow_http.h" - -static frs_return_t -follow_read_http_stream(follow_info_t *follow_info, follow_print_line_func follow_print, void *arg); - -static gboolean -http_queue_packet_data(void *tapdata, packet_info *pinfo, - epan_dissect_t *edt _U_, const void *data) -{ - follow_record_t *follow_record; - follow_info_t *follow_info = (follow_info_t *)tapdata; - tvbuff_t *next_tvb = (tvbuff_t *)data; - - follow_record = g_new(follow_record_t,1); - - follow_record->data = g_byte_array_sized_new(tvb_captured_length(next_tvb)); - follow_record->data = g_byte_array_append(follow_record->data, - tvb_get_ptr(next_tvb, 0, -1), - tvb_captured_length(next_tvb)); - - if (follow_info->client_port == 0) { - follow_info->client_port = pinfo->srcport; - copy_address(&follow_info->client_ip, &pinfo->src); - } - - if (addresses_equal(&follow_info->client_ip, &pinfo->src) && follow_info->client_port == pinfo->srcport) - follow_record->is_server = FALSE; - else - follow_record->is_server = TRUE; - - /* update stream counter */ - follow_info->bytes_written[follow_record->is_server] += follow_record->data->len; - - follow_info->payload = g_list_append(follow_info->payload, follow_record); - return FALSE; -} - -/* Follow the HTTP 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). */ -void -follow_http_stream_cb(GtkWidget *w _U_, gpointer data _U_) -{ - GtkWidget *filter_te, *filter_cm; - gchar *follow_filter; - const gchar *previous_filter; - int filter_out_filter_len, previous_filter_len; - const char *hostname0, *hostname1; - char *port0, *port1; - gchar *server_to_client_string = NULL; - gchar *client_to_server_string = NULL; - gchar *both_directions_string = NULL; - follow_stats_t stats; - follow_info_t *follow_info; - GString *msg; - gboolean is_http = FALSE; - - is_http = proto_is_frame_protocol(cfile.edt->pi.layers, "http"); - - if (!is_http) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "Error following stream. Please make\n" - "sure you have a UDP packet selected."); - return; - } - - reset_stream_follow(TCP_STREAM); - - follow_info = g_new0(follow_info_t, 1); - follow_info->follow_type = FOLLOW_HTTP; - follow_info->read_stream = follow_read_http_stream; - - /* Create a new filter that matches all packets in the HTTP stream, - and set the display filter entry accordingly */ - follow_filter = build_follow_conv_filter(&cfile.edt->pi, "http"); - if (!follow_filter) - { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "Error creating filter for this stream.\n" - "A network layer header is needed"); - g_free(follow_info); - return; - } - - /* Set the display filter entry accordingly */ - filter_cm = (GtkWidget *)g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY); - filter_te = gtk_bin_get_child(GTK_BIN(filter_cm)); - - /* needed in follow_filter_out_stream(), is there a better way? */ - follow_info->filter_te = filter_te; - - /* save previous filter, const since we're not supposed to alter */ - previous_filter = - (const gchar *)gtk_entry_get_text(GTK_ENTRY(filter_te)); - - /* allocate our new filter. API claims g_malloc terminates program on failure */ - /* my calc for max alloc needed is really +10 but when did a few extra bytes hurt ? */ - previous_filter_len = previous_filter?(int)strlen(previous_filter):0; - filter_out_filter_len = (int)strlen(follow_filter) + previous_filter_len + 16; - follow_info->filter_out_filter = (gchar *)g_malloc(filter_out_filter_len); - - /* append the negation */ - if(previous_filter_len) { - g_snprintf(follow_info->filter_out_filter, filter_out_filter_len, - "%s and !(%s)", previous_filter, follow_filter); - } else { - g_snprintf(follow_info->filter_out_filter, filter_out_filter_len, - "!(%s)", follow_filter); - } - - /* data will be passed via tap callback*/ - msg = register_tap_listener("http_follow", follow_info, follow_filter, - 0, NULL, http_queue_packet_data, NULL); - if (msg) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "Can't register http_follow tap: %s\n", - msg->str); - g_free(follow_info->filter_out_filter); - g_free(follow_info); - g_free(follow_filter); - return; - } - - gtk_entry_set_text(GTK_ENTRY(filter_te), follow_filter); - - /* Run the display filter so it goes in effect - even if it's the - same as the previous display filter. */ - main_filter_packets(&cfile, follow_filter, TRUE); - - /* Free the filter string, as we're done with it. */ - g_free(follow_filter); - - remove_tap_listener(follow_info); - - /* Stream to show */ - follow_stats(&stats); - - if (stats.is_ipv6) { - hostname0 = get_hostname6(&stats.ip_address[0].ipv6); - hostname1 = get_hostname6(&stats.ip_address[1].ipv6); - } else { - hostname0 = get_hostname(stats.ip_address[0].ipv4); - hostname1 = get_hostname(stats.ip_address[1].ipv4); - } - - port0 = tcp_port_to_display(NULL, stats.port[0]); - port1 = tcp_port_to_display(NULL, stats.port[1]); - - follow_info->is_ipv6 = stats.is_ipv6; - - /* Both Stream Directions */ - both_directions_string = g_strdup_printf("Entire conversation (%u bytes)", follow_info->bytes_written[0] + follow_info->bytes_written[1]); - - if ((follow_info->client_port == stats.port[0]) && - ((stats.is_ipv6 && (memcmp(follow_info->client_ip.data, &stats.ip_address[0], 16) == 0)) || - (!stats.is_ipv6 && (memcmp(follow_info->client_ip.data, &stats.ip_address[0], 4) == 0)))) { - server_to_client_string = - g_strdup_printf("%s:%s " UTF8_RIGHTWARDS_ARROW " %s:%s (%u bytes)", - hostname0, port0, - hostname1, port1, - follow_info->bytes_written[0]); - - client_to_server_string = - g_strdup_printf("%s:%s " UTF8_RIGHTWARDS_ARROW " %s:%s (%u bytes)", - hostname1, port1, - hostname0, port0, - follow_info->bytes_written[1]); - } else { - server_to_client_string = - g_strdup_printf("%s:%s " UTF8_RIGHTWARDS_ARROW " %s:%s (%u bytes)", - hostname1, port1, - hostname0, port0, - follow_info->bytes_written[0]); - - client_to_server_string = - g_strdup_printf("%s:%s " UTF8_RIGHTWARDS_ARROW " %s:%s (%u bytes)", - hostname0, port0, - hostname1, port1, - follow_info->bytes_written[1]); - } - - follow_stream("Follow HTTP Stream", follow_info, both_directions_string, - server_to_client_string, client_to_server_string); - - wmem_free(NULL, port0); - wmem_free(NULL, port1); - g_free(both_directions_string); - g_free(server_to_client_string); - g_free(client_to_server_string); -} - -#define FLT_BUF_SIZE 1024 - -/* - * XXX - the routine pointed to by "print_line_fcn_p" doesn't get handed lines, - * it gets handed bufferfuls. That's fine for "follow_write_raw()" - * and "follow_add_to_gtk_text()", but, as "follow_print_text()" calls - * the "print_line()" routine from "print.c", and as that routine might - * genuinely expect to be handed a line (if, for example, it's using - * some OS or desktop environment's printing API, and that API expects - * to be handed lines), "follow_print_text()" should probably accumulate - * lines in a buffer and hand them "print_line()". (If there's a - * complete line in a buffer - i.e., there's nothing of the line in - * the previous buffer or the next buffer - it can just hand that to - * "print_line()" after filtering out non-printables, as an - * optimization.) - * - * This might or might not be the reason why C arrays display - * correctly but get extra blank lines very other line when printed. - */ -static frs_return_t -follow_read_http_stream(follow_info_t *follow_info, - follow_print_line_func follow_print, - void *arg) -{ - guint32 global_client_pos = 0, global_server_pos = 0; - guint32 server_packet_count = 0; - guint32 client_packet_count = 0; - guint32 *global_pos; - gboolean skip; - GList* cur; - frs_return_t frs_return; - follow_record_t *follow_record; - char *buffer; - - - for (cur = follow_info->payload; cur; cur = g_list_next(cur)) { - follow_record = (follow_record_t *)cur->data; - skip = FALSE; - if (!follow_record->is_server) { - global_pos = &global_client_pos; - if(follow_info->show_stream == FROM_SERVER) { - skip = TRUE; - } - } else { - global_pos = &global_server_pos; - if (follow_info->show_stream == FROM_CLIENT) { - skip = TRUE; - } - } - - if (!skip) { - buffer = (char *)g_memdup(follow_record->data->data, - follow_record->data->len); - - frs_return = follow_show(follow_info, follow_print, - buffer, - follow_record->data->len, - follow_record->is_server, arg, - global_pos, - &server_packet_count, - &client_packet_count); - g_free(buffer); - if(frs_return == FRS_PRINT_ERROR) - return frs_return; - } - } - - return FRS_OK; -} - -/* - * 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: - */ diff --git a/ui/gtk/follow_http.h b/ui/gtk/follow_http.h deleted file mode 100644 index 011fc353f4..0000000000 --- a/ui/gtk/follow_http.h +++ /dev/null @@ -1,44 +0,0 @@ -/* follow_http.h - * HTTP specific routines for following traffic streams - * - * 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_HTTP_H__ -#define __FOLLOW_HTTP_H__ - -/* Follow the HTTP 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). */ -void follow_http_stream_cb(GtkWidget * w, gpointer data _U_); - -#endif /* __FOLLOW_HTTP_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: - */ diff --git a/ui/gtk/follow_ssl.c b/ui/gtk/follow_ssl.c deleted file mode 100644 index 053283e2b2..0000000000 --- a/ui/gtk/follow_ssl.c +++ /dev/null @@ -1,352 +0,0 @@ -/* follow_ssl.c - * SSL specific routines for following traffic streams - * - * 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> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <gtk/gtk.h> - -#include <epan/follow.h> -#include <epan/prefs.h> -#include <epan/addr_resolv.h> -#include <epan/epan_dissect.h> -#include <wsutil/filesystem.h> -#include <epan/tap.h> - -#include <ui/alert_box.h> -#include <ui/simple_dialog.h> -#include <wsutil/utf8_entities.h> -#include <ui/util.h> - -#include "gtkglobals.h" -#include "ui/gtk/color_utils.h" -#include "ui/gtk/main.h" -#include "ui/gtk/dlg_utils.h" -#include "ui/gtk/file_dlg.h" -#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" - -#ifdef SSL_PLUGIN -#include "packet-ssl-utils.h" -#else -#include <epan/dissectors/packet-ssl-utils.h> -#endif - -static frs_return_t -follow_read_ssl_stream(follow_info_t *follow_info, follow_print_line_func follow_print, void *arg); - - -static gboolean -ssl_queue_packet_data(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, const void *ssl) -{ - follow_info_t * follow_info = (follow_info_t*) tapdata; - SslDecryptedRecord * rec = NULL; - SslDataInfo * appl_data = NULL; - SslPacketInfo * pi = (SslPacketInfo*)ssl; - show_stream_t from = FROM_CLIENT; - - /* Skip packets without decrypted payload data. */ - if (!pi || !pi->appl_data) return FALSE; - - /* Compute the packet's sender. */ - if (follow_info->client_port == 0) { - follow_info->client_port = pinfo->srcport; - copy_address(&follow_info->client_ip, &pinfo->src); - } - if (addresses_equal(&follow_info->client_ip, &pinfo->src) && - follow_info->client_port == pinfo->srcport) { - from = FROM_CLIENT; - } else { - from = FROM_SERVER; - } - - for (appl_data = pi->appl_data; appl_data != NULL; appl_data = appl_data->next) { - - /* TCP segments that contain the end of two or more SSL PDUs will be - queued to SSL taps for each of those PDUs. Therefore a single - packet could be processed by this SSL tap listener multiple times. - The following test handles that scenario by treating the - follow_info->bytes_written[] values as the next expected - appl_data->seq. Any appl_data instances that fall below that have - already been processed and must be skipped. */ - if (appl_data->seq < follow_info->bytes_written[from]) continue; - - /* Allocate a SslDecryptedRecord to hold the current appl_data - instance's decrypted data. Even though it would be possible to - consolidate multiple appl_data instances into a single rec, it is - beneficial to use a one-to-one mapping. This affords the Follow - Stream dialog view modes (ASCII, EBCDIC, Hex Dump, C Arrays, Raw) - the opportunity to accurately reflect SSL PDU boundaries. Currently - the Hex Dump view does by starting a new line, and the C Arrays - view does by starting a new array declaration. */ - rec = (SslDecryptedRecord*) g_malloc(sizeof(SslDecryptedRecord) + appl_data->plain_data.data_len); - rec->is_from_server = from == FROM_SERVER; - rec->data.data = (guchar*) (rec + 1); - rec->data.data_len = appl_data->plain_data.data_len; - memcpy(rec->data.data, appl_data->plain_data.data, appl_data->plain_data.data_len); - - /* Append the record to the follow_info structure. */ - follow_info->payload = g_list_append(follow_info->payload, rec); - follow_info->bytes_written[from] += rec->data.data_len; - } - - return FALSE; -} -/* 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). */ -void -follow_ssl_stream_cb(GtkWidget * w _U_, gpointer data _U_) -{ - GtkWidget * filter_te; - GtkWidget * filter_cm; - gchar * follow_filter; - const gchar * previous_filter; - int filter_out_filter_len; - int previous_filter_len; - const char * hostname0; - const char * hostname1; - char *port0, *port1; - const char * client_hostname; - const char * server_hostname; - const char * client_port; - const char * server_port; - gchar * server_to_client_string = NULL; - gchar * client_to_server_string = NULL; - gchar * both_directions_string = NULL; - const gchar * single_direction_format = NULL; - follow_stats_t stats; - follow_info_t * follow_info; - GString * msg; - - /* we got ssl so we can follow */ - if (!epan_dissect_packet_contains_field(cfile.edt, "ssl")) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "Error following stream. Please make\n" - "sure you have an SSL packet selected."); - return; - } - - follow_info = g_new0(follow_info_t, 1); - follow_info->follow_type = FOLLOW_SSL; - follow_info->read_stream = follow_read_ssl_stream; - - /* Create a new filter that matches all packets in the SSL stream, - and set the display filter entry accordingly */ - reset_stream_follow(TCP_STREAM); - follow_filter = build_follow_conv_filter(&cfile.edt->pi, NULL); - if (!follow_filter) - { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "Error creating filter for this stream.\n" - "A network layer header is needed"); - g_free(follow_info); - return; - } - - /* Set the display filter entry accordingly */ - filter_cm = (GtkWidget *)g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY); - filter_te = gtk_bin_get_child(GTK_BIN(filter_cm)); - - /* needed in follow_filter_out_stream(), is there a better way? */ - follow_info->filter_te = filter_te; - - /* save previous filter, const since we're not supposed to alter */ - previous_filter = - (const gchar *)gtk_entry_get_text(GTK_ENTRY(filter_te)); - - /* allocate our new filter. API claims g_malloc terminates program on failure */ - /* my calc for max alloc needed is really +10 but when did a few extra bytes hurt ? */ - previous_filter_len = previous_filter?(int)strlen(previous_filter):0; - filter_out_filter_len = (int)strlen(follow_filter) + previous_filter_len + 16; - follow_info->filter_out_filter = (gchar *)g_malloc(filter_out_filter_len); - - /* append the negation */ - if(previous_filter_len) { - g_snprintf(follow_info->filter_out_filter, filter_out_filter_len, - "%s and !(%s)", previous_filter, follow_filter); - } else { - g_snprintf(follow_info->filter_out_filter, filter_out_filter_len, - "!(%s)", follow_filter); - } - - /* data will be passed via tap callback*/ - msg = register_tap_listener("ssl", follow_info, follow_filter, 0, - NULL, ssl_queue_packet_data, NULL); - if (msg) - { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "Can't register ssl tap: %s\n",msg->str); - g_free(follow_info->filter_out_filter); - g_free(follow_info); - g_free(follow_filter); - return; - } - gtk_entry_set_text(GTK_ENTRY(filter_te), follow_filter); - - /* Run the display filter so it goes in effect - even if it's the - same as the previous display filter. */ - main_filter_packets(&cfile, follow_filter, TRUE); - - /* Free the filter string, as we're done with it. */ - g_free(follow_filter); - - remove_tap_listener(follow_info); - - /* Stream to show */ - follow_stats(&stats); - - if (stats.is_ipv6) { - hostname0 = get_hostname6(&stats.ip_address[0].ipv6); - hostname1 = get_hostname6(&stats.ip_address[1].ipv6); - } else { - hostname0 = get_hostname(stats.ip_address[0].ipv4); - hostname1 = get_hostname(stats.ip_address[1].ipv4); - } - - port0 = tcp_port_to_display(NULL, stats.port[0]); - port1 = tcp_port_to_display(NULL, stats.port[1]); - - follow_info->is_ipv6 = stats.is_ipv6; - - /* Generate the strings for the follow stream dialog's combo box, - starting with both directions... */ - both_directions_string = g_strdup_printf("Entire conversation (%u bytes)", follow_info->bytes_written[0] + follow_info->bytes_written[1]); - - /* ...and then the server-to-client and client-to-server directions. */ - if ((follow_info->client_port == stats.port[0]) && - ((stats.is_ipv6 && (memcmp(follow_info->client_ip.data, &stats.ip_address[0], 16) == 0)) || - (!stats.is_ipv6 && (memcmp(follow_info->client_ip.data, &stats.ip_address[0], 4) == 0)))) { - server_hostname = hostname0; - server_port = port0; - client_hostname = hostname1; - client_port = port1; - } else { - server_hostname = hostname1; - server_port = port1; - client_hostname = hostname0; - client_port = port0; - } - - single_direction_format = "%s:%s " UTF8_RIGHTWARDS_ARROW " %s:%s (%u bytes)"; - server_to_client_string = g_strdup_printf(single_direction_format, - server_hostname, server_port, - client_hostname, client_port, - follow_info->bytes_written[0]); - client_to_server_string = g_strdup_printf(single_direction_format, - client_hostname, client_port, - server_hostname, server_port, - follow_info->bytes_written[1]); - - /* Invoke the dialog. */ - follow_stream("Follow SSL Stream", follow_info, both_directions_string, - server_to_client_string, client_to_server_string); - - wmem_free(NULL, port0); - wmem_free(NULL, port1); - g_free(both_directions_string); - g_free(server_to_client_string); - g_free(client_to_server_string); -} - -#define FLT_BUF_SIZE 1024 - -/* - * XXX - the routine pointed to by "print_line_fcn_p" doesn't get handed lines, - * it gets handed bufferfuls. That's fine for "follow_write_raw()" - * and "follow_add_to_gtk_text()", but, as "follow_print_text()" calls - * the "print_line()" routine from "print.c", and as that routine might - * genuinely expect to be handed a line (if, for example, it's using - * some OS or desktop environment's printing API, and that API expects - * to be handed lines), "follow_print_text()" should probably accumulate - * lines in a buffer and hand them "print_line()". (If there's a - * complete line in a buffer - i.e., there's nothing of the line in - * the previous buffer or the next buffer - it can just hand that to - * "print_line()" after filtering out non-printables, as an - * optimization.) - * - * This might or might not be the reason why C arrays display - * correctly but get extra blank lines very other line when printed. - */ -static frs_return_t -follow_read_ssl_stream(follow_info_t *follow_info, - follow_print_line_func follow_print, - void *arg) -{ - guint32 global_client_pos = 0, global_server_pos = 0; - guint32 server_packet_count = 0; - guint32 client_packet_count = 0; - guint32 * global_pos; - GList * cur; - frs_return_t frs_return; - - for (cur = follow_info->payload; cur; cur = g_list_next(cur)) { - SslDecryptedRecord * rec = (SslDecryptedRecord*) cur->data; - gboolean include_rec = FALSE; - - if (rec->is_from_server) { - global_pos = &global_server_pos; - include_rec = (follow_info->show_stream == BOTH_HOSTS) || - (follow_info->show_stream == FROM_SERVER); - } else { - global_pos = &global_client_pos; - include_rec = (follow_info->show_stream == BOTH_HOSTS) || - (follow_info->show_stream == FROM_CLIENT); - } - - if (include_rec) { - size_t nchars = rec->data.data_len; - gchar *buffer = (gchar *)g_memdup(rec->data.data, (guint) nchars); - - frs_return = follow_show(follow_info, follow_print, buffer, nchars, - rec->is_from_server, arg, global_pos, - &server_packet_count, &client_packet_count); - g_free(buffer); - if (frs_return == FRS_PRINT_ERROR) - return frs_return; - } - } - - return FRS_OK; -} - -/* - * 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: - */ diff --git a/ui/gtk/follow_ssl.h b/ui/gtk/follow_ssl.h deleted file mode 100644 index a691261814..0000000000 --- a/ui/gtk/follow_ssl.h +++ /dev/null @@ -1,45 +0,0 @@ -/* follow_ssl.h - * SSL specific routines for following traffic streams - * - * 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_SSL_H__ -#define __FOLLOW_SSL_H__ - -/* 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). */ -void follow_ssl_stream_cb(GtkWidget * w, gpointer data _U_); - -#endif /* __FOLLOW_SSL_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: - */ - diff --git a/ui/gtk/follow_stream.c b/ui/gtk/follow_stream.c index 79ae6c7c09..ff98dfb227 100644 --- a/ui/gtk/follow_stream.c +++ b/ui/gtk/follow_stream.c @@ -29,11 +29,14 @@ #include <epan/addr_resolv.h> #include <epan/follow.h> +#include <epan/epan_dissect.h> #include <wsutil/filesystem.h> #include <epan/prefs.h> #include <epan/charsets.h> +#include <epan/tap.h> #include <epan/print.h> +#include <epan/dissectors/packet-ssl-utils.h> #include <ui/alert_box.h> #include <ui/last_open_dir.h> @@ -42,6 +45,8 @@ #include <wsutil/file_util.h> #include <wsutil/ws_version_info.h> +#include "gtkglobals.h" +#include "ui/gtk/keys.h" #include "ui/gtk/color_utils.h" #include "ui/gtk/stock_icons.h" #include "ui/gtk/dlg_utils.h" @@ -53,6 +58,7 @@ #include "ui/gtk/main.h" #include "ui/gtk/old-gtk-compat.h" +#include <wsutil/utf8_entities.h> #ifdef _WIN32 #include "wsutil/tempfile.h" #include "ui/win32/print_win32.h" @@ -69,22 +75,214 @@ static void follow_find_destroy_cb(GtkWidget * win _U_, gpointer data); static void follow_find_button_cb(GtkWidget * w, gpointer data); static void follow_destroy_cb(GtkWidget *w, gpointer data _U_); -GList *follow_infos = NULL; +static void follow_stream(const gchar *title, follow_info_t *follow_info, + gchar *both_directions_string, gchar *server_to_client_string, gchar *client_to_server_string); +static frs_return_t follow_show(follow_info_t *follow_info, + follow_print_line_func follow_print, + char *buffer, size_t nchars, gboolean is_from_server, void *arg, + guint32 *global_pos, guint32 *server_packet_count, + guint32 *client_packet_count); +static GList *follow_infos = NULL; + +/* + * XXX - the routine pointed to by "print_line_fcn_p" doesn't get handed lines, + * it gets handed bufferfuls. That's fine for "follow_write_raw()" + * and "follow_add_to_gtk_text()", but, as "follow_print_text()" calls + * the "print_line()" routine from "print.c", and as that routine might + * genuinely expect to be handed a line (if, for example, it's using + * some OS or desktop environment's printing API, and that API expects + * to be handed lines), "follow_print_text()" should probably accumulate + * lines in a buffer and hand them "print_line()". (If there's a + * complete line in a buffer - i.e., there's nothing of the line in + * the previous buffer or the next buffer - it can just hand that to + * "print_line()" after filtering out non-printables, as an + * optimization.) + * + * This might or might not be the reason why C arrays display + * correctly but get extra blank lines very other line when printed. + */ static frs_return_t -follow_read_stream(follow_info_t *follow_info, - gboolean (*print_line_fcn_p)(char *, size_t, gboolean, void *), - void *arg) +follow_common_read_stream(follow_info_t *follow_info, + follow_print_line_func follow_print, + void *arg) { - if (follow_info->read_stream == NULL) { - g_assert_not_reached(); - return (frs_return_t)0; + guint32 global_client_pos = 0, global_server_pos = 0; + guint32 server_packet_count = 0; + guint32 client_packet_count = 0; + guint32 *global_pos; + gboolean skip; + GList* cur; + frs_return_t frs_return; + follow_record_t *follow_record; + char *buffer; + + + for (cur = follow_info->payload; cur; cur = g_list_next(cur)) { + follow_record = (follow_record_t *)cur->data; + skip = FALSE; + if (!follow_record->is_server) { + global_pos = &global_client_pos; + if(follow_info->show_stream == FROM_SERVER) { + skip = TRUE; + } + } else { + global_pos = &global_server_pos; + if (follow_info->show_stream == FROM_CLIENT) { + skip = TRUE; + } + } + + if (!skip) { + buffer = (char *)g_memdup(follow_record->data->data, + follow_record->data->len); + + frs_return = follow_show(follow_info, follow_print, + buffer, + follow_record->data->len, + follow_record->is_server, arg, + global_pos, + &server_packet_count, + &client_packet_count); + g_free(buffer); + if(frs_return == FRS_PRINT_ERROR) + return frs_return; + } + } + + return FRS_OK; +} + +static void follow_stream_cb(register_follow_t* follower, follow_read_stream_func read_stream_func, GtkWidget * w _U_, gpointer data _U_) +{ + GtkWidget *filter_cm; + GtkWidget *filter_te; + gchar *follow_filter; + const gchar *previous_filter; + int filter_out_filter_len; + const char *hostname0, *hostname1; + char *port0, *port1; + gchar *server_to_client_string = NULL; + gchar *client_to_server_string = NULL; + gchar *both_directions_string = NULL; + follow_info_t *follow_info; + gtk_follow_info_t *gtk_follow_info; + GString *msg; + gboolean is_follow = FALSE; + guint32 ignore_stream; + char stream_window_title[256]; + + is_follow = proto_is_frame_protocol(cfile.edt->pi.layers, proto_get_protocol_filter_name(get_follow_proto_id(follower))); + + if (!is_follow) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, + "Error following stream. Please make\n" + "sure you have a %s packet selected.", proto_get_protocol_short_name(find_protocol_by_id(get_follow_proto_id(follower)))); + return; + } + + gtk_follow_info = g_new0(gtk_follow_info_t, 1); + follow_info = g_new0(follow_info_t, 1); + gtk_follow_info->read_stream = read_stream_func; + follow_info->gui_data = gtk_follow_info; + + /* Create a new filter that matches all packets in the TCP stream, + and set the display filter entry accordingly */ + follow_filter = get_follow_conv_func(follower)(&cfile.edt->pi, &ignore_stream); + if (!follow_filter) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, + "Error creating filter for this stream.\n" + "A transport or network layer header is needed"); + g_free(gtk_follow_info); + g_free(follow_info); + return; + } + + /* Set the display filter entry accordingly */ + filter_cm = (GtkWidget *)g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY); + filter_te = gtk_bin_get_child(GTK_BIN(filter_cm)); + + /* needed in follow_filter_out_stream(), is there a better way? */ + gtk_follow_info->filter_te = filter_te; + + /* save previous filter, const since we're not supposed to alter */ + previous_filter = + (const gchar *)gtk_entry_get_text(GTK_ENTRY(filter_te)); + + /* allocate our new filter. API claims g_malloc terminates program on failure */ + /* my calc for max alloc needed is really +10 but when did a few extra bytes hurt ? */ + filter_out_filter_len = (int)(strlen(follow_filter) + strlen(previous_filter) + 16); + follow_info->filter_out_filter = (gchar *)g_malloc(filter_out_filter_len); + + /* append the negation */ + if(strlen(previous_filter)) { + g_snprintf(follow_info->filter_out_filter, filter_out_filter_len, + "%s and !(%s)", previous_filter, follow_filter); + } else { + g_snprintf(follow_info->filter_out_filter, filter_out_filter_len, + "!(%s)", follow_filter); } - return follow_info->read_stream(follow_info, print_line_fcn_p, arg); + /* data will be passed via tap callback*/ + msg = register_tap_listener(get_follow_tap_string(follower), follow_info, follow_filter, + 0, NULL, get_follow_tap_handler(follower), NULL); + if (msg) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, + "Can't register %s tap: %s\n", + get_follow_tap_string(follower), msg->str); + g_free(gtk_follow_info); + g_free(follow_info->filter_out_filter); + g_free(follow_info); + g_free(follow_filter); + return; + } + + gtk_entry_set_text(GTK_ENTRY(filter_te), follow_filter); + + /* Run the display filter so it goes in effect - even if it's the + same as the previous display filter. */ + main_filter_packets(&cfile, follow_filter, TRUE); + + remove_tap_listener(follow_info); + + hostname0 = address_to_name(&follow_info->client_ip); + hostname1 = address_to_name(&follow_info->server_ip); + + port0 = get_follow_port_to_display(follower)(NULL, follow_info->client_port); + port1 = get_follow_port_to_display(follower)(NULL, follow_info->server_port); + + /* Both Stream Directions */ + both_directions_string = g_strdup_printf("Entire conversation (%u bytes)", follow_info->bytes_written[0] + follow_info->bytes_written[1]); + + server_to_client_string = + g_strdup_printf("%s:%s " UTF8_RIGHTWARDS_ARROW " %s:%s (%u bytes)", + hostname0, port0, + hostname1, port1, + follow_info->bytes_written[0]); + + client_to_server_string = + g_strdup_printf("%s:%s " UTF8_RIGHTWARDS_ARROW " %s:%s (%u bytes)", + hostname1, port1, + hostname0, port0, + follow_info->bytes_written[1]); + + g_snprintf(stream_window_title, 256, "Follow %s Stream (%s)", + proto_get_protocol_short_name(find_protocol_by_id(get_follow_proto_id(follower))), follow_filter); + follow_stream(stream_window_title, follow_info, both_directions_string, + server_to_client_string, client_to_server_string); + + /* Free the filter string, as we're done with it. */ + g_free(follow_filter); + + wmem_free(NULL, port0); + wmem_free(NULL, port1); + g_free(both_directions_string); + g_free(server_to_client_string); + g_free(client_to_server_string); + } -gboolean +static gboolean follow_add_to_gtk_text(char *buffer, size_t nchars, gboolean is_from_server, void *arg) { @@ -165,39 +363,13 @@ follow_write_raw(char *buffer, size_t nchars, gboolean is_from_server _U_, void return TRUE; } -/* Handles the display style toggling */ static void -follow_charset_toggle_cb(GtkWidget * w _U_, gpointer data) -{ - follow_info_t *follow_info = (follow_info_t *)data; - - /* - * A radio button toggles when it goes on and when it goes - * off, so when you click a radio button two signals are - * delivered. We only want to reprocess the display once, - * so we do it only when the button goes on. - */ - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) { - if (w == follow_info->ebcdic_bt) - follow_info->show_type = SHOW_EBCDIC; - else if (w == follow_info->hexdump_bt) - follow_info->show_type = SHOW_HEXDUMP; - else if (w == follow_info->carray_bt) - follow_info->show_type = SHOW_CARRAY; - else if (w == follow_info->ascii_bt) - follow_info->show_type = SHOW_ASCII; - else if (w == follow_info->raw_bt) - follow_info->show_type = SHOW_RAW; - follow_load_text(follow_info); - } -} - -void follow_load_text(follow_info_t *follow_info) { GtkTextBuffer *buf; + gtk_follow_info_t *gtk_follow_info = (gtk_follow_info_t *)follow_info->gui_data; - buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(follow_info->text)); + buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtk_follow_info->text)); /* prepare colors one time for repeated use by follow_add_to_gtk_text */ color_t_to_gdkcolor(&server_fg, &prefs.st_server_fg); @@ -218,27 +390,56 @@ follow_load_text(follow_info_t *follow_info) /* Delete any info already in text box */ gtk_text_buffer_set_text(buf, "", -1); - follow_read_stream(follow_info, follow_add_to_gtk_text, - follow_info->text); + gtk_follow_info->read_stream(follow_info, follow_add_to_gtk_text, + gtk_follow_info->text); } -void +/* Handles the display style toggling */ +static void +follow_charset_toggle_cb(GtkWidget * w _U_, gpointer data) +{ + follow_info_t *follow_info = (follow_info_t *)data; + gtk_follow_info_t *gtk_follow_info = (gtk_follow_info_t *)follow_info->gui_data; + + /* + * A radio button toggles when it goes on and when it goes + * off, so when you click a radio button two signals are + * delivered. We only want to reprocess the display once, + * so we do it only when the button goes on. + */ + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) { + if (w == gtk_follow_info->ebcdic_bt) + gtk_follow_info->show_type = SHOW_EBCDIC; + else if (w == gtk_follow_info->hexdump_bt) + gtk_follow_info->show_type = SHOW_HEXDUMP; + else if (w == gtk_follow_info->carray_bt) + gtk_follow_info->show_type = SHOW_CARRAY; + else if (w == gtk_follow_info->ascii_bt) + gtk_follow_info->show_type = SHOW_ASCII; + else if (w == gtk_follow_info->raw_bt) + gtk_follow_info->show_type = SHOW_RAW; + follow_load_text(follow_info); + } +} + +static void follow_filter_out_stream(GtkWidget * w _U_, gpointer data) { follow_info_t *follow_info = (follow_info_t *)data; + gtk_follow_info_t *gtk_follow_info = (gtk_follow_info_t *)follow_info->gui_data; /* Lock out user from messing with us. (ie. don't free our data!) */ - gtk_widget_set_sensitive(follow_info->streamwindow, FALSE); + gtk_widget_set_sensitive(gtk_follow_info->streamwindow, FALSE); /* Set the display filter. */ - gtk_entry_set_text(GTK_ENTRY(follow_info->filter_te), + gtk_entry_set_text(GTK_ENTRY(gtk_follow_info->filter_te), follow_info->filter_out_filter); /* Run the display filter so it goes in effect. */ main_filter_packets(&cfile, follow_info->filter_out_filter, FALSE); /* we force a subsequent close */ - window_destroy(follow_info->streamwindow); + window_destroy(gtk_follow_info->streamwindow); return; } @@ -247,22 +448,23 @@ static void follow_find_cb(GtkWidget * w _U_, gpointer data) { follow_info_t *follow_info = (follow_info_t *)data; + gtk_follow_info_t *gtk_follow_info = (gtk_follow_info_t *)follow_info->gui_data; GtkWidget *find_dlg_w, *main_vb, *buttons_row, *find_lb; GtkWidget *find_hb, *find_text_box, *find_bt, *cancel_bt; - if (follow_info->find_dlg_w != NULL) { + if (gtk_follow_info->find_dlg_w != NULL) { /* There's already a dialog box; reactivate it. */ - reactivate_window(follow_info->find_dlg_w); + reactivate_window(gtk_follow_info->find_dlg_w); return; } /* Create the find box */ find_dlg_w = dlg_window_new("Wireshark: Find text"); gtk_window_set_transient_for(GTK_WINDOW(find_dlg_w), - GTK_WINDOW(follow_info->streamwindow)); + GTK_WINDOW(gtk_follow_info->streamwindow)); gtk_widget_set_size_request(find_dlg_w, 225, -1); gtk_window_set_destroy_with_parent(GTK_WINDOW(find_dlg_w), TRUE); - follow_info->find_dlg_w = find_dlg_w; + gtk_follow_info->find_dlg_w = find_dlg_w; g_signal_connect(find_dlg_w, "destroy", G_CALLBACK(follow_find_destroy_cb), follow_info); @@ -317,6 +519,7 @@ follow_find_button_cb(GtkWidget * w, gpointer data) gboolean found; const gchar *find_string; follow_info_t *follow_info = (follow_info_t *)data; + gtk_follow_info_t *gtk_follow_info = (gtk_follow_info_t *)follow_info->gui_data; GtkTextBuffer *buffer; GtkTextIter iter, match_start, match_end; GtkTextMark *last_pos_mark; @@ -327,7 +530,7 @@ follow_find_button_cb(GtkWidget * w, gpointer data) find_string = gtk_entry_get_text(GTK_ENTRY(find_string_w)); /* Get the buffer associated with the follow stream */ - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(follow_info->text)); + buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtk_follow_info->text)); gtk_text_buffer_get_start_iter(buffer, &iter); /* Look for the search string in the buffer */ @@ -345,7 +548,7 @@ follow_find_button_cb(GtkWidget * w, gpointer data) last_pos_mark = gtk_text_buffer_create_mark (buffer, "last_position", &match_end, FALSE); - gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(follow_info->text), last_pos_mark); + gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(gtk_follow_info->text), last_pos_mark); } else { /* We didn't find a match */ simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK, @@ -362,10 +565,11 @@ follow_find_button_cb(GtkWidget * w, gpointer data) static void follow_find_destroy_cb(GtkWidget * win _U_, gpointer data) { - follow_info_t *follow_info = (follow_info_t *)data; + follow_info_t *follow_info = (follow_info_t *)data; + gtk_follow_info_t *gtk_follow_info = (gtk_follow_info_t *)follow_info->gui_data; /* Note that we no longer have a dialog box. */ - follow_info->find_dlg_w = NULL; + gtk_follow_info->find_dlg_w = NULL; } static void @@ -375,6 +579,7 @@ follow_print_stream(GtkWidget * w _U_, gpointer data) gboolean to_file; const char *print_dest; follow_info_t *follow_info =(follow_info_t *) data; + gtk_follow_info_t *gtk_follow_info = (gtk_follow_info_t *)follow_info->gui_data; #ifdef _WIN32 gboolean win_printer = FALSE; int tmp_fd; @@ -447,7 +652,7 @@ follow_print_stream(GtkWidget * w _U_, gpointer data) if (!print_preamble(stream, cfile.filename, get_ws_vcs_version_info())) goto print_error; - switch (follow_read_stream(follow_info, follow_print_text, stream)) { + switch (gtk_follow_info->read_stream(follow_info, follow_print_text, stream)) { case FRS_OK: break; case FRS_OPEN_ERROR: @@ -525,8 +730,9 @@ follow_save_as_ok_cb(gchar *to_name, follow_info_t *follow_info) { FILE *fh; print_stream_t *stream; + gtk_follow_info_t *gtk_follow_info = (gtk_follow_info_t *)follow_info->gui_data; - if (follow_info->show_type == SHOW_RAW) { + if (gtk_follow_info->show_type == SHOW_RAW) { /* Write the data out as raw binary data */ fh = ws_fopen(to_name, "wb"); } else { @@ -538,8 +744,8 @@ follow_save_as_ok_cb(gchar *to_name, follow_info_t *follow_info) return FALSE; } - if (follow_info->show_type == SHOW_RAW) { - switch (follow_read_stream(follow_info, follow_write_raw, fh)) { + if (gtk_follow_info->show_type == SHOW_RAW) { + switch (gtk_follow_info->read_stream(follow_info, follow_write_raw, fh)) { case FRS_OK: if (fclose(fh) == EOF) { write_failure_alert_box(to_name, errno); @@ -559,7 +765,7 @@ follow_save_as_ok_cb(gchar *to_name, follow_info_t *follow_info) } } else { stream = print_stream_text_stdio_new(fh); - switch (follow_read_stream(follow_info, follow_print_text, stream)) { + switch (gtk_follow_info->read_stream(follow_info, follow_print_text, stream)) { case FRS_OK: if (!destroy_print_stream(stream)) { write_failure_alert_box(to_name, errno); @@ -637,7 +843,7 @@ remember_follow_info(follow_info_t *follow_info) follow_infos = g_list_append(follow_infos, follow_info); } -#define IS_SHOW_TYPE(x) (follow_info->show_type == x ? 1 : 0) +#define IS_SHOW_TYPE(x) (gtk_follow_info->show_type == x ? 1 : 0) /* Remove a "follow_info_t" structure from the list. */ static void forget_follow_info(follow_info_t *follow_info) @@ -645,7 +851,7 @@ forget_follow_info(follow_info_t *follow_info) follow_infos = g_list_remove(follow_infos, follow_info); } -void +static void follow_stream(const gchar *title, follow_info_t *follow_info, gchar *both_directions_string, gchar *server_to_client_string, gchar *client_to_server_string) @@ -654,14 +860,14 @@ follow_stream(const gchar *title, follow_info_t *follow_info, GtkWidget *hbox, *bbox, *button, *radio_bt; GtkWidget *stream_fr, *stream_vb, *direction_hbox; GtkWidget *stream_cmb; - follow_stats_t stats; + gtk_follow_info_t *gtk_follow_info = (gtk_follow_info_t *)follow_info->gui_data; - follow_info->show_type = SHOW_RAW; + gtk_follow_info->show_type = SHOW_RAW; streamwindow = dlg_window_new(title); /* needed in follow_filter_out_stream(), is there a better way? */ - follow_info->streamwindow = streamwindow; + gtk_follow_info->streamwindow = streamwindow; gtk_widget_set_name(streamwindow, title); gtk_window_set_default_size(GTK_WINDOW(streamwindow), DEF_WIDTH, DEF_HEIGHT); @@ -672,11 +878,7 @@ follow_stream(const gchar *title, follow_info_t *follow_info, gtk_container_add(GTK_CONTAINER(streamwindow), vbox); /* content frame */ - if (incomplete_tcp_stream) { - stream_fr = gtk_frame_new("Stream Content (incomplete)"); - } else { - stream_fr = gtk_frame_new("Stream Content"); - } + stream_fr = gtk_frame_new("Stream Content"); gtk_box_pack_start(GTK_BOX (vbox), stream_fr, TRUE, TRUE, 0); gtk_widget_show(stream_fr); @@ -695,7 +897,7 @@ follow_stream(const gchar *title, follow_info_t *follow_info, gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_WORD_CHAR); gtk_container_add(GTK_CONTAINER(txt_scrollw), text); - follow_info->text = text; + gtk_follow_info->text = text; /* direction hbox */ direction_hbox = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 1, FALSE); @@ -740,18 +942,13 @@ follow_stream(const gchar *title, follow_info_t *follow_info, gtk_widget_set_tooltip_text(button, "Print the content as currently displayed"); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); - /* Stream to show */ - follow_stats(&stats); - - follow_info->is_ipv6 = stats.is_ipv6; - /* ASCII radio button */ radio_bt = gtk_radio_button_new_with_label(NULL, "ASCII"); gtk_widget_set_tooltip_text(radio_bt, "Stream data output in \"ASCII\" format"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_bt), IS_SHOW_TYPE(SHOW_ASCII)); gtk_box_pack_start(GTK_BOX(hbox), radio_bt, TRUE, TRUE, 0); g_signal_connect(radio_bt, "toggled", G_CALLBACK(follow_charset_toggle_cb), follow_info); - follow_info->ascii_bt = radio_bt; + gtk_follow_info->ascii_bt = radio_bt; /* EBCDIC radio button */ radio_bt = gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio_bt)), @@ -760,7 +957,7 @@ follow_stream(const gchar *title, follow_info_t *follow_info, gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_bt), IS_SHOW_TYPE(SHOW_EBCDIC)); gtk_box_pack_start(GTK_BOX(hbox), radio_bt, TRUE, TRUE, 0); g_signal_connect(radio_bt, "toggled", G_CALLBACK(follow_charset_toggle_cb), follow_info); - follow_info->ebcdic_bt = radio_bt; + gtk_follow_info->ebcdic_bt = radio_bt; /* HEX DUMP radio button */ radio_bt = gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio_bt)), @@ -769,7 +966,7 @@ follow_stream(const gchar *title, follow_info_t *follow_info, gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_bt), IS_SHOW_TYPE(SHOW_HEXDUMP)); gtk_box_pack_start(GTK_BOX(hbox), radio_bt, TRUE, TRUE, 0); g_signal_connect(radio_bt, "toggled", G_CALLBACK(follow_charset_toggle_cb),follow_info); - follow_info->hexdump_bt = radio_bt; + gtk_follow_info->hexdump_bt = radio_bt; /* C Array radio button */ radio_bt = gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio_bt)), @@ -778,7 +975,7 @@ follow_stream(const gchar *title, follow_info_t *follow_info, gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_bt), IS_SHOW_TYPE(SHOW_CARRAY)); gtk_box_pack_start(GTK_BOX(hbox), radio_bt, TRUE, TRUE, 0); g_signal_connect(radio_bt, "toggled", G_CALLBACK(follow_charset_toggle_cb), follow_info); - follow_info->carray_bt = radio_bt; + gtk_follow_info->carray_bt = radio_bt; /* Raw radio button */ radio_bt = gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio_bt)), @@ -790,7 +987,7 @@ follow_stream(const gchar *title, follow_info_t *follow_info, gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_bt), IS_SHOW_TYPE(SHOW_RAW)); gtk_box_pack_start(GTK_BOX(hbox), radio_bt, TRUE, TRUE, 0); g_signal_connect(radio_bt, "toggled", G_CALLBACK(follow_charset_toggle_cb), follow_info); - follow_info->raw_bt = radio_bt; + gtk_follow_info->raw_bt = radio_bt; /* Button row: help, filter out, close button */ bbox = dlg_button_row_new(WIRESHARK_STOCK_FILTER_OUT_STREAM, GTK_STOCK_CLOSE, GTK_STOCK_HELP, @@ -840,56 +1037,32 @@ follow_destroy_cb(GtkWidget *w, gpointer data _U_) { follow_info_t *follow_info; follow_record_t *follow_record; + gtk_follow_info_t *gtk_follow_info; GList *cur; - int i; follow_info = (follow_info_t *)g_object_get_data(G_OBJECT(w), E_FOLLOW_INFO_KEY); + gtk_follow_info = (gtk_follow_info_t *)follow_info->gui_data; - switch(follow_info->follow_type) { + for(cur = follow_info->payload; cur; cur = g_list_next(cur)) + if(cur->data) { + follow_record = (follow_record_t *)cur->data; + if(follow_record->data) + g_byte_array_free(follow_record->data, TRUE); - case FOLLOW_TCP : - i = ws_unlink(follow_info->data_out_filename); - if(i != 0) { - g_warning("Follow: Couldn't remove temporary file: \"%s\", errno: %s (%u)", - follow_info->data_out_filename, g_strerror(errno), errno); + g_free(follow_record); } - break; - - case FOLLOW_UDP : - case FOLLOW_HTTP : - for(cur = follow_info->payload; cur; cur = g_list_next(cur)) - if(cur->data) { - follow_record = (follow_record_t *)cur->data; - if(follow_record->data) - g_byte_array_free(follow_record->data, TRUE); - - g_free(follow_record); - } - g_list_free(follow_info->payload); - break; + g_list_free(follow_info->payload); - case FOLLOW_SSL : - /* free decrypted data list*/ - for (cur = follow_info->payload; cur; cur = g_list_next(cur)) - if (cur->data) - { - g_free(cur->data); - cur->data = NULL; - } - g_list_free (follow_info->payload); - break; - } - - g_free(follow_info->data_out_filename); g_free(follow_info->filter_out_filter); g_free((gpointer)follow_info->client_ip.data); forget_follow_info(follow_info); + g_free(gtk_follow_info); g_free(follow_info); gtk_widget_destroy(w); } -frs_return_t +static frs_return_t follow_show(follow_info_t *follow_info, follow_print_line_func follow_print, char *buffer, size_t nchars, gboolean is_from_server, void *arg, @@ -899,8 +1072,9 @@ follow_show(follow_info_t *follow_info, gchar initbuf[256]; guint32 current_pos; static const gchar hexchars[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; + gtk_follow_info_t *gtk_follow_info = (gtk_follow_info_t *)follow_info->gui_data; - switch (follow_info->show_type) { + switch (gtk_follow_info->show_type) { case SHOW_EBCDIC: /* If our native arch is ASCII, call: */ @@ -1024,6 +1198,123 @@ follow_show(follow_info_t *follow_info, return FRS_OK; } +/* Follow the TCP 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). */ +void +follow_tcp_stream_cb(GtkWidget * w _U_, gpointer data _U_) +{ + register_follow_t* follower = get_follow_by_name("TCP"); + + follow_stream_cb(follower, follow_common_read_stream, w, data); +} + +/* 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). */ +void +follow_udp_stream_cb(GtkWidget * w _U_, gpointer data _U_) +{ + register_follow_t* follower = get_follow_by_name("UDP"); + + follow_stream_cb(follower, follow_common_read_stream, w, data); +} + +/* Follow the HTTP 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). */ +void +follow_http_stream_cb(GtkWidget * w _U_, gpointer data _U_) +{ + register_follow_t* follower = get_follow_by_name("HTTP"); + + follow_stream_cb(follower, follow_common_read_stream, w, data); +} + +/* + * XXX - the routine pointed to by "print_line_fcn_p" doesn't get handed lines, + * it gets handed bufferfuls. That's fine for "follow_write_raw()" + * and "follow_add_to_gtk_text()", but, as "follow_print_text()" calls + * the "print_line()" routine from "print.c", and as that routine might + * genuinely expect to be handed a line (if, for example, it's using + * some OS or desktop environment's printing API, and that API expects + * to be handed lines), "follow_print_text()" should probably accumulate + * lines in a buffer and hand them "print_line()". (If there's a + * complete line in a buffer - i.e., there's nothing of the line in + * the previous buffer or the next buffer - it can just hand that to + * "print_line()" after filtering out non-printables, as an + * optimization.) + * + * This might or might not be the reason why C arrays display + * correctly but get extra blank lines very other line when printed. + */ +static frs_return_t +follow_read_ssl_stream(follow_info_t *follow_info, + follow_print_line_func follow_print, + void *arg) +{ + guint32 global_client_pos = 0, global_server_pos = 0; + guint32 server_packet_count = 0; + guint32 client_packet_count = 0; + guint32 * global_pos; + GList * cur; + frs_return_t frs_return; + + for (cur = follow_info->payload; cur; cur = g_list_next(cur)) { + SslDecryptedRecord * rec = (SslDecryptedRecord*) cur->data; + gboolean include_rec = FALSE; + + if (rec->is_from_server) { + global_pos = &global_server_pos; + include_rec = (follow_info->show_stream == BOTH_HOSTS) || + (follow_info->show_stream == FROM_SERVER); + } else { + global_pos = &global_client_pos; + include_rec = (follow_info->show_stream == BOTH_HOSTS) || + (follow_info->show_stream == FROM_CLIENT); + } + + if (include_rec) { + size_t nchars = rec->data.data_len; + gchar *buffer = (gchar *)g_memdup(rec->data.data, (guint) nchars); + + frs_return = follow_show(follow_info, follow_print, buffer, nchars, + rec->is_from_server, arg, global_pos, + &server_packet_count, &client_packet_count); + g_free(buffer); + if (frs_return == FRS_PRINT_ERROR) + return frs_return; + } + } + + return FRS_OK; +} + + +/* 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). */ +void +follow_ssl_stream_cb(GtkWidget * w _U_, gpointer data _U_) +{ + register_follow_t* follower = get_follow_by_name("SSL"); + + follow_stream_cb(follower, follow_read_ssl_stream, w, data); +} + +static void +follow_redraw(gpointer data, gpointer user_data _U_) +{ + follow_load_text((follow_info_t *)data); +} + +/* Redraw the text in all "Follow Stream" windows. */ +void +follow_stream_redraw_all(void) +{ + g_list_foreach(follow_infos, follow_redraw, NULL); +} + /* * Editor modelines - http://www.wireshark.org/tools/modelines.html * diff --git a/ui/gtk/follow_stream.h b/ui/gtk/follow_stream.h index cb5252b612..8b3f7d7eaa 100644 --- a/ui/gtk/follow_stream.h +++ b/ui/gtk/follow_stream.h @@ -25,18 +25,11 @@ #define __FOLLOW_STREAM_H__ #include <gtk/gtk.h> -#include <ui/follow.h> +#include <epan/follow.h> -struct _follow_info; -typedef gboolean (*follow_print_line_func)(char *, size_t, gboolean, void *); -typedef frs_return_t (*follow_read_stream_func)(struct _follow_info *follow_info, follow_print_line_func follow_print, void *arg); - -typedef struct _follow_info { - follow_type_t follow_type; - show_stream_t show_stream; +typedef struct _gtk_follow_info { show_type_t show_type; - char *data_out_filename; GtkWidget *text; GtkWidget *ascii_bt; GtkWidget *ebcdic_bt; @@ -44,37 +37,38 @@ typedef struct _follow_info { GtkWidget *carray_bt; GtkWidget *raw_bt; GtkWidget *find_dlg_w; - gboolean is_ipv6; - char *filter_out_filter; GtkWidget *filter_te; GtkWidget *streamwindow; - GList *payload; - guint bytes_written[2]; /* Index with FROM_CLIENT or FROM_SERVER for readability. */ - guint client_port; - address client_ip; follow_read_stream_func read_stream; -} follow_info_t; +} gtk_follow_info_t; #define E_FOLLOW_INFO_KEY "follow_info_key" -/* List of "follow_info_t" structures for all "Follow TCP Stream" windows, - so we can redraw them all if the colors or font changes. */ -extern GList *follow_infos; +/** Redraw the text in all "Follow TCP Stream" windows. */ +extern void follow_stream_redraw_all(void); + +/** User requested the "Follow TCP Stream" dialog box by menu or toolbar. + * + * @param widget parent widget (unused) + * @param data unused + */ +extern void follow_tcp_stream_cb( GtkWidget *widget, gpointer data); + +/* 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). */ +void follow_udp_stream_cb(GtkWidget * w, gpointer data _U_); + +/* Follow the HTTP 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). */ +void follow_http_stream_cb(GtkWidget * w, gpointer data _U_); + +/* 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). */ +void follow_ssl_stream_cb(GtkWidget * w, gpointer data _U_); -void follow_load_text(follow_info_t *follow_info); -void follow_filter_out_stream(GtkWidget * w, gpointer parent_w); -void follow_stream(const gchar *title, follow_info_t *follow_info, - gchar *both_directions_string, - gchar *server_to_client_string, - gchar *client_to_server_string); -frs_return_t follow_show(follow_info_t *follow_info, - follow_print_line_func follow_print, - char *buffer, size_t nchars, gboolean is_server, - void *arg, guint32 *global_pos, - guint32 *server_packet_count, - guint32 *client_packet_count); -gboolean follow_add_to_gtk_text(char *buffer, size_t nchars, gboolean is_server, - void *arg); #endif /* __FOLLOW_STREAM_H__ */ diff --git a/ui/gtk/follow_tcp.c b/ui/gtk/follow_tcp.c deleted file mode 100644 index edfbfac381..0000000000 --- a/ui/gtk/follow_tcp.c +++ /dev/null @@ -1,327 +0,0 @@ -/* follow_tcp.c - * TCP specific routines for following traffic streams - * - * 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 <gtk/gtk.h> - -#include <epan/addr_resolv.h> -#include <epan/epan_dissect.h> -#include <epan/follow.h> -#include <epan/tap.h> - -#include <ui/simple_dialog.h> -#include <wsutil/utf8_entities.h> - -#include "gtkglobals.h" -#include "ui/gtk/follow_stream.h" -#include "ui/gtk/keys.h" -#include "ui/gtk/main.h" -#include "ui/gtk/follow_tcp.h" - - -static frs_return_t -follow_read_tcp_stream(follow_info_t *follow_info, follow_print_line_func follow_print, void *arg); - -static void -follow_redraw(gpointer data, gpointer user_data _U_) -{ - follow_load_text((follow_info_t *)data); -} - -/* Redraw the text in all "Follow TCP Stream" windows. */ -void -follow_tcp_redraw_all(void) -{ - g_list_foreach(follow_infos, follow_redraw, NULL); -} - -static gboolean -tcp_queue_packet_data(void *tapdata, packet_info *pinfo, - epan_dissect_t *edt _U_, const void *data) -{ - follow_record_t *follow_record; - follow_info_t *follow_info = (follow_info_t *)tapdata; - tvbuff_t *next_tvb = (tvbuff_t *)data; - - follow_record = g_new(follow_record_t,1); - - follow_record->data = g_byte_array_sized_new(tvb_captured_length(next_tvb)); - follow_record->data = g_byte_array_append(follow_record->data, - tvb_get_ptr(next_tvb, 0, -1), - tvb_captured_length(next_tvb)); - - if (follow_info->client_port == 0) { - follow_info->client_port = pinfo->srcport; - copy_address(&follow_info->client_ip, &pinfo->src); - } - - if (addresses_equal(&follow_info->client_ip, &pinfo->src) && follow_info->client_port == pinfo->srcport) - follow_record->is_server = FALSE; - else - follow_record->is_server = TRUE; - - /* update stream counter */ - follow_info->bytes_written[follow_record->is_server] += follow_record->data->len; - - follow_info->payload = g_list_append(follow_info->payload, follow_record); - return FALSE; -} - -/* Follow the TCP 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). */ -void -follow_tcp_stream_cb(GtkWidget * w _U_, gpointer data _U_) -{ - GtkWidget *filter_cm; - GtkWidget *filter_te; - gchar *follow_filter; - const gchar *previous_filter; - int filter_out_filter_len; - const char *hostname0, *hostname1; - char *port0, *port1; - gchar *server_to_client_string = NULL; - gchar *client_to_server_string = NULL; - gchar *both_directions_string = NULL; - follow_stats_t stats; - follow_info_t *follow_info; - GString *msg; - gboolean is_tcp = FALSE; - - is_tcp = proto_is_frame_protocol(cfile.edt->pi.layers, "tcp"); - - if (!is_tcp) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "Error following stream. Please make\n" - "sure you have a TCP packet selected."); - return; - } - - reset_stream_follow(TCP_STREAM); - - follow_info = g_new0(follow_info_t, 1); - follow_info->follow_type = FOLLOW_TCP; - follow_info->read_stream = follow_read_tcp_stream; - - /* Create a new filter that matches all packets in the TCP stream, - and set the display filter entry accordingly */ - follow_filter = build_follow_conv_filter(&cfile.edt->pi, NULL); - if (!follow_filter) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "Error creating filter for this stream.\n" - "A transport or network layer header is needed"); - g_free(follow_info); - return; - } - - /* Set the display filter entry accordingly */ - filter_cm = (GtkWidget *)g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY); - filter_te = gtk_bin_get_child(GTK_BIN(filter_cm)); - - /* needed in follow_filter_out_stream(), is there a better way? */ - follow_info->filter_te = filter_te; - - /* save previous filter, const since we're not supposed to alter */ - previous_filter = - (const gchar *)gtk_entry_get_text(GTK_ENTRY(filter_te)); - - /* allocate our new filter. API claims g_malloc terminates program on failure */ - /* my calc for max alloc needed is really +10 but when did a few extra bytes hurt ? */ - filter_out_filter_len = (int)(strlen(follow_filter) + strlen(previous_filter) + 16); - follow_info->filter_out_filter = (gchar *)g_malloc(filter_out_filter_len); - - /* append the negation */ - if(strlen(previous_filter)) { - g_snprintf(follow_info->filter_out_filter, filter_out_filter_len, - "%s and !(%s)", previous_filter, follow_filter); - } else { - g_snprintf(follow_info->filter_out_filter, filter_out_filter_len, - "!(%s)", follow_filter); - } - - /* data will be passed via tap callback*/ - msg = register_tap_listener("tcp_follow", follow_info, follow_filter, - 0, NULL, tcp_queue_packet_data, NULL); - if (msg) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "Can't register tcp_follow tap: %s\n", - msg->str); - g_free(follow_info->filter_out_filter); - g_free(follow_info); - g_free(follow_filter); - return; - } - - gtk_entry_set_text(GTK_ENTRY(filter_te), follow_filter); - - /* Run the display filter so it goes in effect - even if it's the - same as the previous display filter. */ - main_filter_packets(&cfile, follow_filter, TRUE); - - remove_tap_listener(follow_info); - - /* Stream to show */ - follow_stats(&stats); - - if (stats.is_ipv6) { - hostname0 = get_hostname6(&stats.ip_address[0].ipv6); - hostname1 = get_hostname6(&stats.ip_address[1].ipv6); - } else { - hostname0 = get_hostname(stats.ip_address[0].ipv4); - hostname1 = get_hostname(stats.ip_address[1].ipv4); - } - - follow_info->is_ipv6 = stats.is_ipv6; - - port0 = tcp_port_to_display(NULL, stats.port[0]); - port1 = tcp_port_to_display(NULL, stats.port[1]); - - /* Both Stream Directions */ - both_directions_string = g_strdup_printf("Entire conversation (%u bytes)", follow_info->bytes_written[0] + follow_info->bytes_written[1]); - - if ((follow_info->client_port == stats.port[0]) && - ((stats.is_ipv6 && (memcmp(follow_info->client_ip.data, &stats.ip_address[0], 16) == 0)) || - (!stats.is_ipv6 && (memcmp(follow_info->client_ip.data, &stats.ip_address[0], 4) == 0)))) { - server_to_client_string = - g_strdup_printf("%s:%s " UTF8_RIGHTWARDS_ARROW " %s:%s (%u bytes)", - hostname0, port0, - hostname1, port1, - follow_info->bytes_written[0]); - - client_to_server_string = - g_strdup_printf("%s:%s " UTF8_RIGHTWARDS_ARROW " %s:%s (%u bytes)", - hostname1, port1, - hostname0, port0, - follow_info->bytes_written[1]); - } else { - server_to_client_string = - g_strdup_printf("%s:%s " UTF8_RIGHTWARDS_ARROW " %s:%s (%u bytes)", - hostname1, port1, - hostname0, port0, - follow_info->bytes_written[0]); - - client_to_server_string = - g_strdup_printf("%s:%s " UTF8_RIGHTWARDS_ARROW " %s:%s (%u bytes)", - hostname0, port0, - hostname1, port1, - follow_info->bytes_written[1]); - } - - follow_stream("Follow TCP Stream", follow_info, both_directions_string, - server_to_client_string, client_to_server_string); - - /* Free the filter string, as we're done with it. */ - g_free(follow_filter); - - wmem_free(NULL, port0); - wmem_free(NULL, port1); - g_free(both_directions_string); - g_free(server_to_client_string); - g_free(client_to_server_string); -} - -#define FLT_BUF_SIZE 1024 - -/* - * XXX - the routine pointed to by "print_line_fcn_p" doesn't get handed lines, - * it gets handed bufferfuls. That's fine for "follow_write_raw()" - * and "follow_add_to_gtk_text()", but, as "follow_print_text()" calls - * the "print_line()" routine from "print.c", and as that routine might - * genuinely expect to be handed a line (if, for example, it's using - * some OS or desktop environment's printing API, and that API expects - * to be handed lines), "follow_print_text()" should probably accumulate - * lines in a buffer and hand them "print_line()". (If there's a - * complete line in a buffer - i.e., there's nothing of the line in - * the previous buffer or the next buffer - it can just hand that to - * "print_line()" after filtering out non-printables, as an - * optimization.) - * - * This might or might not be the reason why C arrays display - * correctly but get extra blank lines very other line when printed. - */ -static frs_return_t -follow_read_tcp_stream(follow_info_t *follow_info, - follow_print_line_func follow_print, - void *arg) -{ - guint32 global_client_pos = 0, global_server_pos = 0; - guint32 server_packet_count = 0; - guint32 client_packet_count = 0; - guint32 *global_pos; - gboolean skip; - GList* cur; - frs_return_t frs_return; - follow_record_t *follow_record; - char *buffer; - - - for (cur = follow_info->payload; cur; cur = g_list_next(cur)) { - follow_record = (follow_record_t *)cur->data; - skip = FALSE; - if (!follow_record->is_server) { - global_pos = &global_client_pos; - if(follow_info->show_stream == FROM_SERVER) { - skip = TRUE; - } - } else { - global_pos = &global_server_pos; - if (follow_info->show_stream == FROM_CLIENT) { - skip = TRUE; - } - } - - if (!skip) { - buffer = (char *)g_memdup(follow_record->data->data, - follow_record->data->len); - - frs_return = follow_show(follow_info, follow_print, - buffer, - follow_record->data->len, - follow_record->is_server, arg, - global_pos, - &server_packet_count, - &client_packet_count); - g_free(buffer); - if(frs_return == FRS_PRINT_ERROR) - return frs_return; - } - } - - return FRS_OK; -} - -/* - * 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: - */ diff --git a/ui/gtk/follow_tcp.h b/ui/gtk/follow_tcp.h deleted file mode 100644 index bb0e4c905b..0000000000 --- a/ui/gtk/follow_tcp.h +++ /dev/null @@ -1,55 +0,0 @@ -/* follow_tcp.h - * TCP specific routines for following traffic streams - * - * Wireshark - Network traffic analyzer - * By Gerald Combs <gerald@wireshark.org> - * Copyright 2000 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_TCP_H__ -#define __FOLLOW_TCP_H__ - -/** @file - * "Follow TCP Stream" dialog box. - * @ingroup dialog_group - */ - -/** User requested the "Follow TCP Stream" dialog box by menu or toolbar. - * - * @param widget parent widget (unused) - * @param data unused - */ -extern void follow_tcp_stream_cb( GtkWidget *widget, gpointer data); - -/** Redraw the text in all "Follow TCP Stream" windows. */ -extern void follow_tcp_redraw_all(void); - -#endif /* __FOLLOW_TCP_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: - */ diff --git a/ui/gtk/follow_udp.c b/ui/gtk/follow_udp.c deleted file mode 100644 index c519d82685..0000000000 --- a/ui/gtk/follow_udp.c +++ /dev/null @@ -1,313 +0,0 @@ -/* follow_udp.c - * UDP specific routines for following traffic streams - * - * 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 <gtk/gtk.h> - -#include <epan/addr_resolv.h> -#include <epan/epan_dissect.h> -#include <epan/follow.h> -#include <epan/tap.h> - -#include <ui/simple_dialog.h> -#include <wsutil/utf8_entities.h> - -#include "gtkglobals.h" -#include "ui/gtk/follow_stream.h" -#include "ui/gtk/keys.h" -#include "ui/gtk/main.h" -#include "ui/gtk/follow_udp.h" - -static frs_return_t -follow_read_udp_stream(follow_info_t *follow_info, follow_print_line_func follow_print, void *arg); - -static gboolean -udp_queue_packet_data(void *tapdata, packet_info *pinfo, - epan_dissect_t *edt _U_, const void *data) -{ - follow_record_t *follow_record; - follow_info_t *follow_info = (follow_info_t *)tapdata; - tvbuff_t *next_tvb = (tvbuff_t *)data; - - follow_record = g_new(follow_record_t,1); - - follow_record->data = g_byte_array_sized_new(tvb_captured_length(next_tvb)); - follow_record->data = g_byte_array_append(follow_record->data, - tvb_get_ptr(next_tvb, 0, -1), - tvb_captured_length(next_tvb)); - - if (follow_info->client_port == 0) { - follow_info->client_port = pinfo->srcport; - copy_address(&follow_info->client_ip, &pinfo->src); - } - - if (addresses_equal(&follow_info->client_ip, &pinfo->src) && follow_info->client_port == pinfo->srcport) - follow_record->is_server = FALSE; - else - follow_record->is_server = TRUE; - - /* update stream counter */ - follow_info->bytes_written[follow_record->is_server] += follow_record->data->len; - - follow_info->payload = g_list_append(follow_info->payload, follow_record); - return FALSE; -} - -/* 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). */ -void -follow_udp_stream_cb(GtkWidget *w _U_, gpointer data _U_) -{ - GtkWidget *filter_te, *filter_cm; - gchar *follow_filter; - const gchar *previous_filter; - int filter_out_filter_len, previous_filter_len; - const char *hostname0, *hostname1; - char *port0, *port1; - gchar *server_to_client_string = NULL; - gchar *client_to_server_string = NULL; - gchar *both_directions_string = NULL; - follow_stats_t stats; - follow_info_t *follow_info; - GString *msg; - gboolean is_udp = FALSE; - - is_udp = proto_is_frame_protocol(cfile.edt->pi.layers, "udp"); - - if (!is_udp) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "Error following stream. Please make\n" - "sure you have a UDP packet selected."); - return; - } - - reset_stream_follow(UDP_STREAM); - - follow_info = g_new0(follow_info_t, 1); - follow_info->follow_type = FOLLOW_UDP; - follow_info->read_stream = follow_read_udp_stream; - - /* Create a new filter that matches all packets in the UDP stream, - and set the display filter entry accordingly */ - follow_filter = build_follow_conv_filter(&cfile.edt->pi, NULL); - if (!follow_filter) - { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "Error creating filter for this stream.\n" - "A network layer header is needed"); - g_free(follow_info); - return; - } - - /* Set the display filter entry accordingly */ - filter_cm = (GtkWidget *)g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY); - filter_te = gtk_bin_get_child(GTK_BIN(filter_cm)); - - /* needed in follow_filter_out_stream(), is there a better way? */ - follow_info->filter_te = filter_te; - - /* save previous filter, const since we're not supposed to alter */ - previous_filter = - (const gchar *)gtk_entry_get_text(GTK_ENTRY(filter_te)); - - /* allocate our new filter. API claims g_malloc terminates program on failure */ - /* my calc for max alloc needed is really +10 but when did a few extra bytes hurt ? */ - previous_filter_len = previous_filter?(int)strlen(previous_filter):0; - filter_out_filter_len = (int)strlen(follow_filter) + previous_filter_len + 16; - follow_info->filter_out_filter = (gchar *)g_malloc(filter_out_filter_len); - - /* append the negation */ - if(previous_filter_len) { - g_snprintf(follow_info->filter_out_filter, filter_out_filter_len, - "%s and !(%s)", previous_filter, follow_filter); - } else { - g_snprintf(follow_info->filter_out_filter, filter_out_filter_len, - "!(%s)", follow_filter); - } - - /* data will be passed via tap callback*/ - msg = register_tap_listener("udp_follow", follow_info, follow_filter, - 0, NULL, udp_queue_packet_data, NULL); - if (msg) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "Can't register udp_follow tap: %s\n", - msg->str); - g_free(follow_info->filter_out_filter); - g_free(follow_info); - g_free(follow_filter); - return; - } - - gtk_entry_set_text(GTK_ENTRY(filter_te), follow_filter); - - /* Run the display filter so it goes in effect - even if it's the - same as the previous display filter. */ - main_filter_packets(&cfile, follow_filter, TRUE); - - /* Free the filter string, as we're done with it. */ - g_free(follow_filter); - - remove_tap_listener(follow_info); - - /* Stream to show */ - follow_stats(&stats); - - if (stats.is_ipv6) { - hostname0 = get_hostname6(&stats.ip_address[0].ipv6); - hostname1 = get_hostname6(&stats.ip_address[1].ipv6); - } else { - hostname0 = get_hostname(stats.ip_address[0].ipv4); - hostname1 = get_hostname(stats.ip_address[1].ipv4); - } - - port0 = udp_port_to_display(NULL, stats.port[0]); - port1 = udp_port_to_display(NULL, stats.port[1]); - - follow_info->is_ipv6 = stats.is_ipv6; - - /* Both Stream Directions */ - both_directions_string = g_strdup_printf("Entire conversation (%u bytes)", follow_info->bytes_written[0] + follow_info->bytes_written[1]); - - if ((follow_info->client_port == stats.port[0]) && - ((stats.is_ipv6 && (memcmp(follow_info->client_ip.data, &stats.ip_address[0], 16) == 0)) || - (!stats.is_ipv6 && (memcmp(follow_info->client_ip.data, &stats.ip_address[0], 4) == 0)))) { - server_to_client_string = - g_strdup_printf("%s:%s " UTF8_RIGHTWARDS_ARROW " %s:%s (%u bytes)", - hostname0, port0, - hostname1, port1, - follow_info->bytes_written[0]); - - client_to_server_string = - g_strdup_printf("%s:%s " UTF8_RIGHTWARDS_ARROW " %s:%s (%u bytes)", - hostname1, port1, - hostname0, port0, - follow_info->bytes_written[1]); - } else { - server_to_client_string = - g_strdup_printf("%s:%s " UTF8_RIGHTWARDS_ARROW " %s:%s (%u bytes)", - hostname1, port1, - hostname0, port0, - follow_info->bytes_written[0]); - - client_to_server_string = - g_strdup_printf("%s:%s " UTF8_RIGHTWARDS_ARROW " %s:%s (%u bytes)", - hostname0, port0, - hostname1, port1, - follow_info->bytes_written[1]); - } - - follow_stream("Follow UDP Stream", follow_info, both_directions_string, - server_to_client_string, client_to_server_string); - - wmem_free(NULL, port0); - wmem_free(NULL, port1); - g_free(both_directions_string); - g_free(server_to_client_string); - g_free(client_to_server_string); -} - -#define FLT_BUF_SIZE 1024 - -/* - * XXX - the routine pointed to by "print_line_fcn_p" doesn't get handed lines, - * it gets handed bufferfuls. That's fine for "follow_write_raw()" - * and "follow_add_to_gtk_text()", but, as "follow_print_text()" calls - * the "print_line()" routine from "print.c", and as that routine might - * genuinely expect to be handed a line (if, for example, it's using - * some OS or desktop environment's printing API, and that API expects - * to be handed lines), "follow_print_text()" should probably accumulate - * lines in a buffer and hand them "print_line()". (If there's a - * complete line in a buffer - i.e., there's nothing of the line in - * the previous buffer or the next buffer - it can just hand that to - * "print_line()" after filtering out non-printables, as an - * optimization.) - * - * This might or might not be the reason why C arrays display - * correctly but get extra blank lines very other line when printed. - */ -static frs_return_t -follow_read_udp_stream(follow_info_t *follow_info, - follow_print_line_func follow_print, - void *arg) -{ - guint32 global_client_pos = 0, global_server_pos = 0; - guint32 server_packet_count = 0; - guint32 client_packet_count = 0; - guint32 *global_pos; - gboolean skip; - GList* cur; - frs_return_t frs_return; - follow_record_t *follow_record; - char *buffer; - - - for (cur = follow_info->payload; cur; cur = g_list_next(cur)) { - follow_record = (follow_record_t *)cur->data; - skip = FALSE; - if (!follow_record->is_server) { - global_pos = &global_client_pos; - if(follow_info->show_stream == FROM_SERVER) { - skip = TRUE; - } - } else { - global_pos = &global_server_pos; - if (follow_info->show_stream == FROM_CLIENT) { - skip = TRUE; - } - } - - if (!skip) { - buffer = (char *)g_memdup(follow_record->data->data, - follow_record->data->len); - - frs_return = follow_show(follow_info, follow_print, - buffer, - follow_record->data->len, - follow_record->is_server, arg, - global_pos, - &server_packet_count, - &client_packet_count); - g_free(buffer); - if(frs_return == FRS_PRINT_ERROR) - return frs_return; - } - } - - return FRS_OK; -} - -/* - * 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: - */ diff --git a/ui/gtk/follow_udp.h b/ui/gtk/follow_udp.h deleted file mode 100644 index b85b4f823f..0000000000 --- a/ui/gtk/follow_udp.h +++ /dev/null @@ -1,45 +0,0 @@ -/* follow_udp.h - * UDP specific routines for following traffic streams - * - * 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_UDP_H__ -#define __FOLLOW_UDP_H__ - -/* 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). */ -void follow_udp_stream_cb(GtkWidget * w, gpointer data _U_); - -#endif /* __FOLLOW_UDP_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: - */ - diff --git a/ui/gtk/font_utils.c b/ui/gtk/font_utils.c index 4fb41dacf1..a58138c99c 100644 --- a/ui/gtk/font_utils.c +++ b/ui/gtk/font_utils.c @@ -42,7 +42,7 @@ #include "ui/gtk/gtkglobals.h" #include "ui/gtk/font_utils.h" #include "ui/gtk/packet_panes.h" -#include "ui/gtk/follow_tcp.h" +#include "ui/gtk/follow_stream.h" #include "ui/gtk/packet_list.h" @@ -235,7 +235,7 @@ user_font_apply(void) { redraw_packet_bytes_all(); /* Redraw the "Follow TCP Stream" windows. */ - follow_tcp_redraw_all(); + follow_stream_redraw_all(); /* We're no longer using the old fonts; unreference them. */ if (old_r_font != NULL) diff --git a/ui/gtk/main.c b/ui/gtk/main.c index 25001d813c..6e92da071c 100644 --- a/ui/gtk/main.c +++ b/ui/gtk/main.c @@ -172,7 +172,6 @@ #include "ui/gtk/packet_win.h" #include "ui/gtk/stock_icons.h" #include "ui/gtk/find_dlg.h" -#include "ui/gtk/follow_tcp.h" #include "ui/gtk/font_utils.h" #include "ui/gtk/about_dlg.h" #include "ui/gtk/help_dlg.h" diff --git a/ui/gtk/main_menubar.c b/ui/gtk/main_menubar.c index c31cb335ac..76bafd1d8f 100644 --- a/ui/gtk/main_menubar.c +++ b/ui/gtk/main_menubar.c @@ -65,10 +65,7 @@ #include "ui/gtk/summary_dlg.h" #include "ui/gtk/prefs_dlg.h" #include "ui/gtk/packet_win.h" -#include "ui/gtk/follow_http.h" -#include "ui/gtk/follow_tcp.h" -#include "ui/gtk/follow_udp.h" -#include "ui/gtk/follow_ssl.h" +#include "ui/gtk/follow_stream.h" #include "ui/gtk/decode_as_dlg.h" #include "ui/gtk/help_dlg.h" #include "ui/gtk/supported_protos_dlg.h" diff --git a/ui/gtk/prefs_font_color.c b/ui/gtk/prefs_font_color.c index a2486eeea1..c77fb1571d 100644 --- a/ui/gtk/prefs_font_color.c +++ b/ui/gtk/prefs_font_color.c @@ -35,7 +35,7 @@ #include "ui/gtk/old-gtk-compat.h" #include "color_utils.h" -#include "follow_tcp.h" +#include "follow_stream.h" #include "font_utils.h" #include "packet_panes.h" #include "prefs_font_color.h" @@ -528,7 +528,7 @@ font_color_prefs_apply(GtkWidget *w _U_, gboolean redissect) redraw_packet_bytes_all(); } - follow_tcp_redraw_all(); + follow_stream_redraw_all(); } |