diff options
-rw-r--r-- | epan/dissectors/packet-tcp.c | 11 | ||||
-rw-r--r-- | epan/dissectors/packet-tcp.h | 6 | ||||
-rw-r--r-- | image/toolbar.qrc | 4 | ||||
-rw-r--r-- | ui/qt/tcp_stream_dialog.cpp | 79 | ||||
-rw-r--r-- | ui/qt/tcp_stream_dialog.h | 6 | ||||
-rw-r--r-- | ui/qt/tcp_stream_dialog.ui | 133 | ||||
-rw-r--r-- | ui/tap-tcp-stream.c | 21 | ||||
-rw-r--r-- | ui/tap-tcp-stream.h | 13 |
8 files changed, 206 insertions, 67 deletions
diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c index 5f622e3f4b..b258263bac 100644 --- a/epan/dissectors/packet-tcp.c +++ b/epan/dissectors/packet-tcp.c @@ -448,7 +448,7 @@ static dissector_table_t subdissector_table; static heur_dissector_list_t heur_subdissector_list; static dissector_handle_t data_handle; static dissector_handle_t sport_handle; -static guint32 tcp_stream_index; +static guint32 tcp_stream_count; /* TCP structs and definitions */ @@ -511,7 +511,7 @@ init_tcp_conversation_data(packet_info *pinfo) tcpd->ts_prev.nsecs=pinfo->fd->abs_ts.nsecs; tcpd->flow1.valid_bif = 1; tcpd->flow2.valid_bif = 1; - tcpd->stream = tcp_stream_index++; + tcpd->stream = tcp_stream_count++; tcpd->server_port = 0; return tcpd; @@ -595,6 +595,11 @@ add_tcp_process_info(guint32 frame_num, address *local_addr, address *remote_add flow->command = wmem_strdup(wmem_file_scope(), command); } +/* Return the current stream count */ +guint32 get_tcp_stream_count(void) +{ + return tcp_stream_count; +} /* Calculate the timestamps relative to this conversation */ static void @@ -4764,7 +4769,7 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) static void tcp_init(void) { - tcp_stream_index = 0; + tcp_stream_count = 0; reassembly_table_init(&tcp_reassembly_table, &addresses_ports_reassembly_table_functions); } diff --git a/epan/dissectors/packet-tcp.h b/epan/dissectors/packet-tcp.h index 839eec6dd7..52f84b6343 100644 --- a/epan/dissectors/packet-tcp.h +++ b/epan/dissectors/packet-tcp.h @@ -293,6 +293,12 @@ extern gboolean decode_tcp_ports(tvbuff_t *, int, packet_info *, proto_tree *, i */ extern void add_tcp_process_info(guint32 frame_num, address *local_addr, address *remote_addr, guint16 local_port, guint16 remote_port, guint32 uid, guint32 pid, gchar *username, gchar *command); +/** Get the current number of TCP streams + * + * @return The number of TCP streams + */ +WS_DLL_PUBLIC guint32 get_tcp_stream_count(void); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/image/toolbar.qrc b/image/toolbar.qrc index 3bead0b63a..dc06cf7dfb 100644 --- a/image/toolbar.qrc +++ b/image/toolbar.qrc @@ -15,8 +15,4 @@ <file>plus-8.png</file> <file>copy-8.png</file> </qresource> - <qresource prefix="/graph"> - <file>openhand-16.png</file> - <file>rubberband-16.png</file> - </qresource> </RCC> diff --git a/ui/qt/tcp_stream_dialog.cpp b/ui/qt/tcp_stream_dialog.cpp index 8a6000ea7f..904f1c8652 100644 --- a/ui/qt/tcp_stream_dialog.cpp +++ b/ui/qt/tcp_stream_dialog.cpp @@ -96,8 +96,14 @@ TCPStreamDialog::TCPStreamDialog(QWidget *parent, capture_file *cf, tcp_graph_ty ui->graphTypeComboBox->setCurrentIndex(-1); ui->graphTypeComboBox->setUpdatesEnabled(true); - ui->mouseHorizontalLayout->setContentsMargins(0, 0, 0, 0); - ui->dragToolButton->setChecked(mouse_drags_); + if (QIcon::hasThemeIcon("go-previous") && QIcon::hasThemeIcon("go-next")) { + ui->prevStreamPushButton->setText(QString()); + ui->prevStreamPushButton->setIcon(QIcon::fromTheme("go-previous")); + ui->nextStreamPushButton->setText(QString()); + ui->nextStreamPushButton->setIcon(QIcon::fromTheme("go-next")); + } + + ui->dragRadioButton->setChecked(mouse_drags_); memset (&graph_, 0, sizeof(graph_)); graph_.type = graph_type; @@ -215,6 +221,13 @@ void TCPStreamDialog::keyPressEvent(QKeyEvent *event) resetAxes(); break; + case Qt::Key_PageDown: + on_prevStreamPushButton_clicked(); + break; + case Qt::Key_PageUp: + on_nextStreamPushButton_clicked(); + break; + case Qt::Key_D: on_otherDirectionButton_clicked(); break; @@ -233,9 +246,9 @@ void TCPStreamDialog::keyPressEvent(QKeyEvent *event) break; case Qt::Key_Z: if (mouse_drags_) { - ui->selectToolButton->toggle(); + ui->selectRadioButton->toggle(); } else { - ui->dragToolButton->toggle(); + ui->dragRadioButton->toggle(); } break; @@ -317,6 +330,11 @@ void TCPStreamDialog::fillGraph() sequence_num_map_.clear(); graph_segment_list_free(&graph_); tracer_->setGraph(NULL); + + ui->streamNumberLabel->setText(QString("Stream %1").arg(graph_.stream)); + ui->prevStreamPushButton->setEnabled(graph_.stream > 0); + ui->nextStreamPushButton->setEnabled(graph_.stream < get_tcp_stream_count() - 1); + // We need at least one graph, so don't bother deleting the first one. for (int i = 0; i < sp->graphCount(); i++) { sp->graph(i)->clearData(); @@ -662,8 +680,12 @@ QRectF TCPStreamDialog::getZoomRanges(QRect zoom_rect) void TCPStreamDialog::graphClicked(QMouseEvent *event) { Q_UNUSED(event) + QCustomPlot *sp = ui->streamPlot; if (mouse_drags_) { + if (sp->axisRect()->rect().contains(event->pos())) { + sp->setCursor(QCursor(Qt::ClosedHandCursor)); + } if (tracer_->visible() && cap_file_ && packet_num_ > 0) { emit goToPacket(packet_num_); } @@ -717,6 +739,27 @@ void TCPStreamDialog::axisClicked(QCPAxis *axis, QCPAxis::SelectablePart part, Q // using a QTimer instead. void TCPStreamDialog::mouseMoved(QMouseEvent *event) { + QCustomPlot *sp = ui->streamPlot; + Qt::CursorShape shape = Qt::ArrowCursor; + if (event) { + if (event->buttons() & Qt::LeftButton == Qt::LeftButton) { + if (mouse_drags_) { + shape = Qt::ClosedHandCursor; + } else { + shape = Qt::CrossCursor; + } + } else { + if (sp->axisRect()->rect().contains(event->pos())) { + if (mouse_drags_) { + shape = Qt::OpenHandCursor; + } else { + shape = Qt::CrossCursor; + } + } + } + } + sp->setCursor(QCursor(shape)); + if (mouse_drags_) { double tr_key = tracer_->position->key(); struct segment *packet_seg = NULL; @@ -790,6 +833,8 @@ void TCPStreamDialog::mouseReleased(QMouseEvent *event) sp->replot(); } } + } else if (ui->streamPlot->cursor().shape() == Qt::ClosedHandCursor) { + ui->streamPlot->setCursor(QCursor(Qt::OpenHandCursor)); } } @@ -861,6 +906,26 @@ void TCPStreamDialog::setCaptureFile(capture_file *cf) } } +void TCPStreamDialog::on_prevStreamPushButton_clicked() +{ + if (graph_.stream > 0) { + graph_.stream--; + graph_.src_address.type = AT_NONE; + graph_.dst_address.type = AT_NONE; + fillGraph(); + } +} + +void TCPStreamDialog::on_nextStreamPushButton_clicked() +{ + if (graph_.stream < get_tcp_stream_count() - 1) { + graph_.stream++; + graph_.src_address.type = AT_NONE; + graph_.dst_address.type = AT_NONE; + fillGraph(); + } +} + void TCPStreamDialog::on_otherDirectionButton_clicked() { address tmp_addr; @@ -876,21 +941,19 @@ void TCPStreamDialog::on_otherDirectionButton_clicked() fillGraph(); } -void TCPStreamDialog::on_dragToolButton_toggled(bool checked) +void TCPStreamDialog::on_dragRadioButton_toggled(bool checked) { if (checked) mouse_drags_ = true; ui->streamPlot->setInteractions( QCP::iRangeDrag | QCP::iRangeZoom ); - ui->streamPlot->setCursor(QCursor(Qt::OpenHandCursor)); } -void TCPStreamDialog::on_selectToolButton_toggled(bool checked) +void TCPStreamDialog::on_selectRadioButton_toggled(bool checked) { if (checked) mouse_drags_ = false; ui->streamPlot->setInteractions(0); - ui->streamPlot->setCursor(QCursor(Qt::CrossCursor)); } /* diff --git a/ui/qt/tcp_stream_dialog.h b/ui/qt/tcp_stream_dialog.h index 481bb2bb20..7be1e2fc07 100644 --- a/ui/qt/tcp_stream_dialog.h +++ b/ui/qt/tcp_stream_dialog.h @@ -104,9 +104,11 @@ private slots: void on_buttonBox_accepted(); void on_graphTypeComboBox_currentIndexChanged(int index); void on_resetButton_clicked(); + void on_prevStreamPushButton_clicked(); + void on_nextStreamPushButton_clicked(); void on_otherDirectionButton_clicked(); - void on_dragToolButton_toggled(bool checked); - void on_selectToolButton_toggled(bool checked); + void on_dragRadioButton_toggled(bool checked); + void on_selectRadioButton_toggled(bool checked); }; #endif // TCP_STREAM_DIALOG_H diff --git a/ui/qt/tcp_stream_dialog.ui b/ui/qt/tcp_stream_dialog.ui index b9e139129e..d4980ece16 100644 --- a/ui/qt/tcp_stream_dialog.ui +++ b/ui/qt/tcp_stream_dialog.ui @@ -44,6 +44,8 @@ <tr><th><i>Shift+</i>←</th><td>Move left 10%</td></th> <tr><th><i>Shift+</i>↑</th><td>Move up 10%</td></th> <tr><th><i>Shift+</i>↓</th><td>Move down 10%</td></th> +<tr><th><i>Pg Up</i></th><td>Next stream</td></th> +<tr><th><i>Pg Dn</i></th><td>Previous stream</td></th> <tr><th>0</th><td>Reset graph to its initial state</td></th> <tr><th>d</th><td>Switch direction (swap TCP endpoints)</td></th> <tr><th>g</th><td>Go to packet under cursor</td></th> @@ -60,7 +62,7 @@ </widget> </item> <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> + <layout class="QHBoxLayout" name="horizontalLayout"> <item> <widget class="QLabel" name="label"> <property name="text"> @@ -85,57 +87,36 @@ </spacer> </item> <item> - <layout class="QHBoxLayout" name="mouseHorizontalLayout"> - <item> - <widget class="QToolButton" name="dragToolButton"> - <property name="toolTip"> - <string>Drag using the mouse button.</string> - </property> - <property name="icon"> - <iconset resource="../../image/toolbar.qrc"> - <normaloff>:/graph/openhand-16.png</normaloff>:/graph/openhand-16.png</iconset> - </property> - <property name="checkable"> - <bool>true</bool> - </property> - <attribute name="buttonGroup"> - <string notr="true">mouseButtonGroup</string> - </attribute> - </widget> - </item> - <item> - <widget class="QToolButton" name="selectToolButton"> - <property name="toolTip"> - <string>Select using the mouse button.</string> - </property> - <property name="icon"> - <iconset resource="../../image/toolbar.qrc"> - <normaloff>:/graph/rubberband-16.png</normaloff>:/graph/rubberband-16.png</iconset> - </property> - <property name="checkable"> - <bool>true</bool> - </property> - <attribute name="buttonGroup"> - <string notr="true">mouseButtonGroup</string> - </attribute> - </widget> - </item> - </layout> + <widget class="QPushButton" name="prevStreamPushButton"> + <property name="toolTip"> + <string><html><head/><body><p>Go to the previous TCP stream.</p></body></html></string> + </property> + <property name="text"> + <string>⇦</string> + </property> + </widget> </item> <item> - <widget class="QPushButton" name="resetButton"> + <widget class="QLabel" name="streamNumberLabel"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="nextStreamPushButton"> <property name="toolTip"> - <string><html><head/><body><p>Reset the graph to its initial state.</p></body></html></string> + <string><html><head/><body><p>Go to the next TCP stream.</p></body></html></string> </property> <property name="text"> - <string>Reset</string> + <string>⇨</string> </property> </widget> </item> <item> <widget class="QPushButton" name="otherDirectionButton"> <property name="toolTip"> - <string><html><head/><body><p>Switch the direction of the connection (swap the TCP endpoints).</p></body></html></string> + <string><html><head/><body><p>Switch the direction of the connection (view the opposite flow).</p></body></html></string> </property> <property name="text"> <string>Switch Direction</string> @@ -145,6 +126,72 @@ </layout> </item> <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="mouseLabel"> + <property name="text"> + <string>Mouse</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="dragRadioButton"> + <property name="toolTip"> + <string>Drag using the mouse button.</string> + </property> + <property name="text"> + <string>drags</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <attribute name="buttonGroup"> + <string notr="true">mouseButtonGroup</string> + </attribute> + </widget> + </item> + <item> + <widget class="QRadioButton" name="selectRadioButton"> + <property name="toolTip"> + <string>Select using the mouse button.</string> + </property> + <property name="text"> + <string>selects</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <attribute name="buttonGroup"> + <string notr="true">mouseButtonGroup</string> + </attribute> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="resetButton"> + <property name="toolTip"> + <string><html><head/><body><p>Reset the graph to its initial state.</p></body></html></string> + </property> + <property name="text"> + <string>Reset</string> + </property> + </widget> + </item> + </layout> + </item> + <item> <widget class="QDialogButtonBox" name="buttonBox"> <property name="orientation"> <enum>Qt::Horizontal</enum> @@ -169,9 +216,7 @@ <header>elided_label.h</header> </customwidget> </customwidgets> - <resources> - <include location="../../image/toolbar.qrc"/> - </resources> + <resources/> <connections> <connection> <sender>buttonBox</sender> diff --git a/ui/tap-tcp-stream.c b/ui/tap-tcp-stream.c index 621c882b09..f0ed9ed6c6 100644 --- a/ui/tap-tcp-stream.c +++ b/ui/tap-tcp-stream.c @@ -50,13 +50,25 @@ typedef struct _tcp_scan_t { } tcp_scan_t; -static int +static gboolean tapall_tcpip_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, const void *vip) { tcp_scan_t *ts = (tcp_scan_t *)pct; struct tcp_graph *tg = ts->tg; const struct tcpheader *tcphdr = (const struct tcpheader *)vip; + if (tg->stream == tcphdr->th_stream + && (tg->src_address.type == AT_NONE || tg->dst_address.type == AT_NONE)) { + /* + * We only know the stream number. Fill in our connection data. + * We assume that the server response is more interesting. + */ + COPY_ADDRESS(&tg->src_address, &tcphdr->ip_dst); + tg->src_port = tcphdr->th_dport; + COPY_ADDRESS(&tg->dst_address, &tcphdr->ip_src); + tg->dst_port = tcphdr->th_sport; + } + if (compare_headers(&tg->src_address, &tg->dst_address, tg->src_port, tg->dst_port, &tcphdr->ip_src, &tcphdr->ip_dst, @@ -98,7 +110,7 @@ tapall_tcpip_packet(void *pct, packet_info *pinfo, epan_dissect_t *edt _U_, cons ts->last = segment; } - return 0; + return FALSE; } /* here we collect all the external data we will ever need */ @@ -226,7 +238,7 @@ typedef struct _th_t { struct tcpheader *tcphdrs[MAX_SUPPORTED_TCP_HEADERS]; } th_t; -static int +static gboolean tap_tcpip_packet(void *pct, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *vip) { int n; @@ -261,7 +273,7 @@ tap_tcpip_packet(void *pct, packet_info *pinfo _U_, epan_dissect_t *edt _U_, con th->num_hdrs++; } - return 0; + return FALSE; } /* XXX should be enhanced so that if we have multiple TCP layers in the trace @@ -347,7 +359,6 @@ select_tcpip_session(capture_file *cf, struct segment *hdrs) COPY_ADDRESS(&hdrs->ip_src, &th.tcphdrs[0]->ip_src); COPY_ADDRESS(&hdrs->ip_dst, &th.tcphdrs[0]->ip_dst); return th.tcphdrs[0]; - } int rtt_is_retrans(struct unack *list, unsigned int seqno) diff --git a/ui/tap-tcp-stream.h b/ui/tap-tcp-stream.h index 1aba3c842d..cbbd4fe245 100644 --- a/ui/tap-tcp-stream.h +++ b/ui/tap-tcp-stream.h @@ -77,7 +77,18 @@ struct tcp_graph { struct segment *segments; }; -void graph_segment_list_get(capture_file *, struct tcp_graph *, gboolean stream_known ); +/** Fill in the segment list for a TCP graph + * + * @param cf Capture file to scan + * @param tg TCP graph. A valid stream must be set. If either the source or + * destination address types are AT_NONE the address and port + * information will be filled in using the first packet in the + * specified stream. + * @param stream_known If FALSE, session information will be filled in using + * the currently selected packet. If FALSE, session information will + * be matched against tg. + */ +void graph_segment_list_get(capture_file *cf, struct tcp_graph *tg, gboolean stream_known ); void graph_segment_list_free(struct tcp_graph * ); /* for compare_headers() */ |