aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-babel.c
diff options
context:
space:
mode:
authorSawssen Hadded <saw.hadded@gmail.com>2019-06-05 16:22:44 +0200
committerAnders Broman <a.broman58@gmail.com>2019-06-13 22:33:52 +0000
commitb7cb793fdf71ae9eef132a50e7a3560db1dffbf0 (patch)
tree393c7669c525256f378fe434d2a08b65e6e306ad /epan/dissectors/packet-babel.c
parente39f2bb5177c36b6d8e4988baa382cf8a10ee869 (diff)
babel: add support for babel rfc6126bis
RFC 6126 (Babel) is updated by RFC 6126bis. This adds the following features from 6126bis and related drafts: - Unicast (draft-ietf-babel-rfc6126bis-09) - Mandatory (draft-ietf-babel-rfc6126bis-09) - Unscheduled Hello (draft-ietf-babel-rfc6126bis-09) - HMAC, PC, Challenge Request and Reply (draft-ietf-babel-hmac-04) - Packet Trailer (draft-ietf-babel-rfc6126bis-09) Bug: 15846 Change-Id: I83db9d68e3971a2adc6276882cb5c8d288eb8c98 Reviewed-on: https://code.wireshark.org/review/33564 Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-babel.c')
-rw-r--r--epan/dissectors/packet-babel.c297
1 files changed, 242 insertions, 55 deletions
diff --git a/epan/dissectors/packet-babel.c b/epan/dissectors/packet-babel.c
index 790dc06ddc..6259a50a65 100644
--- a/epan/dissectors/packet-babel.c
+++ b/epan/dissectors/packet-babel.c
@@ -39,8 +39,17 @@ static int hf_babel_message_plen = -1;
static int hf_babel_message_omitted = -1;
static int hf_babel_message_metric = -1;
static int hf_babel_message_hopcount = -1;
+static int hf_babel_message_index = -1;
+static int hf_babel_subtlv = -1;
+static int hf_babel_subtlv_type = -1;
+static int hf_babel_subtlv_diversity = -1;
static gint ett_subtree = -1;
+static gint ett_packet_trailer = -1;
+static gint ett_unicast = -1;
+static gint ett_subtlv = -1;
+static gint ett_timestamp = -1;
+static gint ett_mandatory = -1;
#define UDP_PORT_RANGE_BABEL "6696"
@@ -56,32 +65,57 @@ static gint ett_subtree = -1;
#define MESSAGE_REQUEST 9
#define MESSAGE_MH_REQUEST 10
#define MESSAGE_TS_PC 11
-#define MESSAGE_HMAC 12
+#define MESSAGE_HMAC_OLD 12
#define MESSAGE_SRC_UPDATE 13
#define MESSAGE_SRC_REQUEST 14
-#define MESSAGE_SRC_SEQNO 15
+#define MESSAGE_SRC_SEQNO 15
+#define MESSAGE_HMAC 16
+#define MESSAGE_PC 17
+#define MESSAGE_CHALLENGE_REQUEST 18
+#define MESSAGE_CHALLENGE_REPLY 19
+
+/** sub-TLVs */
+#define MESSAGE_SUB_PAD1 0
+#define MESSAGE_SUB_PADN 1
+#define MESSAGE_SUB_DIVERSITY 2
+#define MESSAGE_SUB_TIMESTAMP 3
+
+/** mask for bits */
+#define UNICAST_FLAG 0x80
+#define MANDATORY_FLAG 128
/** message string values listed in rfc7557 */
static const value_string messages[] = {
- { MESSAGE_PAD1, "pad1"},
- { MESSAGE_PADN, "padn"},
- { MESSAGE_ACK_REQ, "ack-req"},
- { MESSAGE_ACK, "ack"},
- { MESSAGE_HELLO, "hello"},
- { MESSAGE_IHU, "ihu"},
- { MESSAGE_ROUTER_ID, "router-id"},
- { MESSAGE_NH, "nh"},
- { MESSAGE_UPDATE, "update"},
- { MESSAGE_REQUEST, "request"},
- { MESSAGE_MH_REQUEST, "mh-request"},
- { MESSAGE_TS_PC, "ts/pc"},
- { MESSAGE_HMAC, "hmac" },
- { MESSAGE_SRC_UPDATE, "source-specific-update"},
- { MESSAGE_SRC_REQUEST,"source-specific-req"},
- { MESSAGE_SRC_SEQNO, "source-specific-seqno"},
+ { MESSAGE_PAD1, "pad1"},
+ { MESSAGE_PADN, "padn"},
+ { MESSAGE_ACK_REQ, "ack-req"},
+ { MESSAGE_ACK, "ack"},
+ { MESSAGE_HELLO, "hello"},
+ { MESSAGE_IHU, "ihu"},
+ { MESSAGE_ROUTER_ID, "router-id"},
+ { MESSAGE_NH, "nh"},
+ { MESSAGE_UPDATE, "update"},
+ { MESSAGE_REQUEST, "request"},
+ { MESSAGE_MH_REQUEST, "mh-request"},
+ { MESSAGE_TS_PC, "ts/pc (obsolete)"},
+ { MESSAGE_HMAC_OLD, "hmac" },
+ { MESSAGE_SRC_UPDATE, "source-specific-update"},
+ { MESSAGE_SRC_REQUEST, "source-specific-req"},
+ { MESSAGE_SRC_SEQNO, "source-specific-seqno"},
+ { MESSAGE_HMAC, "hmac"},
+ { MESSAGE_PC, "pc"},
+ { MESSAGE_CHALLENGE_REQUEST, "challenge-request"},
+ { MESSAGE_CHALLENGE_REPLY, "challenge-reply"},
{ 0, NULL}
};
+static const value_string subtlvs[] = {
+ { MESSAGE_SUB_PAD1, "sub-pad1"},
+ { MESSAGE_SUB_PADN, "sub-padn"},
+ { MESSAGE_SUB_DIVERSITY, "diversity"},
+ { MESSAGE_SUB_TIMESTAMP, "timestamp"},
+ { 0, NULL}
+};
static const value_string aes[] = {
{ 0, "Wildcard" },
@@ -138,6 +172,7 @@ network_prefix(int ae, int plen, unsigned int omitted,
{
guint pb;
unsigned char prefix[16];
+ int consumed = 0;
if (plen >= 0)
pb = (plen + 7) / 8;
@@ -161,8 +196,10 @@ network_prefix(int ae, int plen, unsigned int omitted,
if (dp == NULL) return -1;
memcpy(prefix, dp, 12 + omitted);
}
- if (pb > omitted)
+ if (pb > omitted) {
tvb_memcpy(tvb, prefix + 12 + omitted, offset, pb - omitted);
+ consumed = pb - omitted;
+ }
break;
case 2:
if (omitted > 16 || (pb > omitted && len < pb - omitted))
@@ -171,22 +208,26 @@ network_prefix(int ae, int plen, unsigned int omitted,
if (dp == NULL) return -1;
memcpy(prefix, dp, omitted);
}
- if (pb > omitted)
+ if (pb > omitted) {
tvb_memcpy(tvb, prefix + omitted, offset, pb - omitted);
+ consumed = pb - omitted;
+ }
break;
case 3:
if (pb > 8 && len < pb - 8) return -1;
prefix[0] = 0xfe;
prefix[1] = 0x80;
- if (pb > 8)
+ if (pb > 8) {
tvb_memcpy(tvb, prefix + 8, offset, pb - 8);
+ consumed = pb - 8;
+ }
break;
default:
return -1;
}
memcpy(p_r, prefix, 16);
- return 1;
+ return consumed;
}
static int
@@ -196,45 +237,109 @@ network_address(int ae, tvbuff_t *tvb, int offset, unsigned int len,
return network_prefix(ae, -1, 0, tvb, offset, NULL, len, a_r);
}
-static int
-dissect_babel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+static const char *
+format_timestamp(const guint32 i)
{
- proto_item *ti;
- unsigned char v4_prefix[16] = {0}, v6_prefix[16] = {0};
- int i;
- proto_tree *babel_tree = NULL;
- guint8 version;
- guint16 bodylen;
-
- if (tvb_captured_length(tvb) < 4)
- return 0;
+ static char buf[sizeof("0000.000000s")];
+ g_snprintf(buf, sizeof(buf), "%u.%06us", i / 1000000, i % 1000000);
+ return buf;
+}
- if (tvb_get_guint8(tvb, 0) != 42)
- return 0;
- version = tvb_get_guint8(tvb, 1);
+static int
+dissect_babel_subtlvs(tvbuff_t * tvb, guint8 type, guint8 beg, guint8 end,
+ proto_tree *message_tree)
+{
+ proto_tree *channel_tree = NULL;
+ proto_item *sub_item;
+ guint8 subtype, sublen;
+ int i = 0;
+
+ while(beg < end) {
+ proto_tree *subtlv_tree = NULL;
+ subtype = tvb_get_guint8(tvb, beg);
+ sublen = tvb_get_guint8(tvb, beg+1);
+
+ sub_item =
+ proto_tree_add_uint_format(message_tree, hf_babel_subtlv,
+ tvb, beg, sublen, subtype,
+ "Sub TLV %s (%u)",
+ val_to_str_const(subtype, subtlvs, "unknown"),
+ subtype);
+
+ if (message_tree) {
+ subtlv_tree = proto_item_add_subtree(sub_item, ett_subtlv);
+ proto_tree_add_item(subtlv_tree, hf_babel_subtlv_type,
+ tvb, beg+2, 1, ENC_BIG_ENDIAN);
+ }
- col_set_str(pinfo->cinfo, COL_PROTOCOL, "Babel");
- col_set_str(pinfo->cinfo, COL_INFO, "Babel");
+ if(subtype == MESSAGE_SUB_PAD1){
+ beg += sublen;
+ continue;
+ }
+ if ((MANDATORY_FLAG & subtype) != 0) {
+ proto_tree_add_subtree_format(subtlv_tree, tvb, beg+2, sublen,
+ ett_mandatory, NULL, "Mandatory");
+ }
- if (version != 2) {
- col_add_fstr(pinfo->cinfo, COL_INFO, "Version %u", version);
- return 2;
+ switch(subtype) {
+ case MESSAGE_SUB_PADN:
+ break;
+ case MESSAGE_SUB_DIVERSITY: {
+ i = 0;
+ channel_tree = proto_tree_add_subtree_format(subtlv_tree, tvb,
+ beg+2, 0, ett_subtlv,
+ NULL, "Channel");
+ while(i < sublen) {
+ proto_tree_add_item(channel_tree, hf_babel_subtlv_diversity,
+ tvb, beg+2+i, 1, ENC_BIG_ENDIAN);
+ i++;
+ }
+ }
+ break;
+ case MESSAGE_SUB_TIMESTAMP: {
+ if (type == MESSAGE_HELLO) {
+ guint32 t1 = tvb_get_guint32(tvb, beg+2, ENC_BIG_ENDIAN);
+ proto_tree_add_subtree_format(subtlv_tree, tvb, beg+2,
+ sublen, ett_timestamp, NULL,
+ "Timestamp : %s",
+ format_timestamp(t1));
+ } else if (type == MESSAGE_IHU) {
+ guint32 t1 = tvb_get_guint32(tvb, beg+2, ENC_BIG_ENDIAN);
+ guint32 t2 = tvb_get_guint32(tvb, beg+6, ENC_BIG_ENDIAN);
+ proto_tree_add_subtree_format(subtlv_tree, tvb, beg+2,
+ sublen, ett_timestamp, NULL,
+ "Timestamp origin : %s",
+ format_timestamp(t1));
+ proto_tree_add_subtree_format(subtlv_tree, tvb, beg+6,
+ sublen, ett_timestamp, NULL,
+ "Timestamp receive: %s",
+ format_timestamp(t2));
+ } else {
+ proto_tree_add_subtree_format(subtlv_tree, tvb, beg+2, sublen,
+ ett_timestamp, NULL, "Bogus");
+ }
+ }
+ break;
+ }
+ beg += (sublen+2);
}
+ return end-beg;
+}
- if (tree) {
- ti = proto_tree_add_item(tree, proto_babel, tvb, 0, -1, ENC_NA);
- babel_tree = proto_item_add_subtree(ti, ett_babel);
- proto_tree_add_item(babel_tree, hf_babel_magic, tvb, 0, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(babel_tree, hf_babel_version, tvb, 1, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(babel_tree, hf_babel_bodylen,
- tvb, 2, 2, ENC_BIG_ENDIAN);
- }
+/* The following function is used to read the packet body and
+ the packet trailer */
+static int
+dissect_babel_body(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ int offset, guint16 bodylen)
+{
+ proto_item *ti = NULL;
+ unsigned char v4_prefix[16] = {0}, v6_prefix[16] = {0};
+ int i;
- bodylen = tvb_get_ntohs(tvb, 2);
- i = 0;
- while (i < bodylen) {
+ i = offset;
+ while (i-offset < bodylen) {
guint8 type, len = 0, total_length;
proto_tree *message_tree = NULL;
int message = 4 + i;
@@ -250,7 +355,7 @@ dissect_babel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U
col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
val_to_str_const(type, messages, "unknown"));
- ti = proto_tree_add_uint_format(babel_tree, hf_babel_message,
+ ti = proto_tree_add_uint_format(tree, hf_babel_message,
tvb, message, total_length, type,
"Message %s (%u)",
val_to_str_const(type, messages, "unknown"),
@@ -270,7 +375,6 @@ dissect_babel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U
if (tree) {
proto_tree_add_item(message_tree, hf_babel_message_length,
tvb, message + 1, 1, ENC_BIG_ENDIAN);
-
if (type == MESSAGE_PADN) {
} else if (type == MESSAGE_ACK_REQ) {
proto_tree_add_item(message_tree, hf_babel_message_nonce,
@@ -281,10 +385,19 @@ dissect_babel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U
proto_tree_add_item(message_tree, hf_babel_message_nonce,
tvb, message + 2, 2, ENC_BIG_ENDIAN);
} else if (type == MESSAGE_HELLO) {
+ guint8 unicast = tvb_get_guint8(tvb, 2);
+ proto_tree_add_subtree_format(message_tree,
+ tvb, message + 2, 2,
+ ett_unicast, NULL,
+ "Unicast : %u",
+ unicast);
proto_tree_add_item(message_tree, hf_babel_message_seqno,
tvb, message + 4, 2, ENC_BIG_ENDIAN);
proto_tree_add_item(message_tree, hf_babel_message_interval,
tvb, message + 6, 2, ENC_BIG_ENDIAN);
+ if(len > 6)
+ dissect_babel_subtlvs(tvb, type, message + 8,
+ message + 2 + len, message_tree);
} else if (type == MESSAGE_IHU) {
proto_tree *subtree;
unsigned char addr_str[16];
@@ -304,6 +417,9 @@ dissect_babel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U
tvb, message + 2, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(subtree, hf_babel_message_prefix,
tvb, message + 4, len - 2, ENC_NA);
+ if (rc < len - 6)
+ dissect_babel_subtlvs(tvb, type, message + 8 + rc,
+ message + 2 + len, message_tree);
} else if (type == MESSAGE_ROUTER_ID) {
proto_tree_add_item(message_tree, hf_babel_message_routerid,
tvb, message + 4, 8, ENC_NA);
@@ -323,7 +439,6 @@ dissect_babel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U
proto_tree_add_item(subtree, hf_babel_message_prefix,
tvb, message + 4, len - 2, ENC_NA);
} else if (type == MESSAGE_UPDATE) {
-
proto_tree *subtree;
unsigned char p[16];
guint8 ae = tvb_get_guint8(tvb, message + 2);
@@ -364,6 +479,9 @@ dissect_babel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U
tvb, message + 5, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(subtree, hf_babel_message_prefix,
tvb, message + 12, len - 10, ENC_NA);
+ if (((guint8)rc) < len - 10)
+ dissect_babel_subtlvs(tvb, type, message + 12 + rc,
+ message + 2 + len, message_tree);
} else if (type == MESSAGE_REQUEST) {
proto_tree *subtree;
unsigned char p[16];
@@ -410,13 +528,61 @@ dissect_babel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U
tvb, message + 3, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(subtree, hf_babel_message_prefix,
tvb, message + 16, len - 14, ENC_NA);
+ } else if (type == MESSAGE_PC){
+ proto_tree_add_item(message_tree, hf_babel_message_index,
+ tvb, message + 2, 4, ENC_NA);
}
}
i += len + 2;
}
+ guint8 packet_len = tvb_reported_length(tvb) - bodylen - 4;
+ if ((offset == 0) && (packet_len != 0)) {
+ proto_tree * subtree;
+ subtree = proto_tree_add_subtree_format(tree, tvb, 4+bodylen, packet_len,
+ ett_packet_trailer, NULL,
+ "Packet Trailer (%u)", packet_len);
+ dissect_babel_body(tvb, pinfo, subtree, bodylen, packet_len);
+ }
return i;
}
+static int
+dissect_babel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+{
+ proto_item *ti;
+ proto_tree *babel_tree = NULL;
+ guint8 version;
+ guint16 bodylen;
+
+ if (tvb_captured_length(tvb) < 4)
+ return 0;
+
+ if (tvb_get_guint8(tvb, 0) != 42)
+ return 0;
+ version = tvb_get_guint8(tvb, 1);
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "Babel");
+ col_set_str(pinfo->cinfo, COL_INFO, "Babel");
+
+ if (version != 2) {
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Version %u", version);
+ return 2;
+ }
+
+ if (tree) {
+ ti = proto_tree_add_item(tree, proto_babel, tvb, 0, -1, ENC_NA);
+ babel_tree = proto_item_add_subtree(ti, ett_babel);
+
+ proto_tree_add_item(babel_tree, hf_babel_magic, tvb, 0, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(babel_tree, hf_babel_version, tvb, 1, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(babel_tree, hf_babel_bodylen,
+ tvb, 2, 2, ENC_BIG_ENDIAN);
+ }
+ bodylen = tvb_get_ntohs(tvb, 2);
+ return dissect_babel_body(tvb, pinfo, babel_tree, 0, bodylen);
+
+}
+
void
proto_register_babel(void)
{
@@ -493,12 +659,33 @@ proto_register_babel(void)
{ "Hop Count", "babel.message.hopcount", FT_UINT8, BASE_DEC,
NULL, 0, NULL, HFILL }
},
+ { &hf_babel_message_index,
+ { "Index", "babel.message.index", FT_UINT32, BASE_DEC,
+ NULL, 0, NULL, HFILL }
+ },
+ { &hf_babel_subtlv,
+ { "Sub-TLV", "babel.subtlv", FT_UINT8, BASE_DEC,
+ NULL, 0, "Babel Sub-TLV", HFILL }
+ },
+ { &hf_babel_subtlv_type,
+ { "Sub-TLV Type", "babel.subtlv.type", FT_UINT8, BASE_DEC,
+ VALS(subtlvs), 0, NULL, HFILL }
+ },
+ { &hf_babel_subtlv_diversity,
+ { "Channel", "babel.subtlv.diversity.channel", FT_UINT8, BASE_DEC,
+ NULL, 0, NULL, HFILL }
+ }
};
static gint *ett[] = {
&ett_babel,
&ett_message,
&ett_subtree,
+ &ett_packet_trailer,
+ &ett_unicast,
+ &ett_subtlv,
+ &ett_timestamp,
+ &ett_mandatory
};
proto_babel =