diff options
author | Sawssen Hadded <saw.hadded@gmail.com> | 2019-06-05 16:22:44 +0200 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2019-06-13 22:33:52 +0000 |
commit | b7cb793fdf71ae9eef132a50e7a3560db1dffbf0 (patch) | |
tree | 393c7669c525256f378fe434d2a08b65e6e306ad /epan/dissectors/packet-babel.c | |
parent | e39f2bb5177c36b6d8e4988baa382cf8a10ee869 (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.c | 297 |
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 = |