diff options
author | Jérôme LAFORGE <jerome.laforge@gmail.com> | 2014-09-07 16:35:10 +0200 |
---|---|---|
committer | Evan Huus <eapache@gmail.com> | 2014-09-08 16:28:35 +0000 |
commit | 00a244445d3102d0169342e92b74471e8635623a (patch) | |
tree | 528d06d5d7d85629ed8e3e49697f886b5061bc0d /epan/dissectors/packet-dhcpv6.c | |
parent | cf8f11f67876462510cc4254b845063c6cc047de (diff) | |
download | wireshark-00a244445d3102d0169342e92b74471e8635623a.tar.gz |
Check hopcount is correctly incremented by 1
Extract RFC3315 about hop-count :
20.1.2. Relaying a Message from a Relay Agent
If the message received by the relay agent is a Relay-forward message
and the hop-count in the message is greater than or equal to
HOP_COUNT_LIMIT, the relay agent discards the received message.
The relay agent copies the source address from the IP datagram in
which the message was received from the client into the peer-address
field in the Relay-forward message and sets the hop-count field to
the value of the hop-count field in the received message incremented
by 1.
Bug:10449
Change-Id: Ifb94e7c54c0a26714fc543862d4358d3e60c2676
Reviewed-on: https://code.wireshark.org/review/4017
Reviewed-by: Michael Mann <mmann78@netscape.net>
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Evan Huus <eapache@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-dhcpv6.c')
-rw-r--r-- | epan/dissectors/packet-dhcpv6.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/epan/dissectors/packet-dhcpv6.c b/epan/dissectors/packet-dhcpv6.c index 787caf76db..0607fa5d17 100644 --- a/epan/dissectors/packet-dhcpv6.c +++ b/epan/dissectors/packet-dhcpv6.c @@ -725,9 +725,15 @@ static value_string_ext eue_capabilities_encoding_ext = VALUE_STRING_EXT_INIT(eu typedef struct hopcount_info_t { guint8 hopcount; proto_item *pi; + gboolean relay_message_previously_detected; } hopcount_info; static void +initialize_hopount_info(hopcount_info *hpi) { + memset(hpi, 0, sizeof(hopcount_info)); +} + +static void dissect_dhcpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean downstream, int off, int eoff, hopcount_info hpi); @@ -1927,6 +1933,8 @@ dissect_dhcpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, if ((msgtype == RELAY_FORW) || (msgtype == RELAY_REPLY)) { + const guint8 previous_hopcount = hpi.hopcount; + proto_item *previous_pi = hpi.pi; if (tree) { proto_tree_add_item(bp_tree, hf_dhcpv6_msgtype, tvb, off, 1, ENC_BIG_ENDIAN); hpi.pi = proto_tree_add_item(bp_tree, hf_dhcpv6_hopcount, tvb, off + 1, 1, ENC_BIG_ENDIAN); @@ -1939,6 +1947,11 @@ dissect_dhcpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, if (hpi.hopcount > HOP_COUNT_LIMIT) { expert_add_info_format(pinfo, hpi.pi, &ei_dhcpv6_error_hopcount, "Hopcount (%d) exceeds the maximum limit HOP_COUNT_LIMIT (%d)", hpi.hopcount, HOP_COUNT_LIMIT); } + /* Check hopcount is correctly incremented by 1 */ + if (hpi.relay_message_previously_detected && hpi.hopcount != previous_hopcount - 1) { + expert_add_info_format(pinfo, previous_pi, &ei_dhcpv6_error_hopcount, "hopcount is not correctly incremented by 1 (expected : %d, actual : %d)", hpi.hopcount + 1, previous_hopcount); + } + hpi.relay_message_previously_detected = TRUE; tvb_get_ipv6(tvb, off + 2, &in6); col_append_fstr(pinfo->cinfo, COL_INFO, "L: %s ", ip6_to_str(&in6)); off += 34; @@ -1964,8 +1977,7 @@ static void dissect_dhcpv6_downstream(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { hopcount_info hpi; - hpi.hopcount = 0; - hpi.pi = NULL; + initialize_hopount_info(&hpi); col_set_str(pinfo->cinfo, COL_PROTOCOL, "DHCPv6"); col_clear(pinfo->cinfo, COL_INFO); dissect_dhcpv6(tvb, pinfo, tree, TRUE, 0, tvb_reported_length(tvb), hpi); @@ -1975,8 +1987,7 @@ static void dissect_dhcpv6_upstream(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { hopcount_info hpi; - hpi.hopcount = 0; - hpi.pi = NULL; + initialize_hopount_info(&hpi); col_set_str(pinfo->cinfo, COL_PROTOCOL, "DHCPv6"); col_clear(pinfo->cinfo, COL_INFO); dissect_dhcpv6(tvb, pinfo, tree, FALSE, 0, tvb_reported_length(tvb), hpi); @@ -1999,8 +2010,7 @@ dissect_dhcpv6_bulk_leasequery_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree guint8 msg_type; gboolean at_end = FALSE; hopcount_info hpi; - hpi.hopcount = 0; - hpi.pi = NULL; + initialize_hopount_info(&hpi); col_set_str(pinfo->cinfo, COL_PROTOCOL, "DHCPv6 BulkLease"); col_clear(pinfo->cinfo, COL_INFO); |