Skip to content

Commit e794525

Browse files
uheiAndersBroman
authored andcommitted
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 <[email protected]> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <[email protected]>
1 parent c888e3a commit e794525

File tree

1 file changed

+279
-8
lines changed

1 file changed

+279
-8
lines changed

epan/dissectors/packet-pim.c

Lines changed: 279 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,31 @@ void proto_reg_handoff_pim(void);
7777
#define PIM_BDIR_DF_BACKOFF 3
7878
#define PIM_BDIR_DF_PASS 4
7979

80+
/* PIM Address Encoding Types */
81+
82+
#define PIM_ADDR_ET_NATIVE 0 /* RFC7761 */
83+
#define PIM_ADDR_ET_NATIVE_JA 1 /* RFC5384 */
84+
85+
#define PIM_JOIN_ATTRIBUTE_TYPE_RPF 0 /* RFC5496 */
86+
#define PIM_JOIN_ATTRIBUTE_TYPE_MVPN 1 /* RFC6513 */
87+
#define PIM_JOIN_ATTRIBUTE_TYPE_MTID 2 /* RFC6420 */
88+
#define PIM_JOIN_ATTRIBUTE_TYPE_PC 3 /* RFC6807 */
89+
#define PIM_JOIN_ATTRIBUTE_TYPE_EX_RPF 4 /* RFC7891 */
90+
#define PIM_JOIN_ATTRIBUTE_TYPE_TA 5 /* RFC8059 */
91+
#define PIM_JOIN_ATTRIBUTE_TYPE_RLOC 6 /* RFC8059 */
92+
93+
#define PIM_GROUP_ADDR_FLAGS_B 0x80
94+
#define PIM_GROUP_ADDR_FLAGS_RESERVED 0x7E
95+
#define PIM_GROUP_ADDR_FLAGS_Z 0x01
96+
97+
#define PIM_SOURCE_ADDR_FLAGS_RESERVED 0xF8
98+
#define PIM_SOURCE_ADDR_FLAGS_S 0x04
99+
#define PIM_SOURCE_ADDR_FLAGS_W 0x02
100+
#define PIM_SOURCE_ADDR_FLAGS_R 0x01
101+
102+
#define PIM_SOURCE_JA_FLAGS_F 0x80
103+
#define PIM_SOURCE_JA_FLAGS_E 0x40
104+
#define PIM_SOURCE_JA_FLAGS_ATTR_TYPE 0x3F
80105

