Hi.
The following patch displays TCP timestamps as up times, somewhat
as p0f <http://lcamtuf.coredump.cx/p0f/p0f.shtml>
and Netcraft <http://uptime.netcraft.com/up/graph> do.
Of course, these up times are meaningless for hosts running operating
systems that apply countermeasures (like OpenBSD). They are valid for
most OSes (including Linux), though.
[ Generated with ude,
the unified-format diff-output ("unidiff") editor,
version 0.1 of 2004-10-13. ]
--- epan/dissectors/packet-tcp.c.orig-0.10.7 2004-10-20 18:34:51 -0400
+++ epan/dissectors/packet-tcp.c 2004-10-23 02:54:44 -0400
@@ -4 +4 @@
* $Id: packet-tcp.c 12259 2004-10-11 08:12:34Z sahlberg $
@@ -132,6 +132,7 @@
static gint ett_tcp_flags = -1;
static gint ett_tcp_options = -1;
static gint ett_tcp_option_sack = -1;
+static gint ett_tcp_option_timestamp = -1;
static gint ett_tcp_analysis = -1;
static gint ett_tcp_analysis_faults = -1;
static gint ett_tcp_segments = -1;
@@ -2205,18 +2206,71 @@ dissect_tcpopt_echo(const ip_tcp_opt *op
tcp_info_append_uint(pinfo, "ECHO", echo);
}
+static void
+dissect_tcpopt_timestamp_field(const proto_tree *ts_tree,
+ tvbuff_t *tvb, int offset,
+ const char *name, guint32 value)
+{
+ /* Always use correct unit symbols. We assume a 10 ms tick. */
+ /* " (up time: 497 d + 02 h + 27 min + 52.95 s)" */
+ char up[44];
+ char *s = "";
+ const char sp[] = " + ";
+ guint32 r, q;
+
+ if (value) {
+ strcpy(up, " (up time: ");
+ r = value;
+ q = r / 8640000;
+ if (q) {
+ r -= q * 8640000;
+ sprintf(up + strlen(up), "%u d", q);
+ s = sp;
+ }
+ q = r / 360000;
+ if (q) {
+ r -= q * 360000;
+ sprintf(up + strlen(up), "%s%u h", s, q);
+ s = sp;
+ }
+ q = r / 6000;
+ if (q) {
+ r -= q * 6000;
+ sprintf(up + strlen(up), "%s%u min", s, q);
+ s = sp;
+ }
+ q = r / 100;
+ r -= q * 100;
+ if (q || r)
+ sprintf(up + strlen(up), "%s%u.%02u s", s, q, r);
+ strcpy(up + strlen(up), ")");
+ } else
+ up[0] = '\0';
+
+ proto_tree_add_text(ts_tree, tvb, offset, 4,
+ "%s: %u%s", name, value, up);
+}
+
static void
dissect_tcpopt_timestamp(const ip_tcp_opt *optp, tvbuff_t *tvb,
int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
{
guint32 tsv, tser;
+ proto_item *tf;
+ proto_tree *ts_tree;
tsv = tvb_get_ntohl(tvb, offset + 2);
tser = tvb_get_ntohl(tvb, offset + 6);
proto_tree_add_boolean_hidden(opt_tree, hf_tcp_option_time_stamp, tvb,
offset, optlen, TRUE);
- proto_tree_add_text(opt_tree, tvb, offset, optlen,
+ tf = proto_tree_add_text(opt_tree, tvb, offset, optlen,
"%s: tsval %u, tsecr %u", optp->name, tsv, tser);
+ ts_tree = proto_item_add_subtree(tf, *optp->subtree_index);
+ dissect_tcpopt_timestamp_field(ts_tree, tvb, offset + 2,
+ "Timestamp Value", tsv);
+ /* XXX: TSecr invalid unless ACK; we should warn. */
+ dissect_tcpopt_timestamp_field(ts_tree, tvb, offset + 6,
+ "Timestamp Echo Reply", tser);
tcp_info_append_uint(pinfo, "TSV", tsv);
tcp_info_append_uint(pinfo, "TSER", tser);
}
@@ -2303,7 +2357,7 @@ static const ip_tcp_opt tcpopts[] = {
{
TCPOPT_TIMESTAMP,
"Time stamp",
- NULL,
+ &ett_tcp_option_timestamp,
FIXED_LENGTH,
TCPOLEN_TIMESTAMP,
dissect_tcpopt_timestamp
@@ -3223,6 +3277,7 @@ proto_register_tcp(void)
&ett_tcp_flags,
&ett_tcp_options,
&ett_tcp_option_sack,
+ &ett_tcp_option_timestamp,
&ett_tcp_analysis_faults,
&ett_tcp_analysis,
&ett_tcp_segments,