aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-pim.c
diff options
context:
space:
mode:
authorUli Heilmeier <uh@heilmeier.eu>2020-06-13 14:07:06 +0200
committerAnders Broman <a.broman58@gmail.com>2020-06-15 05:02:37 +0000
commite794525b7a315784f3d65c2e5048a1817538934f (patch)
treeb007d4dc4e1995fb7796cf5ccda46ed7649dd56e /epan/dissectors/packet-pim.c
parentc888e3a4eec76062b24856f88d6e603cb6039865 (diff)
PIM: decoding of address encoding
This commit extends decoding of source/group/unicast addresses as defined in RFC4601 while preserving the existing fields. Furthermore Joint Attributes TLVs as defined in RFC5384 are added for encoded source addresses. Initial decoding of Vector Attribute TLV Format as defined in RFC5496. Bug: 16613 Change-Id: Ie2f142ef2ed48254c8483180eb4b310674d3437b Reviewed-on: https://code.wireshark.org/review/37468 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-pim.c')
-rw-r--r--epan/dissectors/packet-pim.c287
1 files changed, 279 insertions, 8 deletions
diff --git a/epan/dissectors/packet-pim.c b/epan/dissectors/packet-pim.c
index 9c8bfc0074..945060414a 100644
--- a/epan/dissectors/packet-pim.c
+++ b/epan/dissectors/packet-pim.c
@@ -77,6 +77,31 @@ void proto_reg_handoff_pim(void);
#define PIM_BDIR_DF_BACKOFF 3
#define PIM_BDIR_DF_PASS 4
+/* PIM Address Encoding Types */
+
+#define PIM_ADDR_ET_NATIVE 0 /* RFC7761 */
+#define PIM_ADDR_ET_NATIVE_JA 1 /* RFC5384 */
+
+#define PIM_JOIN_ATTRIBUTE_TYPE_RPF 0 /* RFC5496 */
+#define PIM_JOIN_ATTRIBUTE_TYPE_MVPN 1 /* RFC6513 */
+#define PIM_JOIN_ATTRIBUTE_TYPE_MTID 2 /* RFC6420 */
+#define PIM_JOIN_ATTRIBUTE_TYPE_PC 3 /* RFC6807 */
+#define PIM_JOIN_ATTRIBUTE_TYPE_EX_RPF 4 /* RFC7891 */
+#define PIM_JOIN_ATTRIBUTE_TYPE_TA 5 /* RFC8059 */
+#define PIM_JOIN_ATTRIBUTE_TYPE_RLOC 6 /* RFC8059 */
+
+#define PIM_GROUP_ADDR_FLAGS_B 0x80
+#define PIM_GROUP_ADDR_FLAGS_RESERVED 0x7E
+#define PIM_GROUP_ADDR_FLAGS_Z 0x01
+
+#define PIM_SOURCE_ADDR_FLAGS_RESERVED 0xF8
+#define PIM_SOURCE_ADDR_FLAGS_S 0x04
+#define PIM_SOURCE_ADDR_FLAGS_W 0x02
+#define PIM_SOURCE_ADDR_FLAGS_R 0x01
+
+#define PIM_SOURCE_JA_FLAGS_F 0x80
+#define PIM_SOURCE_JA_FLAGS_E 0x40
+#define PIM_SOURCE_JA_FLAGS_ATTR_TYPE 0x3F
static const value_string pimtypevals[] = {
{ PIM_TYPE_HELLO, "Hello" },
@@ -130,6 +155,23 @@ static const value_string pim_opt_vals[] = {
{ 0, NULL }
};
+static const value_string pim_addr_et_vals[] = {
+ { PIM_ADDR_ET_NATIVE, "Native"},
+ { PIM_ADDR_ET_NATIVE_JA, "Native with Join Attribute"},
+ { 0, NULL }
+};
+
+static const value_string pim_join_attribute_type_vals[] = {
+ { PIM_JOIN_ATTRIBUTE_TYPE_RPF, "RPF Vector TLV"},
+ { PIM_JOIN_ATTRIBUTE_TYPE_MVPN, "MVPN Join Attribute"},
+ { PIM_JOIN_ATTRIBUTE_TYPE_MTID, "MT-ID Join Attribute"},
+ { PIM_JOIN_ATTRIBUTE_TYPE_PC, "Pop-Count"},
+ { PIM_JOIN_ATTRIBUTE_TYPE_EX_RPF, "Explicit RPF Vector"},
+ { PIM_JOIN_ATTRIBUTE_TYPE_TA, "Transport Attribute"},
+ { PIM_JOIN_ATTRIBUTE_TYPE_RLOC, "Receiver RLOC Attribute"},
+ { 0, NULL }
+};
+
enum pimv2_addrtype {
pimv2_unicast, pimv2_group, pimv2_source
};
@@ -219,12 +261,34 @@ static int hf_pim_src_flags_w = -1;
static int hf_pim_src_flags_r = -1;
static int hf_pim_src_flags_rsv = -1;
static int hf_pim_mask_len = -1;
+static int hf_pim_addr_af = -1;
+static int hf_pim_addr_et = -1;
+static int hf_pim_unicast_addr_ipv4 = -1;
+static int hf_pim_unicast_addr_ipv6 = -1;
+static int hf_pim_group = -1;
+static int hf_pim_group_addr_flags = -1;
+static int hf_pim_group_addr_flags_b = -1;
+static int hf_pim_group_addr_flags_reserved = -1;
+static int hf_pim_group_addr_flags_z = -1;
+static int hf_pim_source_addr_flags = -1;
+static int hf_pim_source_addr_flags_reserved = -1;
+static int hf_pim_source_addr_flags_s = -1;
+static int hf_pim_source_addr_flags_w = -1;
+static int hf_pim_source_addr_flags_r = -1;
+static int hf_pim_source_join_attribute = -1;
+static int hf_pim_source_ja_flags = -1;
+static int hf_pim_source_ja_flags_f = -1;
+static int hf_pim_source_ja_flags_e = -1;
+static int hf_pim_source_ja_flags_attr_type = -1;
+static int hf_pim_source_ja_length = -1;
+static int hf_pim_source_ja_value = -1;
static int hf_pim_ttl = -1;
static int hf_pim_interval = -1;
static gint ett_pim = -1;
static gint ett_pim_opts = -1;
static gint ett_pim_opt = -1;
+static gint ett_pim_addr_flags = -1;
static expert_field ei_pim_cksum = EI_INIT;
@@ -294,6 +358,28 @@ static const gint *pim_src_flags_fields[] = {
NULL
};
+static const int *pim_group_addr_flags[] = {
+ &hf_pim_group_addr_flags_b,
+ &hf_pim_group_addr_flags_reserved,
+ &hf_pim_group_addr_flags_z,
+ NULL
+};
+
+static const int *pim_source_addr_flags[] = {
+ &hf_pim_source_addr_flags_reserved,
+ &hf_pim_source_addr_flags_s,
+ &hf_pim_source_addr_flags_w,
+ &hf_pim_source_addr_flags_r,
+ NULL
+};
+
+static const int *pim_source_ja_flags[] = {
+ &hf_pim_source_ja_flags_f,
+ &hf_pim_source_ja_flags_e,
+ &hf_pim_source_ja_flags_attr_type,
+ NULL
+};
+
static void
dissect_pimv1_addr(tvbuff_t *tvb, int offset, proto_tree *pim_tree, int hf_ip) {
@@ -647,7 +733,13 @@ dissect_pim_addr(proto_tree* tree, tvbuff_t *tvb, int offset, enum pimv2_addrtyp
ws_in6_addr ipv6;
guint32 ipv4;
proto_item* ti = NULL;
+ proto_tree* addr_tree = NULL;
+ proto_tree* ja_tree = NULL;
int len = 0;
+ int ja_offset = 0;
+ guint8 ja_eos_type = 0;
+ guint8 ja_length = 0;
+ int ja_length_sum = 0;
af = tvb_get_guint8(tvb, offset);
if (af != AFNUM_INET && af != AFNUM_INET6) {
@@ -659,9 +751,10 @@ dissect_pim_addr(proto_tree* tree, tvbuff_t *tvb, int offset, enum pimv2_addrtyp
}
et = tvb_get_guint8(tvb, offset + 1);
- if (et != 0) {
+ if ((et != PIM_ADDR_ET_NATIVE) && (et != PIM_ADDR_ET_NATIVE_JA)) {
/*
- * The only defined encoding type is 0, for the native encoding;
+ * The only defined encoding type is 0 and 1, for the native encoding
+ * and native with Join Attribute TLVs;
* again, as addresses don't include a length field, we can't
* even show addresses with a different encoding type as raw
* bytes.
@@ -700,6 +793,17 @@ dissect_pim_addr(proto_tree* tree, tvbuff_t *tvb, int offset, enum pimv2_addrtyp
}
break;
}
+ addr_tree = proto_item_add_subtree(ti, ett_pim);
+ proto_tree_add_item(addr_tree, hf_pim_addr_af, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(addr_tree, hf_pim_addr_et, tvb, offset+1, 1, ENC_NA);
+ switch (af) {
+ case AFNUM_INET:
+ proto_tree_add_item(addr_tree, hf_pim_unicast_addr_ipv4, tvb, offset+2, 4, ENC_BIG_ENDIAN);
+ break;
+ case AFNUM_INET6:
+ proto_tree_add_item(addr_tree, hf_pim_unicast_addr_ipv6, tvb, offset+2, 16, ENC_NA);
+ break;
+ }
*advance = 2 + len;
break;
@@ -737,6 +841,20 @@ dissect_pim_addr(proto_tree* tree, tvbuff_t *tvb, int offset, enum pimv2_addrtyp
proto_item_append_text(ti, "/%u", mask_len);
break;
}
+ addr_tree = proto_item_add_subtree(ti, ett_pim);
+ proto_tree_add_item(addr_tree, hf_pim_addr_af, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(addr_tree, hf_pim_addr_et, tvb, offset+1, 1, ENC_NA);
+ proto_tree_add_bitmask(addr_tree, tvb, offset+2, hf_pim_group_addr_flags,
+ ett_pim_addr_flags, pim_group_addr_flags, ENC_BIG_ENDIAN);
+ proto_tree_add_item(addr_tree, hf_pim_mask_len, tvb, offset+3, 1, ENC_NA);
+ switch (af) {
+ case AFNUM_INET:
+ proto_tree_add_item(addr_tree, hf_pim_group_ip4, tvb, offset+4, 4, ENC_BIG_ENDIAN);
+ break;
+ case AFNUM_INET6:
+ proto_tree_add_item(addr_tree, hf_pim_group_ip6, tvb, offset+4, 16, ENC_NA);
+ break;
+ }
*advance = 4 + len;
break;
@@ -782,7 +900,53 @@ dissect_pim_addr(proto_tree* tree, tvbuff_t *tvb, int offset, enum pimv2_addrtyp
flags & 0x02 ? "W" : "",
flags & 0x01 ? "R" : "");
}
- *advance = 4 + len;
+ addr_tree = proto_item_add_subtree(ti, ett_pim);
+ proto_tree_add_item(addr_tree, hf_pim_addr_af, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(addr_tree, hf_pim_addr_et, tvb, offset+1, 1, ENC_NA);
+ proto_tree_add_bitmask(addr_tree, tvb, offset+2, hf_pim_source_addr_flags,
+ ett_pim_addr_flags, pim_source_addr_flags, ENC_BIG_ENDIAN);
+ proto_tree_add_item(addr_tree, hf_pim_mask_len, tvb, offset+3, 1, ENC_NA);
+ switch (af) {
+ case AFNUM_INET:
+ proto_tree_add_item(addr_tree, hf_pim_source_ip4, tvb, offset+4, 4, ENC_BIG_ENDIAN);
+ break;
+ case AFNUM_INET6:
+ proto_tree_add_item(addr_tree, hf_pim_source_ip6, tvb, offset+4, 16, ENC_NA);
+ break;
+ }
+
+ if (et == PIM_ADDR_ET_NATIVE_JA) {
+ ja_offset = offset + 4 + len;
+ while (((ja_eos_type & 0x40) != 0x40) && (tvb_reported_length_remaining(tvb, ja_offset) >= 2)) {
+ ja_length = tvb_get_guint8(tvb, ja_offset+1);
+ ti = proto_tree_add_item(addr_tree, hf_pim_source_join_attribute, tvb, ja_offset, ja_length + 2, ENC_NA);
+ ja_tree = proto_item_add_subtree(ti, ett_pim);
+ ja_eos_type = tvb_get_guint8(tvb, ja_offset);
+ proto_tree_add_bitmask(ja_tree, tvb, ja_offset, hf_pim_source_ja_flags,
+ ett_pim_addr_flags, pim_source_ja_flags, ENC_BIG_ENDIAN);
+ proto_item_append_text(ti, ": %s", val_to_str(ja_eos_type & 0x3F, pim_join_attribute_type_vals, "Unknown"));
+ ja_offset += 1;
+ proto_tree_add_item(ja_tree, hf_pim_source_ja_length, tvb, ja_offset, 1, ENC_BIG_ENDIAN);
+ ja_offset += 1;
+ switch(ja_eos_type & 0x3F) {
+ case PIM_JOIN_ATTRIBUTE_TYPE_RPF:
+ if ((ja_length == 6) || (ja_length == 18)) {
+ int advance_attr;
+ dissect_pim_addr(ja_tree, tvb, ja_offset, pimv2_unicast, NULL, NULL,
+ hf_pim_unicast_addr_ipv4, hf_pim_unicast_addr_ipv6, &advance_attr);
+ } else {
+ proto_tree_add_item(ja_tree, hf_pim_source_ja_value, tvb, ja_offset, ja_length, ENC_NA);
+ }
+ break;
+ default:
+ proto_tree_add_item(ja_tree, hf_pim_source_ja_value, tvb, ja_offset, ja_length, ENC_NA);
+ }
+ ja_offset += ja_length;
+ ja_length_sum += (2 + (int)ja_length);
+ }
+ }
+ *advance = 4 + len + ja_length_sum;
+
break;
default:
return FALSE;
@@ -1123,12 +1287,13 @@ dissect_pim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
offset += 2;
for (i = 0; i < ngroup; i++) {
- if (!dissect_pim_addr(pimopt_tree, tvb, offset, pimv2_group,
- wmem_strdup_printf(wmem_packet_scope(), "Group %d", i), &tigroup,
+ tigroup=proto_tree_add_string_format(pimopt_tree, hf_pim_group, tvb, offset, -1, "", "Group %d", i);
+ grouptree = proto_item_add_subtree(tigroup, ett_pim);
+ if (!dissect_pim_addr(grouptree, tvb, offset, pimv2_group,
+ wmem_strdup_printf(wmem_packet_scope(), "Group %d", i), NULL,
hf_pim_group_ip4, hf_pim_group_ip6, &advance))
goto breakbreak3;
- grouptree = proto_item_add_subtree(tigroup, ett_pim);
offset += advance;
njoin = tvb_get_ntohs(tvb, offset);
@@ -1804,12 +1969,118 @@ proto_register_pim(void)
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
+ { &hf_pim_addr_af,
+ { "Address Family", "pim.addr_address_family",
+ FT_UINT8, BASE_DEC, VALS(afn_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pim_addr_et,
+ { "Encoding Type", "pim.addr_encoding_type",
+ FT_UINT8, BASE_DEC, VALS(pim_addr_et_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pim_unicast_addr_ipv4,
+ { "Unicast", "pim.unicast",
+ FT_IPv4, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pim_unicast_addr_ipv6,
+ { "Unicast", "pim.unicast_ipv6",
+ FT_IPv6, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pim_group,
+ { "Group", "pim.group_set",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pim_group_addr_flags,
+ { "Flags", "pim.group_addr.flags",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pim_group_addr_flags_b,
+ { "Bidirectional PIM", "pim.group_addr.flags.b",
+ FT_BOOLEAN, 8, TFS(&tfs_set_notset), PIM_GROUP_ADDR_FLAGS_B,
+ NULL, HFILL }
+ },
+ { &hf_pim_group_addr_flags_reserved,
+ { "Reserved", "pim.group_addr.flags.reserved",
+ FT_UINT8, BASE_HEX, NULL, PIM_GROUP_ADDR_FLAGS_RESERVED,
+ NULL, HFILL }
+ },
+ { &hf_pim_group_addr_flags_z,
+ { "Admin Scope Zone", "pim.group_addr.flags.z",
+ FT_BOOLEAN, 8, TFS(&tfs_set_notset), PIM_GROUP_ADDR_FLAGS_Z,
+ NULL, HFILL }
+ },
+ { &hf_pim_source_addr_flags,
+ { "Flags", "pim.source_addr.flags",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pim_source_addr_flags_reserved,
+ { "Reserved", "pim.source_addr.flags.reserved",
+ FT_UINT8, BASE_HEX, NULL, PIM_SOURCE_ADDR_FLAGS_RESERVED,
+ NULL, HFILL }
+ },
+ { &hf_pim_source_addr_flags_s,
+ { "Sparse", "pim.source_addr.flags.s",
+ FT_BOOLEAN, 8, TFS(&tfs_set_notset), PIM_SOURCE_ADDR_FLAGS_S,
+ NULL, HFILL }
+ },
+ { &hf_pim_source_addr_flags_w,
+ { "WildCard", "pim.source_addr.flags.w",
+ FT_BOOLEAN, 8, TFS(&tfs_set_notset), PIM_SOURCE_ADDR_FLAGS_W,
+ NULL, HFILL }
+ },
+ { &hf_pim_source_addr_flags_r,
+ { "Rendezvous Point Tree", "pim.source_addr.flags.r",
+ FT_BOOLEAN, 8, TFS(&tfs_set_notset), PIM_SOURCE_ADDR_FLAGS_R,
+ NULL, HFILL }
+ },
+ { &hf_pim_source_join_attribute,
+ { "Join Attribute", "pim.source_ja",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pim_source_ja_flags,
+ { "Flags", "pim.source_ja.flags",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pim_source_ja_flags_f,
+ { "Forward", "pim.source_ja.flags.f",
+ FT_BOOLEAN, 8, TFS(&tfs_set_notset), PIM_SOURCE_JA_FLAGS_F,
+ NULL, HFILL }
+ },
+ { &hf_pim_source_ja_flags_e,
+ { "End of Attributes", "pim.source_ja.flags.e",
+ FT_BOOLEAN, 8, TFS(&tfs_set_notset), PIM_SOURCE_JA_FLAGS_E,
+ NULL, HFILL }
+ },
+ { &hf_pim_source_ja_flags_attr_type,
+ { "Attribute Type", "pim.source_ja.flags.attr_type",
+ FT_UINT8, BASE_DEC, VALS(pim_join_attribute_type_vals), PIM_SOURCE_JA_FLAGS_ATTR_TYPE,
+ NULL, HFILL }
+ },
+ { &hf_pim_source_ja_length,
+ { "Length", "pim.source_ja.length",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_pim_source_ja_value,
+ { "Value", "pim.source_ja.length",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
};
static gint *ett[] = {
&ett_pim,
- &ett_pim_opts, /* Tree for all options */
- &ett_pim_opt /* Tree for each option */
+ &ett_pim_opts, /* Tree for all options */
+ &ett_pim_opt, /* Tree for each option */
+ &ett_pim_addr_flags /* Tree for flags */
};
static ei_register_info ei[] = {