81106
static const value_string pimtypevals[] = {
82107
{ PIM_TYPE_HELLO, "Hello" },
@@ -130,6 +155,23 @@ static const value_string pim_opt_vals[] = {
130155
{ 0, NULL }
131156
};
132157

158+
static const value_string pim_addr_et_vals[] = {
159+
{ PIM_ADDR_ET_NATIVE, "Native"},
160+
{ PIM_ADDR_ET_NATIVE_JA, "Native with Join Attribute"},
161+
{ 0, NULL }
162+
};
163+
164+
static const value_string pim_join_attribute_type_vals[] = {
165+
{ PIM_JOIN_ATTRIBUTE_TYPE_RPF, "RPF Vector TLV"},
166+
{ PIM_JOIN_ATTRIBUTE_TYPE_MVPN, "MVPN Join Attribute"},
167+
{ PIM_JOIN_ATTRIBUTE_TYPE_MTID, "MT-ID Join Attribute"},
168+
{ PIM_JOIN_ATTRIBUTE_TYPE_PC, "Pop-Count"},
169+
{ PIM_JOIN_ATTRIBUTE_TYPE_EX_RPF, "Explicit RPF Vector"},
170+
{ PIM_JOIN_ATTRIBUTE_TYPE_TA, "Transport Attribute"},
171+
{ PIM_JOIN_ATTRIBUTE_TYPE_RLOC, "Receiver RLOC Attribute"},
172+
{ 0, NULL }
173+
};
174+
133175
enum pimv2_addrtype {
134176
pimv2_unicast, pimv2_group, pimv2_source
135177
};
@@ -219,12 +261,34 @@ static int hf_pim_src_flags_w = -1;
219261
static int hf_pim_src_flags_r = -1;
220262
static int hf_pim_src_flags_rsv = -1;
221263
static int hf_pim_mask_len = -1;
264+
static int hf_pim_addr_af = -1;
265+
static int hf_pim_addr_et = -1;
266+
static int hf_pim_unicast_addr_ipv4 = -1;
267+
static int hf_pim_unicast_addr_ipv6 = -1;
268+
static int hf_pim_group = -1;
269+
static int hf_pim_group_addr_flags = -1;
270+
static int hf_pim_group_addr_flags_b = -1;
271+
static int hf_pim_group_addr_flags_reserved = -1;
272+
static int hf_pim_group_addr_flags_z = -1;
273+
static int hf_pim_source_addr_flags = -1;
274+
static int hf_pim_source_addr_flags_reserved = -1;
275+
static int hf_pim_source_addr_flags_s = -1;
276+
static int hf_pim_source_addr_flags_w = -1;
277+
static int hf_pim_source_addr_flags_r = -1;
278+
static int hf_pim_source_join_attribute = -1;
279+
static int hf_pim_source_ja_flags = -1;
280+
static int hf_pim_source_ja_flags_f = -1;
281+
static int hf_pim_source_ja_flags_e = -1;
282+
static int hf_pim_source_ja_flags_attr_type = -1;
283+
static int hf_pim_source_ja_length = -1;
284+
static int hf_pim_source_ja_value = -1;
222285
static int hf_pim_ttl = -1;
223286
static int hf_pim_interval = -1;
224287

225288
static gint ett_pim = -1;
226289
static gint ett_pim_opts = -1;
227290
static gint ett_pim_opt = -1;
291+
static gint ett_pim_addr_flags = -1;
228292

229293
static expert_field ei_pim_cksum = EI_INIT;
230294

@@ -294,6 +358,28 @@ static const gint *pim_src_flags_fields[] = {
294358
NULL
295359
};
296360

361+
static const int *pim_group_addr_flags[] = {
362+
&hf_pim_group_addr_flags_b,
363+
&hf_pim_group_addr_flags_reserved,
364+
&hf_pim_group_addr_flags_z,
365+
NULL
366+
};
367+
368+
static const int *pim_source_addr_flags[] = {
369+
&hf_pim_source_addr_flags_reserved,
370+
&hf_pim_source_addr_flags_s,
371+
&hf_pim_source_addr_flags_w,
372+
&hf_pim_source_addr_flags_r,
373+
NULL
374+
};
375+
376+
static const int *pim_source_ja_flags[] = {
377+
&hf_pim_source_ja_flags_f,
378+
&hf_pim_source_ja_flags_e,
379+
&hf_pim_source_ja_flags_attr_type,
380+
NULL
381+
};
382+
297383
static void
298384
dissect_pimv1_addr(tvbuff_t *tvb, int offset, proto_tree *pim_tree, int hf_ip) {
299385

@@ -647,7 +733,13 @@ dissect_pim_addr(proto_tree* tree, tvbuff_t *tvb, int offset, enum pimv2_addrtyp
647733
ws_in6_addr ipv6;
648734
guint32 ipv4;
649735
proto_item* ti = NULL;
736+
proto_tree* addr_tree = NULL;
737+
proto_tree* ja_tree = NULL;
650738
int len = 0;
739+
int ja_offset = 0;
740+
guint8 ja_eos_type = 0;
741+
guint8 ja_length = 0;
742+
int ja_length_sum = 0;
651743

652744
af = tvb_get_guint8(tvb, offset);
653745
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
659751
}
660752

661753
et = tvb_get_guint8(tvb, offset + 1);
662-
if (et != 0) {
754+
if ((et != PIM_ADDR_ET_NATIVE) && (et != PIM_ADDR_ET_NATIVE_JA)) {
663755
/*
664-
* The only defined encoding type is 0, for the native encoding;
756+
* The only defined encoding type is 0 and 1, for the native encoding
757+
* and native with Join Attribute TLVs;
665758
* again, as addresses don't include a length field, we can't
666759
* even show addresses with a different encoding type as raw
667760
* bytes.
@@ -700,6 +793,17 @@ dissect_pim_addr(proto_tree* tree, tvbuff_t *tvb, int offset, enum pimv2_addrtyp
700793
}
701794
break;
702795
}
796+
addr_tree = proto_item_add_subtree(ti, ett_pim);
797+
proto_tree_add_item(addr_tree, hf_pim_addr_af, tvb, offset, 1, ENC_NA);
798+
proto_tree_add_item(addr_tree, hf_pim_addr_et, tvb, offset+1, 1, ENC_NA);
799+
switch (af) {
800+
case AFNUM_INET:
801+
proto_tree_add_item(addr_tree, hf_pim_unicast_addr_ipv4, tvb, offset+2, 4, ENC_BIG_ENDIAN);
802+
break;
803+
case AFNUM_INET6:
804+
proto_tree_add_item(addr_tree, hf_pim_unicast_addr_ipv6, tvb, offset+2, 16, ENC_NA);
805+
break;
806+
}
703807
*advance = 2 + len;
704808
break;
705809

@@ -737,6 +841,20 @@ dissect_pim_addr(proto_tree* tree, tvbuff_t *tvb, int offset, enum pimv2_addrtyp
737841
proto_item_append_text(ti, "/%u", mask_len);
738842
break;
739843
}
844+
addr_tree = proto_item_add_subtree(ti, ett_pim);
845+
proto_tree_add_item(addr_tree, hf_pim_addr_af, tvb, offset, 1, ENC_NA);
846+
proto_tree_add_item(addr_tree, hf_pim_addr_et, tvb, offset+1, 1, ENC_NA);
847+
proto_tree_add_bitmask(addr_tree, tvb, offset+2, hf_pim_group_addr_flags,
848+
ett_pim_addr_flags, pim_group_addr_flags, ENC_BIG_ENDIAN);
849+
proto_tree_add_item(addr_tree, hf_pim_mask_len, tvb, offset+3, 1, ENC_NA);
850+
switch (af) {
851+
case AFNUM_INET:
852+
proto_tree_add_item(addr_tree, hf_pim_group_ip4, tvb, offset+4, 4, ENC_BIG_ENDIAN);
853+
break;
854+
case AFNUM_INET6:
855+
proto_tree_add_item(addr_tree, hf_pim_group_ip6, tvb, offset+4, 16, ENC_NA);
856+
break;
857+
}
740858
*advance = 4 + len;
741859
break;
742860

@@ -782,7 +900,53 @@ dissect_pim_addr(proto_tree* tree, tvbuff_t *tvb, int offset, enum pimv2_addrtyp
782900
flags & 0x02 ? "W" : "",
783901
flags & 0x01 ? "R" : "");
784902
}
785-
*advance = 4 + len;
903+
addr_tree = proto_item_add_subtree(ti, ett_pim);
904+
proto_tree_add_item(addr_tree, hf_pim_addr_af, tvb, offset, 1, ENC_NA);
905+
proto_tree_add_item(addr_tree, hf_pim_addr_et, tvb, offset+1, 1, ENC_NA);
906+
proto_tree_add_bitmask(addr_tree, tvb, offset+2, hf_pim_source_addr_flags,
907+
ett_pim_addr_flags, pim_source_addr_flags, ENC_BIG_ENDIAN);
908+
proto_tree_add_item(addr_tree, hf_pim_mask_len, tvb, offset+3, 1, ENC_NA);
909+
switch (af) {
910+
case AFNUM_INET:
911+
proto_tree_add_item(addr_tree, hf_pim_source_ip4, tvb, offset+4, 4, ENC_BIG_ENDIAN);
912+
break;
913+
case AFNUM_INET6:
914+
proto_tree_add_item(addr_tree, hf_pim_source_ip6, tvb, offset+4, 16, ENC_NA);
915+
break;
916+
}
917+
918+
if (et == PIM_ADDR_ET_NATIVE_JA) {
919+
ja_offset = offset + 4 + len;
920+
while (((ja_eos_type & 0x40) != 0x40) && (tvb_reported_length_remaining(tvb, ja_offset) >= 2)) {
921+
ja_length = tvb_get_guint8(tvb, ja_offset+1);
922+
ti = proto_tree_add_item(addr_tree, hf_pim_source_join_attribute, tvb, ja_offset, ja_length + 2, ENC_NA);
923+
ja_tree = proto_item_add_subtree(ti, ett_pim);
924+
ja_eos_type = tvb_get_guint8(tvb, ja_offset);
925+
proto_tree_add_bitmask(ja_tree, tvb, ja_offset, hf_pim_source_ja_flags,
926+
ett_pim_addr_flags, pim_source_ja_flags, ENC_BIG_ENDIAN);
927+
proto_item_append_text(ti, ": %s", val_to_str(ja_eos_type & 0x3F, pim_join_attribute_type_vals, "Unknown"));
928+
ja_offset += 1;
929+
proto_tree_add_item(ja_tree, hf_pim_source_ja_length, tvb, ja_offset, 1, ENC_BIG_ENDIAN);
930+
ja_offset += 1;
931+
switch(ja_eos_type & 0x3F) {
932+
case PIM_JOIN_ATTRIBUTE_TYPE_RPF:
933+
if ((ja_length == 6) || (ja_length == 18)) {
934+
int advance_attr;
935+
dissect_pim_addr(ja_tree, tvb, ja_offset, pimv2_unicast, NULL, NULL,
936+
hf_pim_unicast_addr_ipv4, hf_pim_unicast_addr_ipv6, &advance_attr);
937+
} else {
938+
proto_tree_add_item(ja_tree, hf_pim_source_ja_value, tvb, ja_offset, ja_length, ENC_NA);
939+
}
940+
break;
941+
default:
942+
proto_tree_add_item(ja_tree, hf_pim_source_ja_value, tvb, ja_offset, ja_length, ENC_NA);
943+
}
944+
ja_offset += ja_length;
945+
ja_length_sum += (2 + (int)ja_length);
946+
}
947+
}
948+
*advance = 4 + len + ja_length_sum;
949+
786950
break;
787951
default:
788952
return FALSE;
@@ -1123,12 +1287,13 @@ dissect_pim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
11231287
offset += 2;
11241288

11251289
for (i = 0; i < ngroup; i++) {
1126-
if (!dissect_pim_addr(pimopt_tree, tvb, offset, pimv2_group,
1127-
wmem_strdup_printf(wmem_packet_scope(), "Group %d", i), &tigroup,
1290+
tigroup=proto_tree_add_string_format(pimopt_tree, hf_pim_group, tvb, offset, -1, "", "Group %d", i);
1291+
grouptree = proto_item_add_subtree(tigroup, ett_pim);
1292+
if (!dissect_pim_addr(grouptree, tvb, offset, pimv2_group,
1293+
wmem_strdup_printf(wmem_packet_scope(), "Group %d", i), NULL,
11281294
hf_pim_group_ip4, hf_pim_group_ip6, &advance))
11291295
goto breakbreak3;
11301296

1131-
grouptree = proto_item_add_subtree(tigroup, ett_pim);
11321297
offset += advance;
11331298

11341299
njoin = tvb_get_ntohs(tvb, offset);
@@ -1804,12 +1969,118 @@ proto_register_pim(void)
18041969
FT_UINT8, BASE_DEC, NULL, 0x0,
18051970
NULL, HFILL }
18061971
},
1972+
{ &hf_pim_addr_af,
1973+
{ "Address Family", "pim.addr_address_family",
1974+
FT_UINT8, BASE_DEC, VALS(afn_vals), 0x0,
1975+
NULL, HFILL }
1976+
},
1977+
{ &hf_pim_addr_et,
1978+
{ "Encoding Type", "pim.addr_encoding_type",
1979+
FT_UINT8, BASE_DEC, VALS(pim_addr_et_vals), 0x0,
1980+
NULL, HFILL }
1981+
},
1982+
{ &hf_pim_unicast_addr_ipv4,
1983+
{ "Unicast", "pim.unicast",
1984+
FT_IPv4, BASE_NONE, NULL, 0x0,
1985+
NULL, HFILL }
1986+
},
1987+
{ &hf_pim_unicast_addr_ipv6,
1988+
{ "Unicast", "pim.unicast_ipv6",
1989+
FT_IPv6, BASE_NONE, NULL, 0x0,
1990+
NULL, HFILL }
1991+
},
1992+
{ &hf_pim_group,
1993+
{ "Group", "pim.group_set",
1994+
FT_STRING, BASE_NONE, NULL, 0x0,
1995+
NULL, HFILL }
1996+
},
1997+
{ &hf_pim_group_addr_flags,
1998+
{ "Flags", "pim.group_addr.flags",
1999+
FT_UINT8, BASE_HEX, NULL, 0x0,
2000+
NULL, HFILL }
2001+
},
2002+
{ &hf_pim_group_addr_flags_b,
2003+
{ "Bidirectional PIM", "pim.group_addr.flags.b",
2004+
FT_BOOLEAN, 8, TFS(&tfs_set_notset), PIM_GROUP_ADDR_FLAGS_B,
2005+
NULL, HFILL }
2006+
},
2007+
{ &hf_pim_group_addr_flags_reserved,
2008+
{ "Reserved", "pim.group_addr.flags.reserved",
2009+
FT_UINT8, BASE_HEX, NULL, PIM_GROUP_ADDR_FLAGS_RESERVED,
2010+
NULL, HFILL }
2011+
},
2012+
{ &hf_pim_group_addr_flags_z,
2013+
{ "Admin Scope Zone", "pim.group_addr.flags.z",
2014+
FT_BOOLEAN, 8, TFS(&tfs_set_notset), PIM_GROUP_ADDR_FLAGS_Z,
2015+
NULL, HFILL }
2016+
},
2017+
{ &hf_pim_source_addr_flags,
2018+
{ "Flags", "pim.source_addr.flags",
2019+
FT_UINT8, BASE_HEX, NULL, 0x0,
2020+
NULL, HFILL }
2021+
},
2022+
{ &hf_pim_source_addr_flags_reserved,
2023+
{ "Reserved", "pim.source_addr.flags.reserved",
2024+
FT_UINT8, BASE_HEX, NULL, PIM_SOURCE_ADDR_FLAGS_RESERVED,
2025+
NULL, HFILL }
2026+
},
2027+
{ &hf_pim_source_addr_flags_s,
2028+
{ "Sparse", "pim.source_addr.flags.s",
2029+
FT_BOOLEAN, 8, TFS(&tfs_set_notset), PIM_SOURCE_ADDR_FLAGS_S,
2030+
NULL, HFILL }
2031+
},
2032+
{ &hf_pim_source_addr_flags_w,
2033+
{ "WildCard", "pim.source_addr.flags.w",
2034+
FT_BOOLEAN, 8, TFS(&tfs_set_notset), PIM_SOURCE_ADDR_FLAGS_W,
2035+
NULL, HFILL }
2036+
},
2037+
{ &hf_pim_source_addr_flags_r,
2038+
{ "Rendezvous Point Tree", "pim.source_addr.flags.r",
2039+
FT_BOOLEAN, 8, TFS(&tfs_set_notset), PIM_SOURCE_ADDR_FLAGS_R,
2040+
NULL, HFILL }
2041+
},
2042+
{ &hf_pim_source_join_attribute,
2043+
{ "Join Attribute", "pim.source_ja",
2044+
FT_NONE, BASE_NONE, NULL, 0x0,
2045+
NULL, HFILL }
2046+
},
2047+
{ &hf_pim_source_ja_flags,
2048+
{ "Flags", "pim.source_ja.flags",
2049+
FT_UINT8, BASE_HEX, NULL, 0x0,
2050+
NULL, HFILL }
2051+
},
2052+
{ &hf_pim_source_ja_flags_f,
2053+
{ "Forward", "pim.source_ja.flags.f",
2054+
FT_BOOLEAN, 8, TFS(&tfs_set_notset), PIM_SOURCE_JA_FLAGS_F,
2055+
NULL, HFILL }
2056+
},
2057+
{ &hf_pim_source_ja_flags_e,
2058+
{ "End of Attributes", "pim.source_ja.flags.e",
2059+
FT_BOOLEAN, 8, TFS(&tfs_set_notset), PIM_SOURCE_JA_FLAGS_E,
2060+
NULL, HFILL }
2061+
},
2062+
{ &hf_pim_source_ja_flags_attr_type,
2063+
{ "Attribute Type", "pim.source_ja.flags.attr_type",
2064+
FT_UINT8, BASE_DEC, VALS(pim_join_attribute_type_vals), PIM_SOURCE_JA_FLAGS_ATTR_TYPE,
2065+
NULL, HFILL }
2066+
},
2067+
{ &hf_pim_source_ja_length,
2068+
{ "Length", "pim.source_ja.length",
2069+
FT_UINT8, BASE_DEC, NULL, 0x0,
2070+
NULL, HFILL }
2071+
},
2072+
{ &hf_pim_source_ja_value,
2073+
{ "Value", "pim.source_ja.length",
2074+
FT_BYTES, BASE_NONE, NULL, 0x0,
2075+
NULL, HFILL }
2076+
},
18072077
};
18082078

18092079
static gint *ett[] = {
18102080
&ett_pim,
1811-
&ett_pim_opts, /* Tree for all options */
1812-
&ett_pim_opt /* Tree for each option */
2081+
&ett_pim_opts, /* Tree for all options */
2082+
&ett_pim_opt, /* Tree for each option */
2083+
&ett_pim_addr_flags /* Tree for flags */
18132084
};
18142085

18152086
static ei_register_info ei[] = {

0 commit comments

Comments
 (0)