aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-dhcpv6.c
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2013-01-25 03:40:53 +0000
committerMichael Mann <mmann78@netscape.net>2013-01-25 03:40:53 +0000
commit4b3d76d426da23cb669779f17fd8adb757cbda2f (patch)
treebfacb1704792b01af19a99df79c84734d15a97f2 /epan/dissectors/packet-dhcpv6.c
parent471dde4a2192c3fbd7deba83ca2f19cf2f0d12f3 (diff)
Add new query types, options and message types for DHCPv6 Bulk Leasequery protocol. Also enforce message rules in RFC 5460 section 4 through expert_info
Part of bug 8172 (https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8172) svn path=/trunk/; revision=47267
Diffstat (limited to 'epan/dissectors/packet-dhcpv6.c')
-rw-r--r--epan/dissectors/packet-dhcpv6.c69
1 files changed, 54 insertions, 15 deletions
diff --git a/epan/dissectors/packet-dhcpv6.c b/epan/dissectors/packet-dhcpv6.c
index 20478bf362..2acc692833 100644
--- a/epan/dissectors/packet-dhcpv6.c
+++ b/epan/dissectors/packet-dhcpv6.c
@@ -219,6 +219,8 @@ static gint ett_dhcpv6_bulk_leasequery_options = -1;
#define RELAY_REPLY 13
#define LEASEQUERY 14
#define LEASEQUERY_REPLY 15
+#define LEASEQUERY_DONE 16
+#define LEASEQUERY_DATA 17
#define OPTION_CLIENTID 1
#define OPTION_SERVERID 2
@@ -268,6 +270,7 @@ static gint ett_dhcpv6_bulk_leasequery_options = -1;
#define OPTION_LQ_RELAY_DATA 47
#define OPTION_LQ_CLIENT_LINK 48
#define OPTION_CAPWAP_AC_V6 52
+#define OPTION_RELAYID 53
#define OPTION_AFTR_NAME 64
/* temporary value until defined by IETF */
@@ -296,6 +299,8 @@ static const value_string msgtype_vals[] = {
{ RELAY_REPLY, "Relay-reply" },
{ LEASEQUERY, "Leasequery" },
{ LEASEQUERY_REPLY, "Leasequery-reply" },
+ { LEASEQUERY_DONE, "Leasequery-done" },
+ { LEASEQUERY_DATA, "Leasequery-data" },
{ 0, NULL }
};
@@ -368,6 +373,7 @@ static const value_string statuscode_vals[] =
{8, "MalformedQuery" },
{9, "NotConfigured" },
{10, "NotAllowed" },
+ {11, "QueryTerminated" },
{0, NULL }
};
@@ -395,9 +401,18 @@ static const true_false_string fqdn_s = {
"Server should not perform forward DNS updates"
};
+#define LQ_QUERY_ADDRESS 1
+#define LQ_QUERY_CLIENTID 2
+#define LQ_QUERY_RELAYID 3
+#define LQ_QUERY_LINK_ADDRESS 4
+#define LQ_QUERY_REMOTEID 5
+
static const value_string lq_query_vals[] = {
- { 1, "by-address" },
- { 2, "by-clientID" },
+ { LQ_QUERY_ADDRESS, "by-address" },
+ { LQ_QUERY_CLIENTID, "by-clientID" },
+ { LQ_QUERY_RELAYID, "by-relayID" },
+ { LQ_QUERY_LINK_ADDRESS, "by-linkAddress" },
+ { LQ_QUERY_REMOTEID, "by-remoteID" },
{ 0, NULL },
};
@@ -1174,7 +1189,7 @@ dhcpv6_domain(proto_tree * subtree, proto_item *v_item, packet_info *pinfo, tvbu
/* Returns the number of bytes consumed by this option. */
static int
dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
- gboolean downstream, int off, int eoff, gboolean *at_end)
+ gboolean downstream, int off, int eoff, gboolean *at_end, int protocol)
{
guint16 opttype, optlen, hwtype;
guint16 temp_optlen = 0;
@@ -1217,6 +1232,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
col_append_fstr(pinfo->cinfo, COL_INFO, "CID: %s ", tvb_bytes_to_str(tvb, off, optlen));
/* Fall through */
case OPTION_SERVERID:
+ case OPTION_RELAYID:
if (optlen < 2) {
expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "DUID: malformed option");
break;
@@ -1303,7 +1319,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
temp_optlen = 12;
while ((optlen - temp_optlen) > 0) {
temp_optlen += dhcpv6_option(tvb, pinfo, subtree, downstream,
- off+temp_optlen, off + optlen, at_end);
+ off+temp_optlen, off + optlen, at_end, protocol);
if (*at_end) {
/* Bad option - just skip to the end */
temp_optlen = optlen;
@@ -1320,7 +1336,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
temp_optlen = 4;
while ((optlen - temp_optlen) > 0) {
temp_optlen += dhcpv6_option(tvb, pinfo, subtree, downstream,
- off+temp_optlen, off + optlen, at_end);
+ off+temp_optlen, off + optlen, at_end, protocol);
if (*at_end) {
/* Bad option - just skip to the end */
temp_optlen = optlen;
@@ -1360,7 +1376,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
temp_optlen = 24;
while ((optlen - temp_optlen) > 0) {
temp_optlen += dhcpv6_option(tvb, pinfo, subtree, downstream,
- off+temp_optlen, off + optlen, at_end);
+ off+temp_optlen, off + optlen, at_end, protocol);
if (*at_end) {
/* Bad option - just skip to the end */
temp_optlen = optlen;
@@ -1633,30 +1649,41 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
proto_tree_add_item(subtree, hf_opt_tzdb, tvb, off, optlen, ENC_ASCII|ENC_NA);
break;
case OPTION_LQ_QUERY:
+ {
+ guint8 query_type;
if (optlen < 17) {
- expert_add_info_format(pinfo, option_item, PI_PROTOCOL, PI_ERROR, "LQ-QUERY: malformed option");
+ expert_add_info_format(pinfo, option_item, PI_MALFORMED, PI_ERROR, "LQ-QUERY: malformed option");
break;
}
+ query_type = tvb_get_guint8(tvb, off);
+ ti = proto_tree_add_item(subtree, hf_lq_query, tvb, off, 1, ENC_BIG_ENDIAN);
+ if ((protocol == proto_dhcpv6) &&
+ ((query_type == LQ_QUERY_RELAYID) ||
+ (query_type == LQ_QUERY_LINK_ADDRESS) ||
+ (query_type == LQ_QUERY_REMOTEID))) {
+ expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN,
+ "LQ-QUERY: Query types only supported by Bulk Leasequery");
+ }
- proto_tree_add_item(subtree, hf_lq_query, tvb, off, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(subtree, hf_lq_query_link_address, tvb, off+1, 16, ENC_BIG_ENDIAN);
temp_optlen = 17;
while ((optlen - temp_optlen) > 0) {
temp_optlen += dhcpv6_option(tvb, pinfo, subtree,
downstream, off + temp_optlen,
- off + optlen, at_end);
+ off + optlen, at_end, protocol);
if (*at_end) {
/* Bad option - just skip to the end */
temp_optlen = optlen;
}
}
- break;
+ }
+ break;
case OPTION_CLIENT_DATA:
temp_optlen = 0;
while ((optlen - temp_optlen) > 0) {
temp_optlen += dhcpv6_option(tvb, pinfo, subtree,
downstream, off + temp_optlen,
- off + optlen, at_end);
+ off + optlen, at_end, protocol);
if (*at_end) {
/* Bad option - just skip to the end */
temp_optlen = optlen;
@@ -1677,6 +1704,10 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
break;
}
+ if (protocol == proto_dhcpv6_bulk_leasequery) {
+ expert_add_info_format(pinfo, option_item, PI_PROTOCOL, PI_WARN, "LQ_RELAY_DATA: Not allowed in Bulk Leasequery");
+ }
+
proto_tree_add_item(subtree, hf_lq_relay_data_peer_addr, tvb, off, 16, ENC_BIG_ENDIAN);
proto_tree_add_item(subtree, hf_lq_relay_data_msg, tvb, off+16, optlen - 16, ENC_ASCII|ENC_NA);
break;
@@ -1728,7 +1759,7 @@ dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
temp_optlen = 25;
while ((optlen - temp_optlen) > 0) {
temp_optlen += dhcpv6_option(tvb, pinfo, subtree, downstream,
- off+temp_optlen, off + optlen, at_end);
+ off+temp_optlen, off + optlen, at_end, protocol);
if (*at_end) {
/* Bad option - just skip to the end */
temp_optlen = optlen;
@@ -1804,7 +1835,7 @@ dissect_dhcpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
at_end = FALSE;
while (off < eoff && !at_end)
- off += dhcpv6_option(tvb, pinfo, bp_tree, downstream, off, eoff, &at_end);
+ off += dhcpv6_option(tvb, pinfo, bp_tree, downstream, off, eoff, &at_end, proto_dhcpv6);
}
static void
@@ -1851,7 +1882,14 @@ dissect_dhcpv6_bulk_leasequery_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree
offset += 2;
msg_type = tvb_get_guint8( tvb, offset );
- proto_tree_add_item(bulk_tree, hf_dhcpv6_bulk_leasequery_msgtype, tvb, offset, 1, ENC_BIG_ENDIAN);
+ ti = proto_tree_add_item(bulk_tree, hf_dhcpv6_bulk_leasequery_msgtype, tvb, offset, 1, ENC_BIG_ENDIAN);
+ if ((msg_type != LEASEQUERY) &&
+ (msg_type != LEASEQUERY_REPLY) &&
+ (msg_type != LEASEQUERY_DONE) &&
+ (msg_type != LEASEQUERY_DATA))
+ expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN,
+ "Message Type %d not allowed by DHCPv6 Bulk Leasequery", msg_type);
+
offset++;
proto_tree_add_item(bulk_tree, hf_dhcpv6_bulk_leasequery_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
offset++;
@@ -1867,7 +1905,8 @@ dissect_dhcpv6_bulk_leasequery_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree
option_tree = proto_item_add_subtree(ti, ett_dhcpv6_bulk_leasequery_options);
end = size+2;
while ((offset < end) && !at_end)
- offset += dhcpv6_option(tvb, pinfo, option_tree, FALSE, offset, end, &at_end);
+ offset += dhcpv6_option(tvb, pinfo, option_tree, FALSE, offset,
+ end, &at_end, proto_dhcpv6_bulk_leasequery);
}
static void