aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorLorand Jakab <ljakab@ac.upc.edu>2018-06-28 16:59:12 +0200
committerAnders Broman <a.broman58@gmail.com>2018-08-03 12:00:29 +0000
commita13558c6c3cee018e7bce6b5eed115421673723d (patch)
tree45c4e895e656203c9eea4b958f43c3f4ad5d571c /epan
parent50dfbbd566998302a45ab29982c377b21e4a3217 (diff)
LISP: add support for Reliable Transport messages
These messages are defined in [0], and are used in some deployed products already. [0] https://tools.ietf.org/html/draft-kouvelas-lisp-map-server-reliable-transport-04 Change-Id: Idfbc777175c1596d3e0fa1df39602a68ee1c488f Signed-off-by: Lorand Jakab <ljakab@ac.upc.edu> Reviewed-on: https://code.wireshark.org/review/28503 Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com> Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/CMakeLists.txt1
-rw-r--r--epan/dissectors/packet-lisp-tcp.c353
-rw-r--r--epan/dissectors/packet-lisp.c86
-rw-r--r--epan/dissectors/packet-lisp.h32
4 files changed, 398 insertions, 74 deletions
diff --git a/epan/dissectors/CMakeLists.txt b/epan/dissectors/CMakeLists.txt
index 8a079fd6bf..66506c5d34 100644
--- a/epan/dissectors/CMakeLists.txt
+++ b/epan/dissectors/CMakeLists.txt
@@ -413,6 +413,7 @@ set(DISSECTOR_PUBLIC_HEADERS
packet-lcsap.h
packet-ldp.h
packet-link16.h
+ packet-lisp.h
packet-llc.h
packet-lnet.h
packet-logotypecertextn.h
diff --git a/epan/dissectors/packet-lisp-tcp.c b/epan/dissectors/packet-lisp-tcp.c
index acc6251688..c7f8d28049 100644
--- a/epan/dissectors/packet-lisp-tcp.c
+++ b/epan/dissectors/packet-lisp-tcp.c
@@ -1,6 +1,6 @@
/* packet-lisp-tcp.c
* Routines for Locator/ID Separation Protocol (LISP) TCP Control Message dissection
- * Copyright 2014 Lorand Jakab <ljakab@ac.upc.edu>
+ * Copyright 2014, 2018 Lorand Jakab <ljakab@ac.upc.edu>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
@@ -10,32 +10,34 @@
*/
#include "config.h"
+#include "packet-tcp.h"
+#include "packet-lisp.h"
-#include <epan/packet.h>
#include <epan/to_str.h>
#include <epan/afn.h>
#include <epan/expert.h>
-#include "packet-tcp.h"
void proto_register_lisp_tcp(void);
void proto_reg_handoff_lisp_tcp(void);
-#define INET_ADDRLEN 4
-#define INET6_ADDRLEN 16
-#define EUI48_ADDRLEN 6
-
/*
- * See draft-kouvelas-lisp-rloc-membership-00 "LISP RLOC Membership
- * Distribution" for packet format and protocol information.
+ * See draft-kouvelas-lisp-map-server-reliable-transport-04 "LISP Map
+ * Server Reliable Transport", and draft-kouvelas-lisp-rloc-membership-01
+ * "LISP RLOC Membership Distribution" for packet format and protocol
+ * information.
*/
-#define LISP_CONTROL_PORT 4342
#define LISP_MSG_HEADER_LEN 4
#define LISP_MSG_END_MARKER 0x9FACADE9
-/* LISP Reliable Transport message types */
+/* LISP Map Server Reliable Transport message types */
+#define TRANSPORT_BASE 16
+/* LISP RLOC Membership Distribution message types */
#define MEMBERSHIP_BASE 22
+/* Registration refresh message flags */
+#define REFRESH_FLAG_R 0x8000
+
static gboolean lisp_tcp_desegment = TRUE;
/* Initialize the protocol and registered fields */
@@ -48,7 +50,25 @@ static int hf_lisp_tcp_message_eid_afi = -1;
static int hf_lisp_tcp_message_iid = -1;
static int hf_lisp_tcp_message_sid = -1;
static int hf_lisp_tcp_message_err = -1;
+static int hf_lisp_tcp_message_err_code = -1;
+static int hf_lisp_tcp_message_err_reserved = -1;
+static int hf_lisp_tcp_message_err_offending_msg_type = -1;
+static int hf_lisp_tcp_message_err_offending_msg_len = -1;
+static int hf_lisp_tcp_message_err_offending_msg_id = -1;
+static int hf_lisp_tcp_message_err_offending_msg_data = -1;
+static int hf_lisp_tcp_message_registration_reject_reason = -1;
+static int hf_lisp_tcp_message_registration_reject_res = -1;
+static int hf_lisp_tcp_message_registration_refresh_scope = -1;
+static int hf_lisp_tcp_message_registration_refresh_flags_rejected = -1;
+static int hf_lisp_tcp_message_registration_refresh_res = -1;
+static int hf_lisp_tcp_message_xtr_id = -1;
static int hf_lisp_tcp_message_site_id = -1;
+static int hf_lisp_tcp_message_eid_prefix_length = -1;
+static int hf_lisp_tcp_message_eid_prefix_afi = -1;
+static int hf_lisp_tcp_message_eid_ipv4 = -1;
+static int hf_lisp_tcp_message_eid_ipv6 = -1;
+static int hf_lisp_tcp_message_eid_mac = -1;
+static int hf_lisp_tcp_message_eid_lcaf = -1;
static int hf_lisp_tcp_message_rloc_afi = -1;
static int hf_lisp_tcp_message_rloc_ipv4 = -1;
static int hf_lisp_tcp_message_rloc_ipv6 = -1;
@@ -57,15 +77,25 @@ static int hf_lisp_tcp_message_end_marker = -1;
/* Initialize the subtree pointers */
static gint ett_lisp_tcp = -1;
+static gint ett_lisp_tcp_lcaf = -1;
+static gint ett_lisp_tcp_eid_prefix = -1;
+static gint ett_lisp_tcp_map_register = -1;
/* Initialize expert fields */
static expert_field ei_lisp_tcp_undecoded = EI_INIT;
static expert_field ei_lisp_tcp_invalid_length = EI_INIT;
static expert_field ei_lisp_tcp_invalid_marker = EI_INIT;
+static expert_field ei_lisp_tcp_unexpected_afi = EI_INIT;
static dissector_handle_t lisp_tcp_handle;
const value_string lisp_tcp_typevals[] = {
+ { TRANSPORT_BASE, "Error Notification" },
+ { TRANSPORT_BASE + 1, "Registration" },
+ { TRANSPORT_BASE + 2, "Registration ACK" },
+ { TRANSPORT_BASE + 3, "Registration NACK" },
+ { TRANSPORT_BASE + 4, "Registration Refresh" },
+ { TRANSPORT_BASE + 5, "Mapping Notification" },
{ MEMBERSHIP_BASE, "RLOC Membership Subscribe" },
{ MEMBERSHIP_BASE + 1, "RLOC Membership Subscribe ACK" },
{ MEMBERSHIP_BASE + 2, "RLOC Membership Subscribe NACK" },
@@ -86,12 +116,238 @@ const value_string lisp_tcp_membership_subscribe_errors[] = {
{ 0, NULL}
};
+const value_string lisp_tcp_registration_reject_reason[] = {
+ { 1, "Not a valid site EID prefix" },
+ { 2, "Authentication failure" },
+ { 3, "Locator set not allowed" },
+ { 4, "Reason not defined" },
+ { 0, NULL}
+};
+
+const value_string lisp_tcp_registration_refresh_scope[] = {
+ { 0, "All prefixes under all address families under all EID instances" },
+ { 1, "All prefixes under all address families under a single EID instance" },
+ { 2, "All prefixes under a single address family under a single EID instance" },
+ { 3, "All prefixes covered by a specific EID prefix in a single EID instance" },
+ { 4, "A specific EID prefix in a single EID instance" },
+ { 0, NULL}
+};
+
+/*
+ * Dissector for EID prefixes
+ */
+
+static guint
+dissect_lisp_tcp_message_eid_prefix(tvbuff_t *tvb, packet_info *pinfo, proto_tree *message_tree,
+ guint offset, proto_item *tim)
+{
+ proto_item *ti_lcaf_prefix;
+ proto_tree *prefix_tree, *lcaf_tree;
+ guint8 prefix_length;
+ guint16 prefix_afi, addr_len = 0;
+ const gchar *prefix;
+
+ prefix_length = tvb_get_guint8(tvb, offset);
+ prefix_afi = tvb_get_ntohs(tvb, offset + 1);
+
+ prefix = get_addr_str(tvb, offset + 3, prefix_afi, &addr_len);
+
+ if (prefix == NULL) {
+ expert_add_info_format(pinfo, message_tree, &ei_lisp_tcp_unexpected_afi,
+ "Unexpected EID prefix AFI (%d), cannot decode", prefix_afi);
+ return offset + addr_len;
+ }
+
+ proto_item_append_text(tim, " for %s/%d", prefix, prefix_length);
+ prefix_tree = proto_tree_add_subtree_format(message_tree, tvb, offset, 3 + addr_len, ett_lisp_tcp_eid_prefix,
+ NULL, "EID Prefix: %s/%d", prefix, prefix_length);
+
+ /* Prefix-Length (1 byte) */
+ proto_tree_add_item(prefix_tree, hf_lisp_tcp_message_eid_prefix_length, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ /* EID-Prefix-AFI (2 bytes) */
+ proto_tree_add_item(prefix_tree, hf_lisp_tcp_message_eid_prefix_afi, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+
+ /* EID-Prefix */
+ switch(prefix_afi) {
+ case AFNUM_INET:
+ proto_tree_add_item(prefix_tree, hf_lisp_tcp_message_eid_ipv4, tvb, offset, INET_ADDRLEN, ENC_BIG_ENDIAN);
+ offset += INET_ADDRLEN;
+ break;
+ case AFNUM_INET6:
+ proto_tree_add_item(prefix_tree, hf_lisp_tcp_message_eid_ipv6, tvb, offset, INET6_ADDRLEN, ENC_NA);
+ offset += INET6_ADDRLEN;
+ break;
+ case AFNUM_LCAF:
+ ti_lcaf_prefix = proto_tree_add_item(prefix_tree, hf_lisp_tcp_message_eid_lcaf, tvb, offset, addr_len, ENC_ASCII|ENC_NA);
+ proto_item_append_text(ti_lcaf_prefix, "%s", prefix);
+ lcaf_tree = proto_item_add_subtree(ti_lcaf_prefix, ett_lisp_tcp_lcaf);
+ dissect_lcaf(tvb, pinfo, lcaf_tree, offset, NULL);
+ offset += addr_len;
+ break;
+ case AFNUM_802:
+ case AFNUM_EUI48:
+ proto_tree_add_item(prefix_tree, hf_lisp_tcp_message_eid_mac, tvb, offset, EUI48_ADDRLEN, ENC_NA);
+ offset += EUI48_ADDRLEN;
+ break;
+ }
+ return offset;
+}
+
+
+/*
+ * Dissector for Reliable Transport messages
+ */
+
+static guint
+dissect_lisp_tcp_reliable_transport_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *message_tree,
+ guint offset, guint16 type, guint16 data_len, proto_item *tim)
+{
+ guint initial_offset = offset;
+ proto_tree *map_register_tree;
+ guint8 reject_reason, scope, err;
+ guint16 refresh_flags, offending_msg_type;
+
+ switch (type) {
+
+ /* Error Notification */
+ case TRANSPORT_BASE:
+ /* Error code (1 byte) */
+ err = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item(message_tree, hf_lisp_tcp_message_err_code, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+ data_len -= 1;
+ proto_item_append_text(tim, ", Code: %d", err);
+
+ /* Reserved (3 bytes) */
+ proto_tree_add_item(message_tree, hf_lisp_tcp_message_err_reserved, tvb, offset, 3, ENC_BIG_ENDIAN);
+ offset += 3;
+ data_len -= 3;
+
+ /* Offending message type (2 bytes) */
+ offending_msg_type = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_item(message_tree, hf_lisp_tcp_message_err_offending_msg_type, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+ data_len -= 2;
+ proto_item_append_text(tim, ", Offending message type: %s",
+ val_to_str(offending_msg_type, lisp_tcp_typevals, "Unknown type (%u)"));
+
+ /* Offending message length (2 bytes) */
+ proto_tree_add_item(message_tree, hf_lisp_tcp_message_err_offending_msg_len, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+ data_len -= 2;
+
+ /* Offending message ID (4 bytes) */
+ proto_tree_add_item(message_tree, hf_lisp_tcp_message_err_offending_msg_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ data_len -= 4;
+
+ /* Offending message data */
+ if (data_len) {
+ proto_tree_add_item(message_tree, hf_lisp_tcp_message_err_offending_msg_data, tvb, offset, data_len, ENC_NA);
+ offset += data_len;
+ }
+ return offset;
+
+ /* Registration */
+ case TRANSPORT_BASE + 1:
+ /* Map-Register */
+ map_register_tree = proto_tree_add_subtree(message_tree, tvb, offset, data_len,
+ ett_lisp_tcp_map_register, NULL, "Map-Register");
+ offset = dissect_lisp_map_register(tvb, pinfo, map_register_tree, offset, tim, FALSE);
+ data_len -= offset - initial_offset;
+ break;
+
+ /* Registration ACK */
+ case TRANSPORT_BASE + 2:
+ /* EID */
+ offset = dissect_lisp_tcp_message_eid_prefix(tvb, pinfo, message_tree, offset, tim);
+ data_len -= offset - initial_offset;
+ break;
+
+ /* Registration Reject */
+ case TRANSPORT_BASE + 3:
+ /* Reason (1 byte) */
+ reject_reason = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item(message_tree, hf_lisp_tcp_message_registration_reject_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+ proto_item_append_text(tim, ", Reason: %s",
+ val_to_str(reject_reason, lisp_tcp_registration_reject_reason, "Unknown reason code (%u)"));
+
+ /* Reserved (2 bytes) */
+ proto_tree_add_item(message_tree, hf_lisp_tcp_message_registration_reject_res, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+
+ /* EID */
+ offset = dissect_lisp_tcp_message_eid_prefix(tvb, pinfo, message_tree, offset, tim);
+ data_len -= offset - initial_offset;
+ break;
+
+ /* Registration Refresh */
+ case TRANSPORT_BASE + 4:
+ /* Reason (1 byte) */
+ scope = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item(message_tree, hf_lisp_tcp_message_registration_refresh_scope, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+ proto_item_append_text(tim, ", Scope: %s",
+ val_to_str(scope, lisp_tcp_registration_refresh_scope, "Unknown scope code (%u)"));
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Scope: %d", scope);
+
+ /* Rejected only flag (1 bit) */
+ refresh_flags = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_item(message_tree, hf_lisp_tcp_message_registration_refresh_flags_rejected, tvb, offset, 2, ENC_BIG_ENDIAN);
+ if (refresh_flags & REFRESH_FLAG_R) {
+ proto_item_append_text(tim, " (rejected only)");
+ col_append_fstr(pinfo->cinfo, COL_INFO, " (rejected only)");
+ }
+
+ /* Reserved (15 bits) */
+ proto_tree_add_item(message_tree, hf_lisp_tcp_message_registration_refresh_res, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+
+ if (scope == 0) {
+ data_len -= 3;
+ break;
+ }
+
+ /* EID */
+ offset = dissect_lisp_tcp_message_eid_prefix(tvb, pinfo, message_tree, offset, tim);
+ data_len -= offset - initial_offset;
+ break;
+
+ /* Mapping Notification */
+ case TRANSPORT_BASE + 5:
+ /* xTR-ID (16 bytes) */
+ proto_tree_add_item(message_tree, hf_lisp_tcp_message_xtr_id, tvb, offset, LISP_XTRID_LEN, ENC_NA);
+ offset += LISP_XTRID_LEN;
+
+ /* Site-ID (8 bytes) */
+ proto_tree_add_item(message_tree, hf_lisp_tcp_message_site_id, tvb, offset, LISP_SITEID_LEN, ENC_NA);
+ offset += LISP_SITEID_LEN;
+
+ /* Mapping Record */
+ offset = dissect_lisp_mapping(tvb, pinfo, message_tree, 0, 1, FALSE, offset, tim);
+ data_len -= offset - initial_offset;
+ break;
+ }
+
+ if (data_len) {
+ proto_tree_add_item(message_tree, hf_lisp_tcp_message_data, tvb, offset, data_len, ENC_NA);
+ offset += data_len;
+ expert_add_info_format(pinfo, message_tree, &ei_lisp_tcp_undecoded, "Work-in-progress");
+ }
+
+ return offset;
+}
+
/*
* Dissector for Membership messages
*/
-static int
+static guint
dissect_lisp_tcp_membership_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *message_tree,
guint offset, guint16 type, guint16 data_len, proto_item *tim)
{
@@ -139,7 +395,7 @@ dissect_lisp_tcp_membership_message(tvbuff_t *tvb, packet_info *pinfo, proto_tre
case MEMBERSHIP_BASE + 5:
/* Site ID (8 bytes) */
siteid = tvb_get_ntoh64(tvb, offset);
- proto_tree_add_item(message_tree, hf_lisp_tcp_message_site_id, tvb, offset, 8, ENC_BIG_ENDIAN);
+ proto_tree_add_item(message_tree, hf_lisp_tcp_message_site_id, tvb, offset, LISP_SITEID_LEN, ENC_NA);
offset += 8;
data_len -= 8;
proto_item_append_text(tim, ", Site-ID: %"G_GINT64_MODIFIER"u", siteid);
@@ -231,7 +487,10 @@ dissect_lisp_tcp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, vo
proto_item_set_len(tim, len);
data_len = len - 12;
- if (type >= MEMBERSHIP_BASE && type <= MEMBERSHIP_BASE + 8) {
+ if (type >= TRANSPORT_BASE && type <= TRANSPORT_BASE + 5) {
+ /* Map Server reliable transport message types */
+ offset = dissect_lisp_tcp_reliable_transport_message(tvb, pinfo, message_tree, offset, type, data_len, tim);
+ } else if (type >= MEMBERSHIP_BASE && type <= MEMBERSHIP_BASE + 8) {
/* EID instance membership message types */
offset = dissect_lisp_tcp_membership_message(tvb, pinfo, message_tree, offset, type, data_len, tim);
} else {
@@ -329,9 +588,63 @@ proto_register_lisp_tcp(void)
{ &hf_lisp_tcp_message_err,
{ "Error code", "lisp-tcp.message.err",
FT_UINT8, BASE_DEC, VALS(lisp_tcp_membership_subscribe_errors), 0x0, NULL, HFILL }},
+ { &hf_lisp_tcp_message_err_code,
+ { "Error code", "lisp-tcp.message.err.code",
+ FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+ { &hf_lisp_tcp_message_err_reserved,
+ { "Error code", "lisp-tcp.message.err.reserved",
+ FT_UINT24, BASE_HEX, NULL, 0x0, "Must be zero", HFILL }},
+ { &hf_lisp_tcp_message_err_offending_msg_type,
+ { "Offending message type", "lisp-tcp.message.err.offending_msg.type",
+ FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+ { &hf_lisp_tcp_message_err_offending_msg_len,
+ { "Offending message length", "lisp-tcp.message.err.offending_msg.len",
+ FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+ { &hf_lisp_tcp_message_err_offending_msg_id,
+ { "Offending message ID", "lisp-tcp.message.err.offending_msg.id",
+ FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+ { &hf_lisp_tcp_message_err_offending_msg_data,
+ { "Offending message data", "lisp-tcp.message.err.offending_msg.data",
+ FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ { &hf_lisp_tcp_message_registration_reject_reason,
+ { "Registration reject reason", "lisp-tcp.message.registration_reject.reason",
+ FT_UINT8, BASE_DEC, VALS(lisp_tcp_registration_reject_reason), 0x0, NULL, HFILL }},
+ { &hf_lisp_tcp_message_registration_reject_res,
+ { "Reserved bits", "lisp-tcp.message.registration_reject.res",
+ FT_UINT16, BASE_HEX, NULL, 0x0, "Must be zero", HFILL }},
+ { &hf_lisp_tcp_message_registration_refresh_scope,
+ { "Registration refresh scope", "lisp-tcp.message.registration_refresh.scope",
+ FT_UINT8, BASE_DEC, VALS(lisp_tcp_registration_refresh_scope), 0x0, NULL, HFILL }},
+ { &hf_lisp_tcp_message_registration_refresh_flags_rejected,
+ { "Rejected only", "lisp-tcp.message.registration_refresh.flags.rejected",
+ FT_BOOLEAN, 16, TFS(&tfs_set_notset), REFRESH_FLAG_R, NULL, HFILL }},
+ { &hf_lisp_tcp_message_registration_refresh_res,
+ { "Reserved", "lisp-tcp.message.registration_refresh.res",
+ FT_UINT16, BASE_HEX, NULL, 0x7FFF, "Must be zero", HFILL }},
+ { &hf_lisp_tcp_message_xtr_id,
+ { "xTR-ID", "lisp-tcp.message.xtrid",
+ FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_lisp_tcp_message_site_id,
- { "Site-ID", "lisp-tcp.message.site_id",
- FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+ { "Site-ID", "lisp-tcp.message.siteid",
+ FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ { &hf_lisp_tcp_message_eid_prefix_length,
+ { "Prefix Length", "lisp-tcp.message.eid.prefix.length",
+ FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+ { &hf_lisp_tcp_message_eid_prefix_afi,
+ { "Prefix AFI", "lisp-tcp.message.eid.prefix.afi",
+ FT_UINT16, BASE_DEC, VALS(afn_vals), 0x0, NULL, HFILL }},
+ { &hf_lisp_tcp_message_eid_ipv4,
+ { "Address", "lisp-tcp.message.eid.ipv4",
+ FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ { &hf_lisp_tcp_message_eid_ipv6,
+ { "Address", "lisp-tcp.message.eid.ipv6",
+ FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ { &hf_lisp_tcp_message_eid_mac,
+ { "Address", "lisp-tcp.message.eid.mac",
+ FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ { &hf_lisp_tcp_message_eid_lcaf,
+ { "Address", "lisp-tcp.message.eid.lcaf",
+ FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_lisp_tcp_message_rloc_afi,
{ "RLOC AFI", "lisp-tcp.message.rloc.afi",
FT_UINT16, BASE_DEC, VALS(afn_vals), 0x0, NULL, HFILL }},
@@ -351,13 +664,17 @@ proto_register_lisp_tcp(void)
/* Setup protocol subtree array */
static gint *ett[] = {
- &ett_lisp_tcp
+ &ett_lisp_tcp,
+ &ett_lisp_tcp_lcaf,
+ &ett_lisp_tcp_eid_prefix,
+ &ett_lisp_tcp_map_register
};
static ei_register_info ei[] = {
{ &ei_lisp_tcp_undecoded, { "lisp-tcp.undecoded", PI_UNDECODED, PI_WARN, "Not dissected yet (report to wireshark.org)", EXPFILL }},
- { &ei_lisp_tcp_invalid_length, { "lisp-tcp.invalid_marker", PI_PROTOCOL, PI_ERROR, "Invalid message length", EXPFILL }},
+ { &ei_lisp_tcp_invalid_length, { "lisp-tcp.invalid_length", PI_PROTOCOL, PI_ERROR, "Invalid message length", EXPFILL }},
{ &ei_lisp_tcp_invalid_marker, { "lisp-tcp.invalid_marker", PI_PROTOCOL, PI_ERROR, "Invalid message end marker", EXPFILL }},
+ { &ei_lisp_tcp_unexpected_afi, { "lisp-tcp.unexpected_afi", PI_PROTOCOL, PI_ERROR, "Unexpected AFI", EXPFILL }},
};
expert_module_t* expert_lisp_tcp;
diff --git a/epan/dissectors/packet-lisp.c b/epan/dissectors/packet-lisp.c
index 374056b67e..0566807d43 100644
--- a/epan/dissectors/packet-lisp.c
+++ b/epan/dissectors/packet-lisp.c
@@ -12,8 +12,8 @@
*/
#include "config.h"
+#include "packet-lisp.h"
-#include <epan/packet.h>
#include <epan/to_str.h>
#include <epan/afn.h>
#include <epan/expert.h>
@@ -23,10 +23,6 @@
void proto_register_lisp(void);
void proto_reg_handoff_lisp(void);
-#define INET_ADDRLEN 4
-#define INET6_ADDRLEN 16
-#define EUI48_ADDRLEN 6
-
/*
* See RFC 6830 "Locator/ID Separation Protocol (LISP)",
* draft-ietf-lisp-lcaf-05 "LISP Canonical Address Format (LCAF)",
@@ -36,7 +32,6 @@ void proto_reg_handoff_lisp(void);
*/
#define LCAF_DRAFT_VERSION "05"
-#define LISP_CONTROL_PORT 4342
/* LISP Control Message types */
#define LISP_MAP_REQUEST 1
@@ -78,8 +73,6 @@ void proto_reg_handoff_lisp(void);
#define LCAF_HEADER_LEN 6
#define LISP_ECM_HEADER_LEN 4
-#define LISP_XTRID_LEN 16
-#define LISP_SITEID_LEN 8
#define LISP_MAP_ACT 0xE000
#define LISP_MAP_AUTH 0x1000
@@ -474,9 +467,6 @@ const value_string lon_typevals[] = {
};
static int
-dissect_lcaf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, proto_item *tip);
-
-static int
get_lcaf_data(tvbuff_t *tvb, gint offset, guint8 *lcaf_type, guint16 *len)
{
/* Jump over Rsvd1 and Flags (16 bits) */
@@ -499,7 +489,7 @@ get_lcaf_data(tvbuff_t *tvb, gint offset, guint8 *lcaf_type, guint16 *len)
return offset;
}
-static const gchar *
+const gchar *
get_addr_str(tvbuff_t *tvb, gint offset, guint16 afi, guint16 *addr_len)
{
const gchar *notset_str = "not set";
@@ -1710,7 +1700,7 @@ dissect_lcaf_kv_addr_pair(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
*
*/
-static int
+int
dissect_lcaf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, proto_item *tip)
{
guint8 lcaf_type;
@@ -1922,12 +1912,11 @@ dissect_lisp_locator(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lisp_mapping
*
*/
-static int
+int
dissect_lisp_mapping(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lisp_tree,
- guint8 rec_cnt, int rec, gboolean referral)
+ guint8 rec_cnt, int rec, gboolean referral, gint offset, proto_item *tim)
{
int i;
- gint offset = 0;
guint16 addr_len = 0;
guint8 prefix_mask, loc_cnt;
guint16 flags;
@@ -1937,21 +1926,24 @@ dissect_lisp_mapping(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lisp_tree,
proto_item *tir, *ti_lcaf_prefix;
proto_tree *lisp_mapping_tree, *lcaf_prefix_tree;
- prefix_mask = tvb_get_guint8(tvb, 5);
- flags = tvb_get_ntohs(tvb, 6);
- prefix_afi = tvb_get_ntohs(tvb, 10);
+ prefix_mask = tvb_get_guint8(tvb, offset + 5);
+ flags = tvb_get_ntohs(tvb, offset + 6);
+ prefix_afi = tvb_get_ntohs(tvb, offset + 10);
act = flags & LISP_MAP_ACT;
act >>= 13;
- prefix = get_addr_str(tvb, 12, prefix_afi, &addr_len);
+ prefix = get_addr_str(tvb, offset + 12, prefix_afi, &addr_len);
if (prefix == NULL) {
expert_add_info_format(pinfo, lisp_tree, &ei_lisp_unexpected_field,
"Unexpected EID prefix AFI (%d), cannot decode", prefix_afi);
return offset;
}
- tir = proto_tree_add_item(lisp_tree, hf_lisp_mapping, tvb, 0, 12 + addr_len, ENC_NA);
+ tir = proto_tree_add_item(lisp_tree, hf_lisp_mapping, tvb, offset, 12 + addr_len, ENC_NA);
+ if (tim) {
+ proto_item_append_text(tim, " for %s/%d", prefix, prefix_mask);
+ }
/* Update the INFO column if there is only one record */
if (rec_cnt == 1)
@@ -2293,17 +2285,13 @@ dissect_lisp_map_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lisp_tre
/* If M bit is set, we also have a Map-Reply */
if (mrep) {
- int len = 0;
- tvbuff_t *rep_tvb;
proto_item *tim;
proto_tree *lisp_mr_tree;
tim = proto_tree_add_item(lisp_tree, hf_lisp_mrep_record, tvb, offset, -1, ENC_NA);
lisp_mr_tree = proto_item_add_subtree(tim, ett_lisp_mr);
- rep_tvb = tvb_new_subset_remaining(tvb, offset);
- len = dissect_lisp_mapping(rep_tvb, pinfo, lisp_mr_tree, 0, 1, FALSE);
- offset += len;
+ offset = dissect_lisp_mapping(tvb, pinfo, lisp_mr_tree, 0, 1, FALSE, offset, NULL);
}
next_tvb = tvb_new_subset_remaining(tvb, offset);
@@ -2377,12 +2365,7 @@ dissect_lisp_map_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lisp_tree)
/* Reply records */
for(i=0; i < rec_cnt; i++) {
- tvbuff_t *rec_tvb;
- int len = 0;
-
- rec_tvb = tvb_new_subset_remaining(tvb, offset);
- len = dissect_lisp_mapping(rec_tvb, pinfo, lisp_tree, rec_cnt, i+1, FALSE);
- offset += len;
+ offset = dissect_lisp_mapping(tvb, pinfo, lisp_tree, rec_cnt, i+1, FALSE, offset, NULL);
}
next_tvb = tvb_new_subset_remaining(tvb, offset);
@@ -2423,11 +2406,11 @@ dissect_lisp_map_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lisp_tree)
*
*/
-static void
-dissect_lisp_map_register(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lisp_tree)
+gint
+dissect_lisp_map_register(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lisp_tree,
+ gint offset, proto_item *tim, gboolean keep_going)
{
int i;
- gint offset = 0;
guint8 rec_cnt = 0;
tvbuff_t *next_tvb;
guint16 authlen = 0;
@@ -2483,12 +2466,7 @@ dissect_lisp_map_register(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lisp_tr
offset += authlen;
for(i=0; i < rec_cnt; i++) {
- tvbuff_t *rec_tvb;
- int len = 0;
-
- rec_tvb = tvb_new_subset_remaining(tvb, offset);
- len = dissect_lisp_mapping(rec_tvb, pinfo, lisp_tree, rec_cnt, i+1, FALSE);
- offset += len;
+ offset = dissect_lisp_mapping(tvb, pinfo, lisp_tree, rec_cnt, i+1, FALSE, offset, tim);
}
/* If I bit is set, we have an xTR-ID and a site-ID field */
@@ -2498,8 +2476,14 @@ dissect_lisp_map_register(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lisp_tr
offset += LISP_XTRID_LEN + LISP_SITEID_LEN;
}
- next_tvb = tvb_new_subset_remaining(tvb, offset);
- call_data_dissector(next_tvb, pinfo, lisp_tree);
+ if (keep_going) {
+ next_tvb = tvb_new_subset_remaining(tvb, offset);
+ call_data_dissector(next_tvb, pinfo, lisp_tree);
+ } else {
+ return offset;
+ }
+
+ return 0;
}
@@ -2587,12 +2571,7 @@ dissect_lisp_map_notify(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lisp_tree
offset += authlen;
for(i=0; i < rec_cnt; i++) {
- tvbuff_t *rec_tvb;
- int len = 0;
-
- rec_tvb = tvb_new_subset_remaining(tvb, offset);
- len = dissect_lisp_mapping(rec_tvb, pinfo, lisp_tree, rec_cnt, i+1, FALSE);
- offset += len;
+ offset = dissect_lisp_mapping(tvb, pinfo, lisp_tree, rec_cnt, i+1, FALSE, offset, NULL);
}
/* If I bit is set, we have an xTR-ID and a site-ID field */
@@ -2675,12 +2654,7 @@ dissect_lisp_map_referral(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lisp_tr
/* Referral records */
for(i=0; i < rec_cnt; i++) {
- tvbuff_t *rec_tvb;
- int len = 0;
-
- rec_tvb = tvb_new_subset_remaining(tvb, offset);
- len = dissect_lisp_mapping(rec_tvb, pinfo, lisp_tree, rec_cnt, i+1, TRUE);
- offset += len;
+ offset = dissect_lisp_mapping(tvb, pinfo, lisp_tree, rec_cnt, i+1, TRUE, offset, NULL);
}
next_tvb = tvb_new_subset_remaining(tvb, offset);
@@ -2931,7 +2905,7 @@ dissect_lisp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
dissect_lisp_map_reply(tvb, pinfo, lisp_tree);
break;
case LISP_MAP_REGISTER:
- dissect_lisp_map_register(tvb, pinfo, lisp_tree);
+ dissect_lisp_map_register(tvb, pinfo, lisp_tree, 0, NULL, TRUE);
break;
case LISP_MAP_NOTIFY:
dissect_lisp_map_notify(tvb, pinfo, lisp_tree);
diff --git a/epan/dissectors/packet-lisp.h b/epan/dissectors/packet-lisp.h
new file mode 100644
index 0000000000..6b25cb00f1
--- /dev/null
+++ b/epan/dissectors/packet-lisp.h
@@ -0,0 +1,32 @@
+/* packet-lisp.h
+ * Routines for Locator/ID Separation Protocol (LISP) Control Message dissection
+ * Copyright 2018 Lorand Jakab <ljakab@ac.upc.edu>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef __PACKET_LISP_H__
+#define __PACKET_LISP_H__
+
+#include <epan/packet.h>
+
+#define INET_ADDRLEN 4
+#define INET6_ADDRLEN 16
+#define EUI48_ADDRLEN 6
+#define LISP_XTRID_LEN 16
+#define LISP_SITEID_LEN 8
+
+#define LISP_CONTROL_PORT 4342
+
+const gchar * get_addr_str(tvbuff_t *tvb, gint offset, guint16 afi, guint16 *addr_len);
+int dissect_lcaf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, proto_item *tip);
+int dissect_lisp_mapping(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lisp_tree,
+ guint8 rec_cnt, int rec, gboolean referral, gint offset, proto_item *tim);
+gint dissect_lisp_map_register(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lisp_tree,
+ gint offset, proto_item *tim, gboolean keep_going);
+
+#endif /* __PACKET_LISP_H__ */