aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorPedro Jose Marron <pjmarron@locoslab.com>2015-10-09 14:59:37 +0200
committerGerald Combs <gerald@wireshark.org>2015-10-10 00:10:34 +0000
commit911da8b9d5e2215e7851e0874f0cdffac5961c73 (patch)
tree168ed1e88100b95bec9e76b2424965af2ea86394 /epan
parent4a45bd5bf486d7d9e5bc93478e1ee286bb301775 (diff)
Support in 6lowpan for RFC4944 address generation
For the conversion of a 16-bit short address in 6lowpan to an IID, there are several RFCs that produce different results. RFC 4944 section 6 specifies that the conversion uses the given PAN ID and the 16-bit short address. RFC 6282, on the other hand, specifies thta the conversion only uses the 16-bit short address and no longer uses the PAN ID. The current version of the 6lowpan dissector supports only the newer RFC 6282, but there are protocols out there that assume that the address conversion still abides to RFC 4944. In order to support these protocols and following the discussion from https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8970 this patch introduces a boolean preference in the 6lowpan dissector that indicates whether or not the older RFC 4944 should be used for address conversion. By default, it is set to FALSE, thus leaving the behavior of the dissector unchanged. Besides the boolean preference, another helper function lowpan_addr16_with_panid_to_ifcid has been written that implements the expected behavior from RFC 4944 using the same hint mechanism already in place in the dissector for the support of RFC 6282. Change-Id: I8d202c69a225d7b1212080a174e0111e5203553c Reviewed-on: https://code.wireshark.org/review/10902 Reviewed-by: Pascal Quantin <pascal.quantin@gmail.com> Petri-Dish: Pascal Quantin <pascal.quantin@gmail.com> Petri-Dish: Gerald Combs <gerald@wireshark.org> Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Gerald Combs <gerald@wireshark.org>
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-6lowpan.c86
1 files changed, 81 insertions, 5 deletions
diff --git a/epan/dissectors/packet-6lowpan.c b/epan/dissectors/packet-6lowpan.c
index fa91101e3a..ea0816e90b 100644
--- a/epan/dissectors/packet-6lowpan.c
+++ b/epan/dissectors/packet-6lowpan.c
@@ -455,6 +455,9 @@ static lowpan_context_data lowpan_context_local;
static lowpan_context_data lowpan_context_default;
static const gchar * lowpan_context_prefs[LOWPAN_CONTEXT_MAX];
+/* Preferences */
+static gboolean rfc4944_short_address_format = FALSE;
+
/* Helper macro to convert a bit offset/length into a byte count. */
#define BITS_TO_BYTE_LEN(bitoff, bitlen) ((bitlen)?(((bitlen) + ((bitoff)&0x07) + 7) >> 3):(0))
@@ -497,6 +500,7 @@ static void dissect_6lowpan_unknown (tvbuff_t *tvb, packet_info *pin
static gboolean lowpan_dlsrc_to_ifcid (packet_info *pinfo, guint8 *ifcid);
static gboolean lowpan_dldst_to_ifcid (packet_info *pinfo, guint8 *ifcid);
static void lowpan_addr16_to_ifcid (guint16 addr, guint8 *ifcid);
+static void lowpan_addr16_with_panid_to_ifcid(guint16 panid, guint16 addr, guint8 *ifcid);
static tvbuff_t * lowpan_reassemble_ipv6 (tvbuff_t *tvb, struct ip6_hdr * ipv6, struct lowpan_nhdr * nhdr_list);
static guint8 lowpan_parse_nhc_proto (tvbuff_t *tvb, gint offset);
@@ -678,7 +682,7 @@ lowpan_context_free(gpointer data)
* lowpan_addr16_to_ifcid
* DESCRIPTION
* Converts a short address to in interface identifier as
- * per rfc 4944 section 6.
+ * per rfc 6282 section 3.2.2.
* PARAMETERS
* addr ; 16-bit short address.
* ifcid ; interface identifier (output).
@@ -702,6 +706,34 @@ lowpan_addr16_to_ifcid(guint16 addr, guint8 *ifcid)
/*FUNCTION:------------------------------------------------------
* NAME
+ * lowpan_addr16_with_panid_to_ifcid
+ * DESCRIPTION
+ * Converts a short address to in interface identifier as
+ * per rfc 4944 section 6.
+ * PARAMETERS
+ * panid ; 16-bit PAN ID.
+ * addr ; 16-bit short address.
+ * ifcid ; interface identifier (output).
+ * RETURNS
+ * void ;
+ *---------------------------------------------------------------
+ */
+static void
+lowpan_addr16_with_panid_to_ifcid(guint16 panid, guint16 addr, guint8 *ifcid)
+{
+ /* Note: The PANID is used in building the IID following RFC 2464 section 4. */
+ ifcid[0] = (panid >> 8) & 0xfd; /* the U/L bit must be cleared. */
+ ifcid[1] = (panid >> 0) & 0xff;
+ ifcid[2] = 0x00;
+ ifcid[3] = 0xff;
+ ifcid[4] = 0xfe;
+ ifcid[5] = 0x00;
+ ifcid[6] = (addr >> 8) & 0xff;
+ ifcid[7] = (addr >> 0) & 0xff;
+} /* lowpan_addr16_with_panid_to_ifcid */
+
+/*FUNCTION:------------------------------------------------------
+ * NAME
* lowpan_dlsrc_to_ifcid
* DESCRIPTION
* Finds an interface identifier from the data-link source
@@ -731,7 +763,14 @@ lowpan_dlsrc_to_ifcid(packet_info *pinfo, guint8 *ifcid)
hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo,
proto_get_id_by_filter_name(IEEE802154_PROTOABBREV_WPAN), 0);
if (hints) {
- lowpan_addr16_to_ifcid(hints->src16, ifcid);
+
+ /* Convert the 16-bit short address to an IID using the PAN ID (RFC 4944) or not depending on the preference */
+ if (rfc4944_short_address_format) {
+ lowpan_addr16_with_panid_to_ifcid(hints->src_pan, hints->src16, ifcid);
+ } else {
+ lowpan_addr16_to_ifcid(hints->src16, ifcid);
+ }
+
return TRUE;
} else {
/* Failed to find a link-layer source address. */
@@ -770,7 +809,14 @@ lowpan_dldst_to_ifcid(packet_info *pinfo, guint8 *ifcid)
hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo,
proto_get_id_by_filter_name(IEEE802154_PROTOABBREV_WPAN), 0);
if (hints) {
- lowpan_addr16_to_ifcid(hints->dst16, ifcid);
+
+ /* Convert the 16-bit short address to an IID using the PAN ID (RFC 4944) or not depending on the preference */
+ if (rfc4944_short_address_format) {
+ lowpan_addr16_with_panid_to_ifcid(hints->src_pan, hints->dst16, ifcid);
+ } else {
+ lowpan_addr16_to_ifcid(hints->dst16, ifcid);
+ }
+
return TRUE;
} else {
/* Failed to find a link-layer destination address. */
@@ -2227,6 +2273,8 @@ dissect_6lowpan_mesh(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8
const guint8 * src_ifcid;
const guint8 * dst_ifcid;
+ ieee802154_hints_t *hints;
+
/* Create a tree for the mesh header. */
mesh_tree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_6lowpan_mesh, &ti, "Mesh Header");
@@ -2270,7 +2318,18 @@ dissect_6lowpan_mesh(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8
proto_tree_add_uint(mesh_tree, hf_6lowpan_mesh_orig16, tvb, offset, 2, addr16);
}
ifcid = (guint8 *)wmem_alloc(pinfo->pool, 8);
- lowpan_addr16_to_ifcid(addr16, ifcid);
+
+ /* Lookup the IEEE 802.15.4 addressing hints wanting RFC 2464 compatibility. */
+ hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo,
+ proto_get_id_by_filter_name(IEEE802154_PROTOABBREV_WPAN), 0);
+
+ /* Convert the 16-bit short address to an IID using the PAN ID (RFC 4944) or not depending on the preference and the presence of hints from lower layers */
+ if (hints && rfc4944_short_address_format) {
+ lowpan_addr16_with_panid_to_ifcid(hints->src_pan, addr16, ifcid);
+ } else {
+ lowpan_addr16_to_ifcid(addr16, ifcid);
+ }
+
src_ifcid = ifcid;
/* Update source IID */
memcpy(siid, src_ifcid, LOWPAN_IFC_ID_LEN);
@@ -2299,7 +2358,18 @@ dissect_6lowpan_mesh(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8
proto_tree_add_uint(mesh_tree, hf_6lowpan_mesh_dest16, tvb, offset, 2, addr16);
}
ifcid = (guint8 *)wmem_alloc(pinfo->pool, 8);
- lowpan_addr16_to_ifcid(addr16, ifcid);
+
+ /* Lookup the IEEE 802.15.4 addressing hints wanting RFC 2464 compatibility. */
+ hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo,
+ proto_get_id_by_filter_name(IEEE802154_PROTOABBREV_WPAN), 0);
+
+ /* Convert the 16-bit short address to an IID using the PAN ID (RFC 4944) or not depending on the preference and the presence of hints from lower layers */
+ if (hints && rfc4944_short_address_format) {
+ lowpan_addr16_with_panid_to_ifcid(hints->src_pan, addr16, ifcid);
+ } else {
+ lowpan_addr16_to_ifcid(addr16, ifcid);
+ }
+
dst_ifcid = ifcid;
/* Update destination IID */
memcpy(diid, dst_ifcid, LOWPAN_IFC_ID_LEN);
@@ -2855,6 +2925,12 @@ proto_register_6lowpan(void)
/* Register preferences. */
prefs_module = prefs_register_protocol(proto_6lowpan, prefs_6lowpan_apply);
+
+ prefs_register_bool_preference(prefs_module, "rfc4944_short_address_format",
+ "Derive IID according to RFC 4944",
+ "Derive IID from a short 16-bit address according to RFC 4944 (using the PAN ID).",
+ &rfc4944_short_address_format);
+
for (i = 0; i < LOWPAN_CONTEXT_MAX; i++) {
char *pref_name, *pref_title;