diff options
author | Michael Mann <mmann78@netscape.net> | 2013-01-30 20:36:47 +0000 |
---|---|---|
committer | Michael Mann <mmann78@netscape.net> | 2013-01-30 20:36:47 +0000 |
commit | 7f3064e6aec5d8a1523ac43c5182c361317588a6 (patch) | |
tree | d32c61cb98011dceba80d7a6f86b3f7e63b176d3 /ui | |
parent | 9296fcc310c3d179e02c11e1f3a3927791cf300d (diff) | |
download | wireshark-7f3064e6aec5d8a1523ac43c5182c361317588a6.tar.gz |
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')
-rw-r--r-- | ui/cli/tap-follow.c | 135 |
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); } |