summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexis La Goutte <alexis.lagoutte@gmail.com>2012-03-20 08:51:05 +0000
committerAlexis La Goutte <alexis.lagoutte@gmail.com>2012-03-20 08:51:05 +0000
commitfa68273f40887ee75e2dbbbc67c964934e8eefae (patch)
tree1263ba9d78997ead82b19f45d0217e44a50e5606
parentb7cfa1359d4b5bd9d4bd962d97b9ca1123f96847 (diff)
downloadwireshark-fa68273f40887ee75e2dbbbc67c964934e8eefae.tar.gz
Add Quick Start IPv6 Option ( And shared Quick Start option between IPv4/IPv6/TCP )
svn path=/trunk/; revision=41681
-rw-r--r--epan/dissectors/packet-ip.c37
-rw-r--r--epan/dissectors/packet-ipv6.c84
-rw-r--r--epan/dissectors/packet-tcp.c27
-rw-r--r--epan/ip_opts.h33
4 files changed, 122 insertions, 59 deletions
diff --git a/epan/dissectors/packet-ip.c b/epan/dissectors/packet-ip.c
index a9f20d1136..a99e23cdc8 100644
--- a/epan/dissectors/packet-ip.c
+++ b/epan/dissectors/packet-ip.c
@@ -1253,40 +1253,7 @@ dissect_ipopt_ra(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
proto_tree_add_item(field_tree, hf_ip_opt_ra, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
}
-/* Quick start */
-#define QS_FUNC_MASK 0xf0
-#define QS_RATE_MASK 0x0f
-#define QS_RATE_REQUEST 0
-#define QS_RATE_REPORT 8
-
-static const value_string qs_func_vals[] = {
- {QS_RATE_REQUEST, "Rate request"},
- {QS_RATE_REPORT, "Rate report"},
- {0, NULL}
-};
-
-/* Quick-Start TCP option, as defined by RFC4782 */
-static const value_string qs_rate_vals[] = {
- { 0, "0 bit/s"},
- { 1, "80 Kbit/s"},
- { 2, "160 Kbit/s"},
- { 3, "320 Kbit/s"},
- { 4, "640 Kbit/s"},
- { 5, "1.28 Mbit/s"},
- { 6, "2.56 Mbit/s"},
- { 7, "5.12 Mbit/s"},
- { 8, "10.24 Mbit/s"},
- { 9, "20.48 Mbit/s"},
- {10, "40.96 Mbit/s"},
- {11, "81.92 Mbit/s"},
- {12, "163.84 Mbit/s"},
- {13, "327.68 Mbit/s"},
- {14, "655.36 Mbit/s"},
- {15, "1.31072 Gbit/s"},
- {0, NULL}
-};
static value_string_ext qs_rate_vals_ext = VALUE_STRING_EXT_INIT(qs_rate_vals);
-
static void
dissect_ipopt_qs(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
guint optlen, packet_info *pinfo, proto_tree *opt_tree)
@@ -2423,11 +2390,11 @@ proto_register_ip(void)
{ &hf_ip_opt_qs_nonce,
{ "QS Nonce", "ip.opt.qs_nonce", FT_UINT32, BASE_HEX,
- NULL, 0xFFFC, NULL, HFILL }},
+ NULL, 0xFFFFFFFC, NULL, HFILL }},
{ &hf_ip_opt_qs_reserved,
{ "Reserved", "ip.opt.qs_reserved", FT_UINT32, BASE_HEX,
- NULL, 0x0003, NULL, HFILL }},
+ NULL, 0x00000003, NULL, HFILL }},
{ &hf_ip_rec_rt,
{ "Recorded Route", "ip.rec_rt", FT_IPv4, BASE_NONE, NULL, 0x0,
diff --git a/epan/dissectors/packet-ipv6.c b/epan/dissectors/packet-ipv6.c
index 9c92c9df4e..182d9f1c8e 100644
--- a/epan/dissectors/packet-ipv6.c
+++ b/epan/dissectors/packet-ipv6.c
@@ -136,6 +136,13 @@ static int hf_ipv6_opt_pad1 = -1;
static int hf_ipv6_opt_padn = -1;
static int hf_ipv6_opt_rtalert = -1;
static int hf_ipv6_opt_jumbo = -1;
+static int hf_ipv6_opt_qs_func = -1;
+static int hf_ipv6_opt_qs_rate = -1;
+static int hf_ipv6_opt_qs_ttl = -1;
+static int hf_ipv6_opt_qs_ttl_diff = -1;
+static int hf_ipv6_opt_qs_unused = -1;
+static int hf_ipv6_opt_qs_nonce = -1;
+static int hf_ipv6_opt_qs_reserved = -1;
static int hf_ipv6_opt_unknown = -1;
static int hf_ipv6_dst_opt = -1;
static int hf_ipv6_hop_opt = -1;
@@ -809,6 +816,8 @@ dissect_unknown_option(tvbuff_t *tvb, int offset, proto_tree *tree)
return len;
}
+static value_string_ext qs_rate_vals_ext = VALUE_STRING_EXT_INIT(qs_rate_vals);
+
static int
dissect_opts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo, const int hf_option_item)
{
@@ -838,7 +847,7 @@ dissect_opts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo, c
/* there are more options */
/* IPv6 Option */
- ti_opt = proto_tree_add_item(dstopt_tree, hf_ipv6_opt, tvb, offset, 1, ENC_NA);
+ ti_opt = proto_tree_add_item(dstopt_tree, hf_ipv6_opt, tvb, offset, 2, ENC_NA);
opt_tree = proto_item_add_subtree(ti_opt, ett_ipv6_opt);
/* Option type */
@@ -906,6 +915,49 @@ dissect_opts(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info * pinfo, c
SET_ADDRESS(&pinfo->src, AT_IPv6, 16, tvb_get_ptr(tvb, offset, 16));
offset += opt_len;
break;
+
+ case IP6OPT_QUICKSTART:
+ {
+
+ guint8 command = tvb_get_guint8(tvb, offset);
+ guint8 function = command >> 4;
+ guint8 rate = command & QS_RATE_MASK;
+ guint8 ttl_diff;
+
+ proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_func, tvb, offset, 1, ENC_NA);
+
+ if (function == QS_RATE_REQUEST) {
+ proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_rate, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_ttl, tvb, offset, 1, ENC_NA);
+ ttl_diff = (pinfo->ip_ttl - tvb_get_guint8(tvb, offset) % 256);
+ offset += 1;
+ ti = proto_tree_add_uint_format_value(opt_tree, hf_ipv6_opt_qs_ttl_diff,
+ tvb, offset, 1, ttl_diff,
+ "%u", ttl_diff);
+ PROTO_ITEM_SET_GENERATED(ti);
+ proto_item_append_text(ti_opt, ", %s, QS TTL %u, QS TTL diff %u",
+ val_to_str_ext_const(rate, &qs_rate_vals_ext, "Unknown"),
+ tvb_get_guint8(tvb, offset), ttl_diff);
+ offset += 1;
+ proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_nonce, tvb, offset, 4, ENC_NA);
+ proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_reserved, tvb, offset, 4, ENC_NA);
+ offset += 4;
+ } else if (function == QS_RATE_REPORT) {
+ proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_rate, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_item_append_text(ti_opt, ", %s",
+ val_to_str_ext_const(rate, &qs_rate_vals_ext, "Unknown (%u)"));
+ proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_unused, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_nonce, tvb, offset, 4, ENC_NA);
+ proto_tree_add_item(opt_tree, hf_ipv6_opt_qs_reserved, tvb, offset, 4, ENC_NA);
+ offset += 4;
+ }
+
+ }
+ break;
+
default:
proto_tree_add_item(opt_tree, hf_ipv6_opt_unknown, tvb,
offset, opt_len, ENC_NA);
@@ -1595,6 +1647,8 @@ dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_tree_add_item(ipv6_tree, hf_ipv6_hlim, tvb,
offset + offsetof(struct ip6_hdr, ip6_hlim), 1, ENC_BIG_ENDIAN);
+ /* Yes, there is not TTL in IPv6 Header... but it is the same of Hop Limit...*/
+ pinfo->ip_ttl = tvb_get_guint8(tvb, offset + offsetof(struct ip6_hdr, ip6_hlim));
/* Add the different items for the source address */
proto_tree_add_item(ipv6_tree, hf_ipv6_src, tvb,
@@ -2222,6 +2276,34 @@ proto_register_ipv6(void)
{ "Jumbo", "ipv6.opt.jumbo",
FT_UINT32, BASE_DEC, NULL, 0x0,
"Length of the IPv6 packet in octets", HFILL }},
+ { &hf_ipv6_opt_qs_func,
+ { "Function", "ipv6.opt.qs_func",
+ FT_UINT8, BASE_DEC, VALS(qs_func_vals), QS_FUNC_MASK,
+ NULL, HFILL }},
+ { &hf_ipv6_opt_qs_rate,
+ { "Rate", "ipv6.opt.qs_rate",
+ FT_UINT8, BASE_DEC | BASE_EXT_STRING, &(qs_rate_vals_ext), QS_RATE_MASK,
+ NULL, HFILL }},
+ { &hf_ipv6_opt_qs_ttl,
+ { "QS TTL", "ipv6.opt.qs_ttl",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_ipv6_opt_qs_ttl_diff,
+ { "TTL Diff", "ipv6.opt.qs_ttl_diff",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_ipv6_opt_qs_unused,
+ { "Not Used", "ipv6.opt.qs_unused",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
+ { &hf_ipv6_opt_qs_nonce,
+ { "QS Nonce", "ipv6.opt.qs_nonce",
+ FT_UINT32, BASE_HEX, NULL, 0xFFFFFFFC,
+ NULL, HFILL }},
+ { &hf_ipv6_opt_qs_reserved,
+ { "Reserved", "ipv6.opt.qs_reserved",
+ FT_UINT32, BASE_HEX, NULL, 0x0003,
+ NULL, HFILL }},
{ &hf_ipv6_opt_unknown,
{ "Unknown Option Payload","ipv6.opt.unknown",
FT_BYTES, BASE_NONE, NULL, 0x0,
diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c
index 3f7c971aad..40bf01ac85 100644
--- a/epan/dissectors/packet-tcp.c
+++ b/epan/dissectors/packet-tcp.c
@@ -2818,31 +2818,12 @@ dissect_tcpopt_cc(const ip_tcp_opt *optp, tvbuff_t *tvb,
tcp_info_append_uint(pinfo, "CC", cc);
}
+static value_string_ext qs_rate_vals_ext = VALUE_STRING_EXT_INIT(qs_rate_vals);
+
static void
dissect_tcpopt_qs(const ip_tcp_opt *optp, tvbuff_t *tvb,
int offset, guint optlen, packet_info *pinfo, proto_tree *opt_tree)
{
- /* Quick-Start TCP option, as defined by RFC4782 */
- static const value_string qs_rates[] = {
- { 0, "0 bit/s"},
- { 1, "80 kbit/s"},
- { 2, "160 kbit/s"},
- { 3, "320 kbit/s"},
- { 4, "640 kbit/s"},
- { 5, "1.28 Mbit/s"},
- { 6, "2.56 Mbit/s"},
- { 7, "5.12 Mbit/s"},
- { 8, "10.24 Mbit/s"},
- { 9, "20.48 Mbit/s"},
- {10, "40.96 Mbit/s"},
- {11, "81.92 Mbit/s"},
- {12, "163.84 Mbit/s"},
- {13, "327.68 Mbit/s"},
- {14, "655.36 Mbit/s"},
- {15, "1.31072 Gbit/s"},
- {0, NULL}
- };
- static value_string_ext qs_rates_ext = VALUE_STRING_EXT_INIT(qs_rates);
proto_item *hidden_item;
@@ -2860,9 +2841,9 @@ dissect_tcpopt_qs(const ip_tcp_opt *optp, tvbuff_t *tvb,
PROTO_ITEM_SET_HIDDEN(hidden_item);
proto_tree_add_text(opt_tree, tvb, offset, optlen,
"%s: Rate response, %s, TTL diff %u ", optp->name,
- val_to_str_ext(rate, &qs_rates_ext, "Unknown"),
+ val_to_str_ext(rate, &qs_rate_vals_ext, "Unknown"),
tvb_get_guint8(tvb, offset + 3));
- col_append_fstr(pinfo->cinfo, COL_INFO, " QSresp=%s", val_to_str_ext(rate, &qs_rates_ext, "Unknown"));
+ col_append_fstr(pinfo->cinfo, COL_INFO, " QSresp=%s", val_to_str_ext(rate, &qs_rate_vals_ext, "Unknown"));
}
diff --git a/epan/ip_opts.h b/epan/ip_opts.h
index e39aced53d..7fe4a31964 100644
--- a/epan/ip_opts.h
+++ b/epan/ip_opts.h
@@ -57,4 +57,37 @@ extern void dissect_ip_tcp_options(tvbuff_t *, int, guint,
const ip_tcp_opt *, int, int,
packet_info *, proto_tree *, proto_item *);
+/* Quick-Start option, as defined by RFC4782 */
+#define QS_FUNC_MASK 0xf0
+#define QS_RATE_MASK 0x0f
+#define QS_RATE_REQUEST 0
+#define QS_RATE_REPORT 8
+
+static const value_string qs_func_vals[] = {
+ {QS_RATE_REQUEST, "Rate request"},
+ {QS_RATE_REPORT, "Rate report"},
+ {0, NULL}
+};
+
+static const value_string qs_rate_vals[] = {
+ { 0, "0 bit/s"},
+ { 1, "80 Kbit/s"},
+ { 2, "160 Kbit/s"},
+ { 3, "320 Kbit/s"},
+ { 4, "640 Kbit/s"},
+ { 5, "1.28 Mbit/s"},
+ { 6, "2.56 Mbit/s"},
+ { 7, "5.12 Mbit/s"},
+ { 8, "10.24 Mbit/s"},
+ { 9, "20.48 Mbit/s"},
+ {10, "40.96 Mbit/s"},
+ {11, "81.92 Mbit/s"},
+ {12, "163.84 Mbit/s"},
+ {13, "327.68 Mbit/s"},
+ {14, "655.36 Mbit/s"},
+ {15, "1.31072 Gbit/s"},
+ {0, NULL}
+};
+
+
#endif