summaryrefslogtreecommitdiff
path: root/epan/dissectors/packet-icmp.c
diff options
context:
space:
mode:
authorSake Blok <sake@euronet.nl>2011-07-14 21:27:17 +0000
committerSake Blok <sake@euronet.nl>2011-07-14 21:27:17 +0000
commit43116e9a0b571863e1bca841bd840cb216cda216 (patch)
treeb92801f95049530b15061c2f1c9a7327a201a659 /epan/dissectors/packet-icmp.c
parentef1e70dfd7dea918210841accf9de7ee9d47bae4 (diff)
downloadwireshark-43116e9a0b571863e1bca841bd840cb216cda216.tar.gz
If the first 8 bytes of the icmp echo/echo-reply data look like a timestamp, dissect it as a timestmap and calculate the time since the icmp packet was created.
svn path=/trunk/; revision=38028
Diffstat (limited to 'epan/dissectors/packet-icmp.c')
-rw-r--r--epan/dissectors/packet-icmp.c71
1 files changed, 50 insertions, 21 deletions
diff --git a/epan/dissectors/packet-icmp.c b/epan/dissectors/packet-icmp.c
index d92bc12384..0e8afc4654 100644
--- a/epan/dissectors/packet-icmp.c
+++ b/epan/dissectors/packet-icmp.c
@@ -33,6 +33,7 @@
#endif
#include <glib.h>
+#include <time.h>
#include <epan/packet.h>
#include <epan/ipproto.h>
@@ -51,6 +52,8 @@ static int icmp_tap = -1;
static int hf_icmp_resp_in = -1;
static int hf_icmp_resp_to = -1;
static int hf_icmp_resptime = -1;
+static int hf_icmp_data_time = -1;
+static int hf_icmp_data_time_relative = -1;
typedef struct _icmp_conv_info_t {
emem_tree_t *pdus;
@@ -827,6 +830,7 @@ dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_item *item;
guint32 conv_key[2];
icmp_transaction_t *trans = NULL;
+ nstime_t ts,time_relative;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ICMP");
col_clear(pinfo->cinfo, COL_INFO);
@@ -1009,29 +1013,46 @@ dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
break;
case ICMP_ECHOREPLY:
- if ( !pinfo->in_error_pkt ) {
- conv_key[0] = (guint32)tvb_get_ntohs(tvb, 2);
- conv_key[1] = (guint32)((tvb_get_ntohs(tvb, 4) << 16) |
- tvb_get_ntohs(tvb, 6));
- trans = transaction_end(pinfo, icmp_tree, conv_key);
+ case ICMP_ECHO:
+ if ( icmp_type == ICMP_ECHOREPLY ) {
+ if ( !pinfo->in_error_pkt ) {
+ conv_key[0] = (guint32)tvb_get_ntohs(tvb, 2);
+ conv_key[1] = (guint32)((tvb_get_ntohs(tvb, 4) << 16) |
+ tvb_get_ntohs(tvb, 6));
+ trans = transaction_end(pinfo, icmp_tree, conv_key);
+ }
+ } else {
+ if ( !pinfo->in_error_pkt ) {
+ guint16 tmp[2];
+
+ tmp[0] = ~tvb_get_ntohs(tvb, 2);
+ tmp[1] = ~0x0800; /* The difference between echo request & reply */
+ conv_key[0] = ip_checksum((guint8 *)&tmp, sizeof(tmp));
+ conv_key[1] = (guint32)((tvb_get_ntohs(tvb, 4) << 16) |
+ tvb_get_ntohs(tvb, 6));
+ trans = transaction_start(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];
-
- tmp[0] = ~tvb_get_ntohs(tvb, 2);
- tmp[1] = ~0x0800; /* The difference between echo request & reply */
- conv_key[0] = ip_checksum((guint8 *)&tmp, sizeof(tmp));
- conv_key[1] = (guint32)((tvb_get_ntohs(tvb, 4) << 16) |
- tvb_get_ntohs(tvb, 6));
- trans = transaction_start(pinfo, icmp_tree, conv_key);
+ /* Interpret the first 8 bytes of the icmp data as a timestamp
+ * But only if it does look like it's a timestamp.
+ */
+ ts.secs = tvb_get_ntohl(tvb,8);
+ ts.nsecs = tvb_get_ntohl(tvb,8+4); /* Leave at microsec resolution for now */
+ if (abs(ts.secs - pinfo->fd->abs_ts.secs)<3600*24 &&
+ ts.nsecs < 1000000) {
+ ts.nsecs *= 1000; /* Convert to nanosec resolution */
+ proto_tree_add_time(icmp_tree, hf_icmp_data_time, tvb, 8, 8, &ts);
+ nstime_delta(&time_relative, &pinfo->fd->abs_ts, &ts);
+ ti = proto_tree_add_time(icmp_tree, hf_icmp_data_time_relative, tvb,
+ 8, 8, &time_relative);
+ PROTO_ITEM_SET_GENERATED(ti);
+ call_dissector(data_handle, tvb_new_subset_remaining(tvb, 8+8), pinfo,
+ icmp_tree);
+ } else {
+ call_dissector(data_handle, tvb_new_subset_remaining(tvb, 8), pinfo,
+ icmp_tree);
}
- call_dissector(data_handle, tvb_new_subset_remaining(tvb, 8), pinfo,
- icmp_tree);
break;
case ICMP_RTRADVERT:
@@ -1248,7 +1269,15 @@ proto_register_icmp(void)
{ &hf_icmp_resptime,
{ "Response Time", "icmp.resptime", FT_DOUBLE, BASE_NONE, NULL, 0x0,
- "The time between the request and the response, in ms.", HFILL }}
+ "The time between the request and the response, in ms.", HFILL }},
+
+ { &hf_icmp_data_time,
+ { "Timestamp from icmp data", "icmp.data_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
+ "The timestamp in the first 8 btyes of the icmp data", HFILL }},
+
+ { &hf_icmp_data_time_relative,
+ { "Time since icmp packet was created", "icmp.data_time_relative", FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
+ " The timestamp of the packet, relative to the timestamp in the first 8 btyes of the icmp data", HFILL }}
};
static gint *ett[] = {