diff options
author | Michael Mann <mmann78@netscape.net> | 2016-01-02 08:58:08 -0500 |
---|---|---|
committer | Michael Mann <mmann78@netscape.net> | 2016-01-03 13:36:18 +0000 |
commit | 1fed5fef9a455171323e08f46f2dd8c1b834df79 (patch) | |
tree | 14f04a9c27e1362385e11fff70f3cc5b90137611 /ui/qt | |
parent | ca736cc7b49650764340bf420f834ddbd92da60b (diff) |
Add HTTP Follow stream
This automatically detects and decompresses HTTP along a TCP stream through the use of taps.
Bug: 3528
Change-Id: I8ab832d509700d0da8eabf3c3e514d8511c598d3
Reviewed-on: https://code.wireshark.org/review/13009
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'ui/qt')
-rw-r--r-- | ui/qt/follow_stream_dialog.cpp | 125 | ||||
-rw-r--r-- | ui/qt/follow_stream_dialog.h | 5 | ||||
-rw-r--r-- | ui/qt/main_window.h | 1 | ||||
-rw-r--r-- | ui/qt/main_window.ui | 9 | ||||
-rw-r--r-- | ui/qt/main_window_slots.cpp | 9 | ||||
-rw-r--r-- | ui/qt/packet_list.cpp | 1 | ||||
-rw-r--r-- | ui/qt/proto_tree.cpp | 1 |
7 files changed, 141 insertions, 10 deletions
diff --git a/ui/qt/follow_stream_dialog.cpp b/ui/qt/follow_stream_dialog.cpp index cf020ad00e..dec1a0576e 100644 --- a/ui/qt/follow_stream_dialog.cpp +++ b/ui/qt/follow_stream_dialog.cpp @@ -252,9 +252,9 @@ void FollowStreamDialog::filterOut() close(); } -void FollowStreamDialog::on_cbDirections_currentIndexChanged(int index) +void FollowStreamDialog::on_cbDirections_currentIndexChanged(int idx) { - switch(index) + switch(idx) { case 0 : follow_info_.show_stream = BOTH_HOSTS; @@ -272,10 +272,10 @@ void FollowStreamDialog::on_cbDirections_currentIndexChanged(int index) readStream(); } -void FollowStreamDialog::on_cbCharset_currentIndexChanged(int index) +void FollowStreamDialog::on_cbCharset_currentIndexChanged(int idx) { - if (index < 0) return; - follow_info_.show_type = static_cast<show_type_t>(ui->cbCharset->itemData(index).toInt()); + if (idx < 0) return; + follow_info_.show_type = static_cast<show_type_t>(ui->cbCharset->itemData(idx).toInt()); readStream(); } @@ -361,6 +361,10 @@ FollowStreamDialog::readStream() ret = readSslStream(); break; + case FOLLOW_HTTP : + ret = readHttpStream(); + break; + default : g_assert_not_reached(); ret = (frs_return_t)0; @@ -465,6 +469,39 @@ ssl_queue_packet_data(void *tapdata, packet_info *pinfo, epan_dissect_t *, const return FALSE; } +//Copy from ui/gtk/follow_http.c +static gboolean +http_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)); + + 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; +} + /* * 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()" @@ -519,6 +556,52 @@ 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() { @@ -856,7 +939,7 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index) follow_stats_t stats; tcp_stream_chunk sc; size_t nchars; - gboolean is_tcp = FALSE, is_udp = FALSE; + gboolean is_tcp = FALSE, is_udp = FALSE, is_http = FALSE; resetStream(); @@ -873,6 +956,7 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index) } proto_get_frame_protocols(cap_file_.capFile()->edt->pi.layers, NULL, &is_tcp, &is_udp, NULL, NULL, NULL, NULL); + is_http = proto_is_frame_protocol(cap_file_.capFile()->edt->pi.layers, "http"); switch (follow_type_) { @@ -897,6 +981,12 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index) return false; } break; + case FOLLOW_HTTP: + if (!is_http) { + QMessageBox::warning(this, tr("Error following stream."), tr("Please make sure you have a HTTP packet selected.")); + return false; + } + break; } if (follow_type_ == FOLLOW_TCP || follow_type_ == FOLLOW_SSL) @@ -912,7 +1002,11 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index) follow_filter = gchar_free_to_qstring( build_follow_index_filter((follow_type_ == FOLLOW_TCP) ? TCP_STREAM : UDP_STREAM)); } else { - follow_filter = gchar_free_to_qstring(build_follow_conv_filter(&cap_file_.capFile()->edt->pi)); + if (follow_type_ == FOLLOW_HTTP) { + follow_filter = gchar_free_to_qstring(build_follow_conv_filter(&cap_file_.capFile()->edt->pi, "http")); + } else { + follow_filter = gchar_free_to_qstring(build_follow_conv_filter(&cap_file_.capFile()->edt->pi, NULL)); + } } if (follow_filter.isEmpty()) { QMessageBox::warning(this, @@ -1006,6 +1100,14 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index) return false; } break; + case FOLLOW_HTTP: + /* data will be passed via tap callback*/ + if (!registerTapListener("http_follow", &follow_info_, + follow_filter.toUtf8().constData(), + 0, NULL, http_queue_packet_data, NULL)) { + return false; + } + break; } beginRetapPackets(); @@ -1022,6 +1124,7 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index) break; case FOLLOW_UDP: case FOLLOW_SSL: + case FOLLOW_HTTP: removeTapListeners(); break; } @@ -1097,6 +1200,7 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index) switch (follow_type_) { case FOLLOW_TCP: + case FOLLOW_HTTP: port0 = tcp_port_to_display(NULL, stats.port[0]); port1 = tcp_port_to_display(NULL, stats.port[1]); break; @@ -1231,6 +1335,13 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index) format_size_unit_bytes|format_size_prefix_si))); setWindowSubtitle(tr("Follow SSL Stream (%1)").arg(follow_filter)); break; + case FOLLOW_HTTP: + both_directions_string = QString("Entire conversation (%1)") + .arg(gchar_free_to_qstring(format_size( + stats.bytes_written[0] + stats.bytes_written[1], + format_size_unit_bytes|format_size_prefix_si))); + setWindowSubtitle(tr("Follow HTTP Stream (%1)").arg(follow_filter)); + break; } ui->cbDirections->clear(); diff --git a/ui/qt/follow_stream_dialog.h b/ui/qt/follow_stream_dialog.h index 86041e7192..2d82a83ea7 100644 --- a/ui/qt/follow_stream_dialog.h +++ b/ui/qt/follow_stream_dialog.h @@ -79,8 +79,8 @@ protected: void keyPressEvent(QKeyEvent *event); private slots: - void on_cbCharset_currentIndexChanged(int index); - void on_cbDirections_currentIndexChanged(int index); + void on_cbCharset_currentIndexChanged(int idx); + void on_cbDirections_currentIndexChanged(int idx); void on_bFind_clicked(); void on_leFind_returnPressed(); @@ -113,6 +113,7 @@ private: frs_return_t readTcpStream(); frs_return_t readUdpStream(); frs_return_t readSslStream(); + frs_return_t readHttpStream(); void followStream(); void addText(QString text, gboolean is_from_server, guint32 packet_num); diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h index f7ffcfbabe..aacbb46aa3 100644 --- a/ui/qt/main_window.h +++ b/ui/qt/main_window.h @@ -463,6 +463,7 @@ private slots: void on_actionAnalyzeFollowTCPStream_triggered(); void on_actionAnalyzeFollowUDPStream_triggered(); void on_actionAnalyzeFollowSSLStream_triggered(); + void on_actionAnalyzeFollowHTTPStream_triggered(); void statCommandExpertInfo(const char *, void *); void on_actionAnalyzeExpertInfo_triggered(); diff --git a/ui/qt/main_window.ui b/ui/qt/main_window.ui index 9c5bf183f0..4a9db3e4b0 100644 --- a/ui/qt/main_window.ui +++ b/ui/qt/main_window.ui @@ -386,6 +386,7 @@ <addaction name="actionAnalyzeFollowTCPStream"/> <addaction name="actionAnalyzeFollowUDPStream"/> <addaction name="actionAnalyzeFollowSSLStream"/> + <addaction name="actionAnalyzeFollowHTTPStream"/> </widget> <widget class="QMenu" name="menuConversationFilter"> <property name="title"> @@ -1699,6 +1700,14 @@ <string>SSL Stream</string> </property> </action> + <action name="actionAnalyzeFollowHTTPStream"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>HTTP Stream</string> + </property> + </action> <action name="actionStatisticsTcpStreamTcptrace"> <property name="text"> <string>Time Sequence (tcptrace)</string> diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp index 2cc5755626..a564ae2626 100644 --- a/ui/qt/main_window_slots.cpp +++ b/ui/qt/main_window_slots.cpp @@ -1046,7 +1046,7 @@ void MainWindow::recentActionTriggered() { void MainWindow::setMenusForSelectedPacket() { - gboolean is_ip = FALSE, is_tcp = FALSE, is_udp = FALSE, is_sctp = FALSE, is_ssl = FALSE, is_rtp = FALSE, is_lte_rlc = FALSE; + gboolean is_ip = FALSE, is_tcp = FALSE, is_udp = FALSE, is_sctp = FALSE, is_ssl = FALSE, is_rtp = FALSE, is_lte_rlc = FALSE, is_http = FALSE; /* Making the menu context-sensitive allows for easier selection of the desired item and has the added benefit, with large captures, of @@ -1100,6 +1100,7 @@ void MainWindow::setMenusForSelectedPacket() proto_get_frame_protocols(capture_file_.capFile()->edt->pi.layers, &is_ip, &is_tcp, &is_udp, &is_sctp, &is_ssl, &is_rtp, &is_lte_rlc); + is_http = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, "http"); } } @@ -1148,6 +1149,7 @@ void MainWindow::setMenusForSelectedPacket() main_ui_->actionAnalyzeFollowTCPStream->setEnabled(is_tcp); main_ui_->actionAnalyzeFollowUDPStream->setEnabled(is_udp); main_ui_->actionAnalyzeFollowSSLStream->setEnabled(is_ssl); + main_ui_->actionAnalyzeFollowHTTPStream->setEnabled(is_http); foreach (QAction *cc_action, cc_actions) { cc_action->setEnabled(frame_selected); @@ -2671,6 +2673,11 @@ void MainWindow::on_actionAnalyzeFollowSSLStream_triggered() openFollowStreamDialog(FOLLOW_SSL); } +void MainWindow::on_actionAnalyzeFollowHTTPStream_triggered() +{ + openFollowStreamDialog(FOLLOW_HTTP); +} + void MainWindow::openSCTPAllAssocsDialog() { SCTPAllAssocsDialog *sctp_dialog = new SCTPAllAssocsDialog(this, capture_file_.capFile()); diff --git a/ui/qt/packet_list.cpp b/ui/qt/packet_list.cpp index 0f5d57d694..11d7e2e585 100644 --- a/ui/qt/packet_list.cpp +++ b/ui/qt/packet_list.cpp @@ -326,6 +326,7 @@ PacketList::PacketList(QWidget *parent) : submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowTCPStream")); submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowUDPStream")); submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowSSLStream")); + submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowHTTPStream")); ctx_menu_.addSeparator(); diff --git a/ui/qt/proto_tree.cpp b/ui/qt/proto_tree.cpp index 577cf1f8c9..a4fcd3458e 100644 --- a/ui/qt/proto_tree.cpp +++ b/ui/qt/proto_tree.cpp @@ -209,6 +209,7 @@ ProtoTree::ProtoTree(QWidget *parent) : submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowTCPStream")); submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowUDPStream")); submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowSSLStream")); + submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowHTTPStream")); ctx_menu_.addSeparator(); main_menu_item = window()->findChild<QMenu *>("menuEditCopy"); |