@@ -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
81106static 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+
133175enum pimv2_addrtype {
134176 pimv2_unicast , pimv2_group , pimv2_source
135177};
@@ -219,12 +261,34 @@ static int hf_pim_src_flags_w = -1;
219261static int hf_pim_src_flags_r = -1 ;
220262static int hf_pim_src_flags_rsv = -1 ;
221263static 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 ;
222285static int hf_pim_ttl = -1 ;
223286static int hf_pim_interval = -1 ;
224287
225288static gint ett_pim = -1 ;
226289static gint ett_pim_opts = -1 ;
227290static gint ett_pim_opt = -1 ;
291+ static gint ett_pim_addr_flags = -1 ;
228292
229293static 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+
297383static void
298384dissect_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