diff options
-rw-r--r-- | epan/dissectors/packet-6lowpan.c | 86 |
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; |