summaryrefslogtreecommitdiff
path: root/ui/qt/follow_stream_dialog.cpp
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2016-01-03 00:58:31 -0500
committerMichael Mann <mmann78@netscape.net>2016-01-06 13:35:45 +0000
commit57acc227f08fd05fb20b577568780deff77f972f (patch)
tree2edda647a9f7c0c7af8ceef3580b10520d1467c0 /ui/qt/follow_stream_dialog.cpp
parentaede5c0c412caad92ce4e4982d17f1b2b85d0e59 (diff)
downloadwireshark-57acc227f08fd05fb20b577568780deff77f972f.tar.gz
KISS the Follow TCP functionality.
[KISS - Keep It Simple, Stupid] Convert the Follow TCP functionality to use a tap from the TCP dissector that passes the tvb of the payload. This makes things A LOT simpler, but relies on the TCP dissector to make all decisions. The "tap" logic passes tvb data 1. Before calls to process_tcp_payload 2. Before hf_tcp_segment_data fields (that aren't retransmissions or otherwise handled) Follow up patches will be necessary to clean up all of the supporting "follow" functionality that is now useless. Bug: 6925 Bug: 9780 Change-Id: I4e7f5d453519be839de39a109bafa899b9987139 Reviewed-on: https://code.wireshark.org/review/13038 Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'ui/qt/follow_stream_dialog.cpp')
-rw-r--r--ui/qt/follow_stream_dialog.cpp405
1 files changed, 86 insertions, 319 deletions
diff --git a/ui/qt/follow_stream_dialog.cpp b/ui/qt/follow_stream_dialog.cpp
index 175f8c04e7..058e70ab30 100644
--- a/ui/qt/follow_stream_dialog.cpp
+++ b/ui/qt/follow_stream_dialog.cpp
@@ -360,21 +360,15 @@ FollowStreamDialog::readStream()
switch(follow_type_) {
case FOLLOW_TCP :
- ret = readTcpStream();
- break;
-
case FOLLOW_UDP :
- ret = readUdpStream();
+ case FOLLOW_HTTP :
+ ret = readFollowStream();
break;
case FOLLOW_SSL :
ret = readSslStream();
break;
- case FOLLOW_HTTP :
- ret = readHttpStream();
- break;
-
default :
g_assert_not_reached();
ret = (frs_return_t)0;
@@ -384,6 +378,40 @@ FollowStreamDialog::readStream()
return ret;
}
+//Copy from ui/gtk/follow_tcp.c
+static gboolean
+tcp_queue_packet_data(void *tapdata, packet_info *pinfo,
+ epan_dissect_t *, 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));
+ follow_record->packet_num = pinfo->fd->num;
+
+ 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;
+}
+
//Copy from ui/gtk/follow_udp.c
static gboolean
udp_queue_packet_data(void *tapdata, packet_info *pinfo,
@@ -565,52 +593,6 @@ FollowStreamDialog::readSslStream()
return FRS_OK;
}
-/* XXX - Currently the same as readUdpStream() */
-frs_return_t
-FollowStreamDialog::readHttpStream()
-{
- guint32 global_client_pos = 0, global_server_pos = 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 = showBuffer(
- buffer,
- follow_record->data->len,
- follow_record->is_server,
- follow_record->packet_num,
- global_pos);
- g_free(buffer);
- if(frs_return == FRS_PRINT_ERROR)
- return frs_return;
- }
- }
-
- return FRS_OK;
-}
-
void
FollowStreamDialog::followStream()
{
@@ -946,8 +928,6 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index)
QString client_to_server_string;
QString both_directions_string;
follow_stats_t stats;
- tcp_stream_chunk sc;
- size_t nchars;
gboolean is_tcp = FALSE, is_udp = FALSE, is_http = FALSE;
resetStream();
@@ -1006,10 +986,10 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index)
case FOLLOW_HTTP:
/* Create a new filter that matches all packets in the TCP stream,
and set the display filter entry accordingly */
- reset_tcp_reassembly();
+ reset_stream_follow(TCP_STREAM);
break;
case FOLLOW_UDP:
- reset_udp_follow();
+ reset_stream_follow(UDP_STREAM);
break;
}
@@ -1042,7 +1022,7 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index)
return false;
}
- if (follow_type_ == FOLLOW_TCP || follow_type_ == FOLLOW_SSL)
+ if (follow_type_ == FOLLOW_SSL)
{
/* Create a temporary file into which to dump the reassembled data
from the TCP stream, and set "data_out_file" to refer to it, so
@@ -1090,6 +1070,13 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index)
{
case FOLLOW_TCP:
{
+ /* data will be passed via tap callback*/
+ if (!registerTapListener("tcp_follow", &follow_info_,
+ follow_filter.toUtf8().constData(),
+ 0, NULL, tcp_queue_packet_data, NULL)) {
+ return false;
+ }
+
int stream_count = get_tcp_stream_count();
ui->streamNumberSpinBox->blockSignals(true);
ui->streamNumberSpinBox->setMaximum(stream_count-1);
@@ -1147,8 +1134,6 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index)
switch (follow_type_)
{
case FOLLOW_TCP:
-
- break;
case FOLLOW_UDP:
case FOLLOW_SSL:
case FOLLOW_HTTP:
@@ -1156,57 +1141,6 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index)
break;
}
- if (follow_type_ == FOLLOW_TCP)
- {
- /* Check whether we got any data written to the file. */
- if (empty_tcp_stream) {
- QMessageBox::warning(this, "Error",
- "The packets in the capture file for that stream have no data.");
- //ws_close(tmp_fd);
- ws_unlink(data_out_filename_.toUtf8().constData());
- data_out_filename_.clear();
- updateWidgets(false);
- endRetapPackets();
- return false;
- }
-
- /* Go back to the top of the file and read the first tcp_stream_chunk
- * to ensure that the IP addresses and port numbers in the drop-down
- * list are tied to the correct lines displayed by follow_read_stream()
- * later on (which also reads from this file). Close the file when
- * we're done.
- *
- * We read the data now, before we pop up a window, in case the
- * read fails. We use the data later.
- */
-
- rewind(data_out_file);
- nchars=fread(&sc, 1, sizeof(sc), data_out_file);
- if (nchars != sizeof(sc)) {
- if (ferror(data_out_file)) {
- QMessageBox::warning(this, "Error",
- QString(tr("Could not read from temporary file %1: %2"))
- .arg(data_out_filename_)
- .arg(g_strerror(errno)));
- } else {
- QMessageBox::warning(this, "Error",
- QString(tr("Short read from temporary file %1: expected %2, got %3"))
- .arg(data_out_filename_)
- .arg((unsigned long)sizeof(sc))
- .arg((unsigned long)nchars));
-
- }
- //ws_close(tmp_fd);
- ws_unlink(data_out_filename_.toUtf8().constData());
- data_out_filename_.clear();
- updateWidgets(false);
- endRetapPackets();
- return false;
- }
- fclose(data_out_file);
- data_out_file = NULL;
- }
-
/* Stream to show */
follow_stats(&stats);
@@ -1228,6 +1162,7 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index)
{
case FOLLOW_TCP:
case FOLLOW_HTTP:
+ case FOLLOW_SSL:
port0 = tcp_port_to_display(NULL, stats.port[0]);
port1 = tcp_port_to_display(NULL, stats.port[1]);
break;
@@ -1235,104 +1170,48 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index)
port0 = udp_port_to_display(NULL, stats.port[0]);
port1 = udp_port_to_display(NULL, stats.port[1]);
break;
- case FOLLOW_SSL:
- port0 = tcp_port_to_display(NULL, stats.port[0]);
- port1 = tcp_port_to_display(NULL, stats.port[1]);
- break;
}
follow_info_.is_ipv6 = stats.is_ipv6;
- if (follow_type_ == FOLLOW_TCP)
- {
- /* Host 0 --> Host 1 */
- if ((sc.src_port == stats.port[0]) &&
- ((stats.is_ipv6 && (memcmp(sc.src_addr, stats.ip_address[0], 16) == 0)) ||
- (!stats.is_ipv6 && (memcmp(sc.src_addr, stats.ip_address[0], 4) == 0)))) {
- server_to_client_string =
- QString("%1:%2 %3 %4:%5 (%6)")
- .arg(hostname0).arg(port0)
- .arg(UTF8_RIGHTWARDS_ARROW)
- .arg(hostname1).arg(port1)
- .arg(gchar_free_to_qstring(format_size(
- stats.bytes_written[0],
- format_size_unit_bytes|format_size_prefix_si)));
- } else {
- server_to_client_string =
- QString("%1:%2 %3 %4:%5 (%6)")
- .arg(hostname1).arg(port1)
- .arg(UTF8_RIGHTWARDS_ARROW)
- .arg(hostname0).arg(port0)
- .arg(gchar_free_to_qstring(format_size(
- stats.bytes_written[0],
- format_size_unit_bytes|format_size_prefix_si)));
- }
-
- /* Host 1 --> Host 0 */
- if ((sc.src_port == stats.port[1]) &&
- ((stats.is_ipv6 && (memcmp(sc.src_addr, stats.ip_address[1], 16) == 0)) ||
- (!stats.is_ipv6 && (memcmp(sc.src_addr, stats.ip_address[1], 4) == 0)))) {
- client_to_server_string =
- QString("%1:%2 %3 %4:%5 (%6)")
- .arg(hostname0).arg(port0)
- .arg(UTF8_RIGHTWARDS_ARROW)
- .arg(hostname1).arg(port1)
- .arg(gchar_free_to_qstring(format_size(
- stats.bytes_written[1],
- format_size_unit_bytes|format_size_prefix_si)));
- } else {
- client_to_server_string =
- QString("%1:%2 %3 %4:%5 (%6)")
- .arg(hostname1).arg(port1)
- .arg(UTF8_RIGHTWARDS_ARROW)
- .arg(hostname0).arg(port0)
- .arg(gchar_free_to_qstring(format_size(
- stats.bytes_written[1],
- format_size_unit_bytes|format_size_prefix_si)));
- }
-
- }
- else
- {
- 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 =
- QString("%1:%2 %3 %4:%5 (%6)")
- .arg(hostname0).arg(port0)
- .arg(UTF8_RIGHTWARDS_ARROW)
- .arg(hostname1).arg(port1)
- .arg(gchar_free_to_qstring(format_size(
- follow_info_.bytes_written[0],
- format_size_unit_bytes|format_size_prefix_si)));
-
- client_to_server_string =
- QString("%1:%2 %3 %4:%5 (%6)")
- .arg(hostname1).arg(port1)
- .arg(UTF8_RIGHTWARDS_ARROW)
- .arg(hostname0).arg(port0)
- .arg(gchar_free_to_qstring(format_size(
- follow_info_.bytes_written[1],
- format_size_unit_bytes|format_size_prefix_si)));
- } else {
- server_to_client_string =
- QString("%1:%2 %3 %4:%5 (%6)")
- .arg(hostname1).arg(port1)
- .arg(UTF8_RIGHTWARDS_ARROW)
- .arg(hostname0).arg(port0)
- .arg(gchar_free_to_qstring(format_size(
- follow_info_.bytes_written[0],
- format_size_unit_bytes|format_size_prefix_si)));
-
- client_to_server_string =
- QString("%1:%2 %3 %4:%5 (%6)")
- .arg(hostname0).arg(port0)
- .arg(UTF8_RIGHTWARDS_ARROW)
- .arg(hostname1).arg(port1)
- .arg(gchar_free_to_qstring(format_size(
- follow_info_.bytes_written[1],
- format_size_unit_bytes|format_size_prefix_si)));
- }
+ 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 =
+ QString("%1:%2 %3 %4:%5 (%6)")
+ .arg(hostname0).arg(port0)
+ .arg(UTF8_RIGHTWARDS_ARROW)
+ .arg(hostname1).arg(port1)
+ .arg(gchar_free_to_qstring(format_size(
+ follow_info_.bytes_written[0],
+ format_size_unit_bytes|format_size_prefix_si)));
+
+ client_to_server_string =
+ QString("%1:%2 %3 %4:%5 (%6)")
+ .arg(hostname1).arg(port1)
+ .arg(UTF8_RIGHTWARDS_ARROW)
+ .arg(hostname0).arg(port0)
+ .arg(gchar_free_to_qstring(format_size(
+ follow_info_.bytes_written[1],
+ format_size_unit_bytes|format_size_prefix_si)));
+ } else {
+ server_to_client_string =
+ QString("%1:%2 %3 %4:%5 (%6)")
+ .arg(hostname1).arg(port1)
+ .arg(UTF8_RIGHTWARDS_ARROW)
+ .arg(hostname0).arg(port0)
+ .arg(gchar_free_to_qstring(format_size(
+ follow_info_.bytes_written[0],
+ format_size_unit_bytes|format_size_prefix_si)));
+
+ client_to_server_string =
+ QString("%1:%2 %3 %4:%5 (%6)")
+ .arg(hostname0).arg(port0)
+ .arg(UTF8_RIGHTWARDS_ARROW)
+ .arg(hostname1).arg(port1)
+ .arg(gchar_free_to_qstring(format_size(
+ follow_info_.bytes_written[1],
+ format_size_unit_bytes|format_size_prefix_si)));
}
wmem_free(NULL, port0);
@@ -1417,119 +1296,7 @@ void FollowStreamDialog::captureFileClosing()
* correctly but get extra blank lines very other line when printed.
*/
frs_return_t
-FollowStreamDialog::readTcpStream()
-{
- FILE *data_out_fp;
- tcp_stream_chunk sc;
- size_t bcount;
- size_t bytes_read;
- int iplen;
- guint8 client_addr[MAX_IPADDR_LEN];
- guint16 client_port = 0;
- gboolean is_server;
- guint32 global_client_pos = 0, global_server_pos = 0;
- guint32 *global_pos;
- gboolean skip;
- char buffer[FLT_BUF_SIZE+1]; /* +1 to fix ws bug 1043 */
- size_t nchars;
- frs_return_t frs_return;
-
- iplen = (follow_info_.is_ipv6) ? 16 : 4;
-
- data_out_fp = ws_fopen(data_out_filename_.toUtf8().constData(), "rb");
- if (data_out_fp == NULL) {
- QMessageBox::critical(this, "Error",
- "Could not open temporary file %1: %2", data_out_filename_,
- g_strerror(errno));
- return FRS_OPEN_ERROR;
- }
-
- while ((nchars=fread(&sc, 1, sizeof(sc), data_out_fp))) {
- if (nchars != sizeof(sc)) {
- QMessageBox::critical(this, "Error",
- QString(tr("Short read from temporary file %1: expected %2, got %3"))
- .arg(data_out_filename_)
- .arg(sizeof(sc))
- .arg(nchars));
- fclose(data_out_fp);
- data_out_fp = NULL;
- return FRS_READ_ERROR;
- }
- if (client_port == 0) {
- memcpy(client_addr, sc.src_addr, iplen);
- client_port = sc.src_port;
- }
- skip = FALSE;
- if (memcmp(client_addr, sc.src_addr, iplen) == 0 &&
- client_port == sc.src_port) {
- is_server = FALSE;
- global_pos = &global_client_pos;
- if (follow_info_.show_stream == FROM_SERVER) {
- skip = TRUE;
- }
- } else {
- is_server = TRUE;
- global_pos = &global_server_pos;
- if (follow_info_.show_stream == FROM_CLIENT) {
- skip = TRUE;
- }
- }
-
- bytes_read = 0;
- while (bytes_read < sc.dlen) {
- bcount = ((sc.dlen-bytes_read) < FLT_BUF_SIZE) ? (sc.dlen-bytes_read) : FLT_BUF_SIZE;
- nchars = fread(buffer, 1, bcount, data_out_fp);
- if (nchars == 0)
- break;
- /* XXX - if we don't get "bcount" bytes, is that an error? */
- bytes_read += nchars;
-
- if (!skip)
- {
- frs_return = showBuffer(buffer,
- nchars, is_server, sc.packet_num, global_pos);
- if(frs_return == FRS_PRINT_ERROR) {
- fclose(data_out_fp);
- data_out_fp = NULL;
- return frs_return;
- }
-
- }
- }
- }
-
- if (ferror(data_out_fp)) {
- QMessageBox::critical(this, tr("Error reading temporary file"),
- QString("%1: %2").arg(data_out_filename_).arg(g_strerror(errno)));
- fclose(data_out_fp);
- data_out_fp = NULL;
- return FRS_READ_ERROR;
- }
-
- fclose(data_out_fp);
- data_out_fp = NULL;
- return FRS_OK;
-}
-
-/*
- * 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.
- */
-frs_return_t
-FollowStreamDialog::readUdpStream()
+FollowStreamDialog::readFollowStream()
{
guint32 global_client_pos = 0, global_server_pos = 0;
guint32 *global_pos;