aboutsummaryrefslogtreecommitdiffstats
path: root/ui/cli
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2013-01-30 20:36:47 +0000
committerMichael Mann <mmann78@netscape.net>2013-01-30 20:36:47 +0000
commit7f3064e6aec5d8a1523ac43c5182c361317588a6 (patch)
treed32c61cb98011dceba80d7a6f86b3f7e63b176d3 /ui/cli
parent9296fcc310c3d179e02c11e1f3a3927791cf300d (diff)
Add support in TShark to follow SSL streams
From QA Cafe, bug 8280 (https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8280) svn path=/trunk/; revision=47372
Diffstat (limited to 'ui/cli')
-rw-r--r--ui/cli/tap-follow.c135
1 files changed, 130 insertions, 5 deletions
diff --git a/ui/cli/tap-follow.c b/ui/cli/tap-follow.c
index d3ac497e04..30a4c06935 100644
--- a/ui/cli/tap-follow.c
+++ b/ui/cli/tap-follow.c
@@ -1,6 +1,6 @@
/* tap-follow.c
*
- * Copyright 2011, QA Cafe <info@qacafe.com>
+ * Copyright 2011-2013, QA Cafe <info@qacafe.com>
*
* $Id$
*
@@ -47,12 +47,19 @@
#include "wsutil/file_util.h"
#include "tempfile.h"
+#ifdef SSL_PLUGIN
+#include "packet-ssl-utils.h"
+#else
+#include <epan/dissectors/packet-ssl-utils.h>
+#endif
+
WS_VAR_IMPORT FILE *data_out_file;
typedef enum
{
type_TCP,
- type_UDP
+ type_UDP,
+ type_SSL
} type_e;
typedef enum
@@ -85,6 +92,7 @@ typedef struct
#define STR_FOLLOW "follow,"
#define STR_FOLLOW_TCP STR_FOLLOW "tcp"
#define STR_FOLLOW_UDP STR_FOLLOW "udp"
+#define STR_FOLLOW_SSL STR_FOLLOW "ssl"
#define STR_HEX ",hex"
#define STR_ASCII ",ascii"
@@ -108,6 +116,7 @@ followStrType(
{
case type_TCP: return "tcp";
case type_UDP: return "udp";
+ case type_SSL: return "ssl";
}
g_assert_not_reached();
@@ -148,6 +157,7 @@ followStrFilter(
switch (fp->type)
{
case type_TCP:
+ case type_SSL:
len = g_snprintf(filter, sizeof filter,
"tcp.stream eq %d", fp->index);
break;
@@ -187,6 +197,8 @@ followStrFilter(
verp, ip1, fp->port[1],
verp, ip0, fp->port[0]);
break;
+ case type_SSL:
+ break;
}
}
@@ -297,7 +309,7 @@ followFree(
}
static int
-followPacket(
+followUdpPacket(
void * contextp,
packet_info * pip,
epan_dissect_t * edp _U_,
@@ -331,6 +343,75 @@ followPacket(
return 0;
}
+static int
+followSslPacket(
+ void * contextp,
+ packet_info * pip,
+ epan_dissect_t * edp _U_,
+ const void * datap
+ )
+{
+ follow_t * fp = contextp;
+ SslPacketInfo * spip = p_get_proto_data(pip->fd, (size_t)datap);
+ SslDataInfo * sdip;
+ gint length;
+ tcp_stream_chunk sc;
+ size_t size;
+
+ if (spip == NULL)
+ {
+ return 0;
+ }
+
+ if (fp->addr[0].type == AT_NONE)
+ {
+ memcpy(fp->addrBuf[0], pip->net_src.data, pip->net_src.len);
+ SET_ADDRESS(&fp->addr[0], pip->net_src.type, pip->net_src.len,
+ fp->addrBuf[0]);
+ fp->port[0] = pip->srcport;
+
+ memcpy(fp->addrBuf[1], pip->net_dst.data, pip->net_dst.len);
+ SET_ADDRESS(&fp->addr[1], pip->net_dst.type, pip->net_dst.len,
+ fp->addrBuf[1]);
+ fp->port[1] = pip->destport;
+ }
+
+ /* total length */
+ for (length = 0, sdip = spip->appl_data; sdip != NULL; sdip = sdip->next)
+ {
+ length += sdip->plain_data.data_len;
+ }
+
+
+ if (length > 0)
+ {
+ memcpy(sc.src_addr, pip->net_src.data, pip->net_src.len);
+ sc.src_port = pip->srcport;
+ sc.dlen = length;
+
+ size = fwrite(&sc, 1, sizeof sc, fp->filep);
+ if (sizeof sc != size)
+ {
+ followExit("Error writing stream chunk header.");
+ }
+
+ for (sdip = spip->appl_data; sdip != NULL; sdip = sdip->next)
+ {
+ if (sdip->plain_data.data_len > 0)
+ {
+ size = fwrite(sdip->plain_data.data, 1, sdip->plain_data.data_len,
+ fp->filep);
+ if (sdip->plain_data.data_len != size)
+ {
+ followExit("Error writing stream chunk data.");
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
#define BYTES_PER_LINE 16
#define OFFSET_START 0
#define OFFSET_LEN 8
@@ -430,12 +511,20 @@ followDraw(
if (fp->type == type_TCP)
{
+ static const guint8 ip_zero[MAX_IPADDR_LEN] = {0};
follow_stats_t stats;
address_type type;
follow_stats(&stats);
- if (stats.is_ipv6)
+ if (stats.port[0] == 0 && stats.port[1] == 0 &&
+ memcmp(stats.ip_address[0], ip_zero, sizeof ip_zero) == 0 &&
+ memcmp(stats.ip_address[1], ip_zero, sizeof ip_zero) == 0)
+ {
+ type = AT_NONE;
+ len = 0;
+ }
+ else if (stats.is_ipv6)
{
type = AT_IPv6;
len = 16;
@@ -848,7 +937,7 @@ followUdp(
followFileOpen(fp);
errp = register_tap_listener("udp_follow", fp, followStrFilter(fp), 0,
- NULL, followPacket, followDraw);
+ NULL, followUdpPacket, followDraw);
if (errp != NULL)
{
followFree(fp);
@@ -857,9 +946,45 @@ followUdp(
}
}
+static void
+followSsl(
+ const char * optarg,
+ void * userdata _U_
+ )
+{
+ follow_t * fp;
+ GString * errp;
+
+ optarg += strlen(STR_FOLLOW_SSL);
+
+ fp = followAlloc(type_SSL);
+
+ followArgMode(&optarg, fp);
+ followArgFilter(&optarg, fp);
+ followArgRange(&optarg, fp);
+ followArgDone(optarg);
+
+ if (fp->index == G_MAXUINT32)
+ {
+ followExit("SSL only supports index filters.");
+ }
+
+ followFileOpen(fp);
+
+ errp = register_tap_listener("ssl", fp, followStrFilter(fp), 0,
+ NULL, followSslPacket, followDraw);
+ if (errp != NULL)
+ {
+ followFree(fp);
+ g_string_free(errp, TRUE);
+ followExit("Error registering ssl tap listner.");
+ }
+}
+
void
register_tap_listener_follow(void)
{
register_stat_cmd_arg(STR_FOLLOW_TCP, followTcp, NULL);
register_stat_cmd_arg(STR_FOLLOW_UDP, followUdp, NULL);
+ register_stat_cmd_arg(STR_FOLLOW_SSL, followSsl, NULL);
}