diff options
author | Chris Maynard <Christopher.Maynard@GTECH.COM> | 2011-04-05 20:21:59 +0000 |
---|---|---|
committer | Chris Maynard <Christopher.Maynard@GTECH.COM> | 2011-04-05 20:21:59 +0000 |
commit | 595e5e1c1d150812de9cc0d1549acd0ed5d8770d (patch) | |
tree | c0101435e5778ab84ef23a5809fa0332e5430fbf /epan | |
parent | 4f462b3d09e661d64714187636ddb851457c1c39 (diff) |
Add ICMP tap support, and add a tshark tap to measure such things as:
* Number of ICMP echo requests, replies, lost replies and percent loss.
* Min, Max, Average SRT (Service Response Time), and standard deviation.
(This is my first tap, so hopefully I didn't miss something, but we'll see ...)
TODO: Add a Wireshark tap.
svn path=/trunk/; revision=36480
Diffstat (limited to 'epan')
-rw-r--r-- | epan/dissectors/Makefile.common | 1 | ||||
-rw-r--r-- | epan/dissectors/packet-icmp.c | 50 | ||||
-rwxr-xr-x | epan/dissectors/packet-icmp.h | 32 | ||||
-rw-r--r-- | epan/tap.h | 5 |
4 files changed, 65 insertions, 23 deletions
diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common index 8e79a7491f..39f6df6ac2 100644 --- a/epan/dissectors/Makefile.common +++ b/epan/dissectors/Makefile.common @@ -1148,6 +1148,7 @@ DISSECTOR_INCLUDES = \ packet-http.h \ packet-i2c.h \ packet-iax2.h \ + packet-icmp.h \ packet-idmp.h \ packet-idp.h \ packet-ieee80211.h \ diff --git a/epan/dissectors/packet-icmp.c b/epan/dissectors/packet-icmp.c index 3d78455adb..d92bc12384 100644 --- a/epan/dissectors/packet-icmp.c +++ b/epan/dissectors/packet-icmp.c @@ -40,26 +40,24 @@ #include <epan/in_cksum.h> #include "packet-ip.h" +#include "packet-icmp.h" #include <epan/conversation.h> #include <epan/emem.h> +#include <epan/tap.h> + +static int icmp_tap = -1; /* Conversation related data */ static int hf_icmp_resp_in = -1; static int hf_icmp_resp_to = -1; static int hf_icmp_resptime = -1; -typedef struct _icmp_transaction_t { - guint32 rqst_frame; - guint32 resp_frame; - nstime_t rqst_time; -} icmp_transaction_t; - typedef struct _icmp_conv_info_t { emem_tree_t *pdus; } icmp_conv_info_t; -static void transaction_start(packet_info *pinfo, proto_tree *tree, guint32 *key); -static void transaction_end(packet_info *pinfo, proto_tree *tree, guint32 *key); +static icmp_transaction_t *transaction_start(packet_info *pinfo, proto_tree *tree, guint32 *key); +static icmp_transaction_t *transaction_end(packet_info *pinfo, proto_tree *tree, guint32 *key); /* Decode the end of the ICMP payload as ICMP MPLS extensions if the packet in the payload has more than 128 bytes */ @@ -705,7 +703,7 @@ dissect_mpls_extensions(tvbuff_t *tvb, gint offset, proto_tree *tree) } /* end dissect_mpls_extensions */ /* ======================================================================= */ -static void transaction_start(packet_info *pinfo, proto_tree *tree, guint32 *key) +static icmp_transaction_t *transaction_start(packet_info *pinfo, proto_tree *tree, guint32 *key) { conversation_t *conversation; icmp_conv_info_t *icmp_info; @@ -734,13 +732,14 @@ static void transaction_start(packet_info *pinfo, proto_tree *tree, guint32 *key icmp_trans->rqst_frame = PINFO_FD_NUM(pinfo); icmp_trans->resp_frame = 0; icmp_trans->rqst_time = pinfo->fd->abs_ts; + icmp_trans->resp_time = 0.0; se_tree_insert32_array(icmp_info->pdus, icmp_key, (void *)icmp_trans); } else /* Already visited this frame */ icmp_trans = se_tree_lookup32_array(icmp_info->pdus, icmp_key); if ( icmp_trans == NULL ) - return; + return (NULL); /* Print state tracking in the tree */ if ( icmp_trans->resp_frame && @@ -751,10 +750,12 @@ static void transaction_start(packet_info *pinfo, proto_tree *tree, guint32 *key PROTO_ITEM_SET_GENERATED(it); } + return (icmp_trans); + } /* transaction_start() */ /* ======================================================================= */ -static void transaction_end(packet_info *pinfo, proto_tree *tree, guint32 *key) +static icmp_transaction_t *transaction_end(packet_info *pinfo, proto_tree *tree, guint32 *key) { conversation_t *conversation; icmp_conv_info_t *icmp_info; @@ -762,16 +763,15 @@ static void transaction_end(packet_info *pinfo, proto_tree *tree, guint32 *key) emem_tree_key_t icmp_key[2]; proto_item *it; nstime_t ns; - double resptime; conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, 0, 0, 0); if ( conversation == NULL ) - return; + return (NULL); icmp_info = conversation_get_proto_data(conversation, proto_icmp); if ( icmp_info == NULL ) - return; + return (NULL); icmp_key[0].length = 2; icmp_key[0].key = key; @@ -779,12 +779,12 @@ static void transaction_end(packet_info *pinfo, proto_tree *tree, guint32 *key) icmp_key[1].key = NULL; icmp_trans = se_tree_lookup32_array(icmp_info->pdus, icmp_key); if ( icmp_trans == NULL ) - return; + return (NULL); /* Print state tracking in the tree */ if ( icmp_trans->rqst_frame && (icmp_trans->rqst_frame < PINFO_FD_NUM(pinfo)) && - ((icmp_trans->resp_frame == 0) || + ((icmp_trans->resp_frame == 0) || (icmp_trans->resp_frame == PINFO_FD_NUM(pinfo))) ) { icmp_trans->resp_frame = PINFO_FD_NUM(pinfo); @@ -793,12 +793,14 @@ static void transaction_end(packet_info *pinfo, proto_tree *tree, guint32 *key) PROTO_ITEM_SET_GENERATED(it); nstime_delta(&ns, &pinfo->fd->abs_ts, &icmp_trans->rqst_time); - resptime = 1000.0 * ns.secs + ns.nsecs/1000000.0; - it = proto_tree_add_double_format_value(tree, hf_icmp_resptime, - NULL, 0, 0, resptime, "%.3f ms", resptime); + icmp_trans->resp_time = nstime_to_msec(&ns); + it = proto_tree_add_double_format_value(tree, hf_icmp_resptime, NULL, + 0, 0, icmp_trans->resp_time, "%.3f ms", icmp_trans->resp_time); PROTO_ITEM_SET_GENERATED(it); } + return (icmp_trans); + } /* transaction_end() */ /* @@ -824,6 +826,7 @@ dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) tvbuff_t *next_tvb; proto_item *item; guint32 conv_key[2]; + icmp_transaction_t *trans = NULL; col_set_str(pinfo->cinfo, COL_PROTOCOL, "ICMP"); col_clear(pinfo->cinfo, COL_INFO); @@ -1010,11 +1013,12 @@ dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) conv_key[0] = (guint32)tvb_get_ntohs(tvb, 2); conv_key[1] = (guint32)((tvb_get_ntohs(tvb, 4) << 16) | tvb_get_ntohs(tvb, 6)); - transaction_end(pinfo, icmp_tree, conv_key); + trans = transaction_end(pinfo, icmp_tree, conv_key); } call_dissector(data_handle, tvb_new_subset_remaining(tvb, 8), pinfo, icmp_tree); break; + case ICMP_ECHO: if ( !pinfo->in_error_pkt ) { guint16 tmp[2]; @@ -1024,7 +1028,7 @@ dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) conv_key[0] = ip_checksum((guint8 *)&tmp, sizeof(tmp)); conv_key[1] = (guint32)((tvb_get_ntohs(tvb, 4) << 16) | tvb_get_ntohs(tvb, 6)); - transaction_start(pinfo, icmp_tree, conv_key); + trans = transaction_start(pinfo, icmp_tree, conv_key); } call_dissector(data_handle, tvb_new_subset_remaining(tvb, 8), pinfo, icmp_tree); @@ -1063,6 +1067,9 @@ dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) tvb_ip_to_str(tvb, 8), tvb_get_ntohl(tvb, 8)); break; } + + if (trans) + tap_queue_packet(icmp_tap, pinfo, trans); } void @@ -1269,6 +1276,7 @@ proto_register_icmp(void) &favor_icmp_mpls_ext); register_dissector("icmp", dissect_icmp, proto_icmp); + icmp_tap = register_tap("icmp"); } void diff --git a/epan/dissectors/packet-icmp.h b/epan/dissectors/packet-icmp.h new file mode 100755 index 0000000000..a8ef789f3f --- /dev/null +++ b/epan/dissectors/packet-icmp.h @@ -0,0 +1,32 @@ +/* packet-icmp.h + * Definitions for ICMP: http://tools.ietf.org/html/rfc792. + * + * $Id$ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __PACKET_ICMP_H__ +#define __PACKET_ICMP_H__ + +/* ICMP echo request/reply transaction statistics ... used by ICMP tap(s) */ +typedef struct _icmp_transaction_t { + guint32 rqst_frame; + guint32 resp_frame; + nstime_t rqst_time; + double resp_time; +} icmp_transaction_t; + +#endif diff --git a/epan/tap.h b/epan/tap.h index 94a681339f..4624a5fe92 100644 --- a/epan/tap.h +++ b/epan/tap.h @@ -34,8 +34,9 @@ typedef void (*tap_draw_cb)(void *tapdata); /* * Flags to indicate what a tap listener's packet routine requires. */ -#define TL_REQUIRES_PROTO_TREE 0x00000001 /**< full protocol tree */ -#define TL_REQUIRES_COLUMNS 0x00000002 /**< columns */ +#define TL_REQUIRES_NOTHING 0x00000000 /**< nothing */ +#define TL_REQUIRES_PROTO_TREE 0x00000001 /**< full protocol tree */ +#define TL_REQUIRES_COLUMNS 0x00000002 /**< columns */ extern void tap_init(void); extern int register_tap(const char *name); |