summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-tcp.c11
-rw-r--r--epan/dissectors/packet-tcp.h6
-rw-r--r--image/toolbar.qrc4
-rw-r--r--ui/qt/tcp_stream_dialog.cpp79
-rw-r--r--ui/qt/tcp_stream_dialog.h6
-rw-r--r--ui/qt/tcp_stream_dialog.ui133
-rw-r--r--ui/tap-tcp-stream.c21
-rw-r--r--ui/tap-tcp-stream.h13
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 @@
&lt;tr&gt;&lt;th&gt;&lt;i&gt;Shift+&lt;/i&gt;←&lt;/th&gt;&lt;td&gt;Move left 10%&lt;/td&gt;&lt;/th&gt;
&lt;tr&gt;&lt;th&gt;&lt;i&gt;Shift+&lt;/i&gt;↑&lt;/th&gt;&lt;td&gt;Move up 10%&lt;/td&gt;&lt;/th&gt;
&lt;tr&gt;&lt;th&gt;&lt;i&gt;Shift+&lt;/i&gt;↓&lt;/th&gt;&lt;td&gt;Move down 10%&lt;/td&gt;&lt;/th&gt;
+&lt;tr&gt;&lt;th&gt;&lt;i&gt;Pg Up&lt;/i&gt;&lt;/th&gt;&lt;td&gt;Next stream&lt;/td&gt;&lt;/th&gt;
+&lt;tr&gt;&lt;th&gt;&lt;i&gt;Pg Dn&lt;/i&gt;&lt;/th&gt;&lt;td&gt;Previous stream&lt;/td&gt;&lt;/th&gt;
&lt;tr&gt;&lt;th&gt;0&lt;/th&gt;&lt;td&gt;Reset graph to its initial state&lt;/td&gt;&lt;/th&gt;
&lt;tr&gt;&lt;th&gt;d&lt;/th&gt;&lt;td&gt;Switch direction (swap TCP endpoints)&lt;/td&gt;&lt;/th&gt;
&lt;tr&gt;&lt;th&gt;g&lt;/th&gt;&lt;td&gt;Go to packet under cursor&lt;/td&gt;&lt;/th&gt;
@@ -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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Go to the previous TCP stream.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Reset the graph to its initial state.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Go to the next TCP stream.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
- <string>Reset</string>
+ <string>⇨</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="otherDirectionButton">
<property name="toolTip">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Switch the direction of the connection (swap the TCP endpoints).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Switch the direction of the connection (view the opposite flow).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Reset the graph to its initial state.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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() */