/src/wireshark/epan/dissectors/packet-pim.c
Line | Count | Source |
1 | | /* packet-pim.c |
2 | | * Routines for PIM disassembly |
3 | | * (c) Copyright Jun-ichiro itojun Hagino <itojun@itojun.org> |
4 | | * |
5 | | * Wireshark - Network traffic analyzer |
6 | | * By Gerald Combs <gerald@wireshark.org> |
7 | | * Copyright 1998 Gerald Combs |
8 | | * |
9 | | * SPDX-License-Identifier: GPL-2.0-or-later |
10 | | */ |
11 | | |
12 | | #include "config.h" |
13 | | |
14 | | #include <epan/packet.h> |
15 | | #include <epan/prefs.h> |
16 | | #include <epan/expert.h> |
17 | | #include <epan/in_cksum.h> |
18 | | #include <epan/to_str.h> |
19 | | #include <epan/tfs.h> |
20 | | #include <wsutil/array.h> |
21 | | #include "packet-iana-data.h" |
22 | | #include "packet-igmp.h" |
23 | | |
24 | | void proto_register_pim(void); |
25 | | void proto_reg_handoff_pim(void); |
26 | | |
27 | 1.14k | #define PIM_TYPE(x) ((x) & 0x0f) |
28 | 510 | #define PIM_VER(x) (((x) & 0xf0) >> 4) |
29 | 6 | #define PIM_BIDIR_SUBTYPE(x) ((x) & 0x0f) |
30 | 161 | #define PIM_SUBTYPE(x) (((x) & 0xf0) >> 4) |
31 | | |
32 | | /* PIM message type */ |
33 | | |
34 | 19 | #define PIM_TYPE_HELLO 0 /* Hello [RFC3973][RFC4601] */ |
35 | 6 | #define PIM_TYPE_REGISTER 1 /* Register [RFC4601] */ |
36 | 164 | #define PIM_TYPE_REGISTER_STOP 2 /* Register Stop [RFC4601] */ |
37 | 3 | #define PIM_TYPE_JOIN_PRUNE 3 /* Join/Prune [RFC3973][RFC4601] */ |
38 | 5 | #define PIM_TYPE_BOOTSTRAP 4 /* Bootstrap [RFC4601] */ |
39 | 1 | #define PIM_TYPE_ASSERT 5 /* Assert [RFC3973][RFC4601] */ |
40 | 12 | #define PIM_TYPE_GRAFT 6 /* Graft [RFC3973] */ |
41 | 43 | #define PIM_TYPE_GRAFT_ACK 7 /* Graft-Ack [RFC3973] */ |
42 | 4 | #define PIM_TYPE_CAND_RP_ADV 8 /* Candidate RP Advertisement [RFC4601] */ |
43 | 7 | #define PIM_TYPE_STATE_REFRESH 9 /* State Refresh [RFC3973] */ |
44 | 168 | #define PIM_TYPE_DF_ELECT 10 /* DF Election [RFC5015] */ |
45 | | #define PIM_TYPE_ECMP_REDIR 11 /* ECMP Redirect [RFC6754] */ |
46 | 174 | #define PIM_TYPE_PFM 12 /* PIM PFM [RFC8364] */ |
47 | 195 | #define PIM_TYPE_PACKED_REGISTER 13 /* PIM PFM [RFC9465] */ |
48 | | |
49 | | /* PIM Message Subtypes */ |
50 | | |
51 | 11 | #define PIM_TYPE_PACKED_NULL_REGISTER 0 /* 13.0 */ |
52 | 11 | #define PIM_TYPE_PACKED_REGISTER_STOP 1 /* 13.1 */ |
53 | | |
54 | | /* PIM Message hello options */ |
55 | | |
56 | 3 | #define PIM_HELLO_HOLD_T 1 /* Hold Time [RFC7761] */ |
57 | 1 | #define PIM_HELLO_LAN_PRUNE_DELAY 2 /* LAN Prune Delay [RFC3973] */ |
58 | | #define PIM_HELLO_LABEL_PARA 17 /* Label Parameters [Dino_Farinacci] */ |
59 | | #define PIM_HELLO_DEPRECATED_18 18 /* Deprecated */ |
60 | 1 | #define PIM_HELLO_DR_PRIORITY 19 /* DR Priority [RFC7761] */ |
61 | 1 | #define PIM_HELLO_GEN_ID 20 /* Generation ID [RFC3973] */ |
62 | 0 | #define PIM_HELLO_STATE_REFRESH 21 /* State-Refresh [RFC3973] */ |
63 | | #define PIM_HELLO_BIDIR_CAPA 22 /* Bidirectional Capable [RFC5015] */ |
64 | | #define PIM_HELLO_VCI_CAPA 23 /* VCI Capability */ |
65 | 1 | #define PIM_HELLO_VAR_ADDR_LST 24 /* variable Address List [RF7761] */ |
66 | | #define PIM_HELLO_VAR_NEIG_LST 25 /* variable Neighbor List TLV */ |
67 | | #define PIM_HELL0_JOIN_ATTR 26 /* Join Attribute [RFC5384] */ |
68 | | #define PIM_HELLO_O_TCP_CAPA 27 /* variable PIM-over-TCP-Capable [RFC6559] */ |
69 | | #define PIM_HELLO_O_SCTP_CAPA 28 /* variable PIM-over-SCTP-Capable [RFC6559] */ |
70 | | #define PIM_HELLO_VAR_POP_COUNT 29 /* variable Pop-Count [RFC6807] */ |
71 | | #define PIM_HELLO_MT_ID 30 /* PIM MT-ID [RFC6420] */ |
72 | | #define PIM_HELLO_INT_ID 31 /* Interface ID [RFC6395] */ |
73 | | #define PIM_HELLO_ECMP_REDIR 32 /* PIM ECMP Redirect Hello Option [RFC6754] */ |
74 | | #define PIM_HELLO_VPC_PEER_ID 33 /* 2 vPC Peer ID */ |
75 | | #define PIM_HELLO_DR_LB_CAPA 34 /* variable DR Load Balancing Capability [RFC8775] */ |
76 | | #define PIM_HELLO_DR_LB_LIST 35 /* variable DR Load Balancing List [RFC8775] */ |
77 | | #define PIM_HELLO_HIER_JP_ATTR 36 /* Hierarchical Join/Prune Attribute [RFC7887] */ |
78 | 1 | #define PIM_HELLO_ADDR_LST 65001 /* Address list, old implementation */ |
79 | | #define PIM_HELLO_RPF_PROXY 65004 /* RPF Proxy Vector (Cisco proprietary) */ |
80 | | |
81 | | /* PIM PFM message */ |
82 | | |
83 | 1 | #define PIM_PFM_GROUP_SOURCE 1 /* Source Group Holdtime [RFC8364] */ |
84 | | |
85 | | |
86 | | /* PIM BIDIR DF election messages */ |
87 | | |
88 | | #define PIM_BDIR_DF_OFFER 1 |
89 | | #define PIM_BDIR_DF_WINNER 2 |
90 | 0 | #define PIM_BDIR_DF_BACKOFF 3 |
91 | 0 | #define PIM_BDIR_DF_PASS 4 |
92 | | |
93 | | /* PIM Address Encoding Types */ |
94 | | |
95 | 175 | #define PIM_ADDR_ET_NATIVE 0 /* RFC7761 */ |
96 | 236 | #define PIM_ADDR_ET_NATIVE_JA 1 /* RFC5384 */ |
97 | | |
98 | | #define PIM_TRANSPORT_MODE_MULTICAST 0 /*RFC8059*/ |
99 | | #define PIM_TRANSPORT_MODE_UNICAST_REPLICATION 1 /*RFC8059*/ |
100 | | |
101 | 391 | #define PIM_JOIN_ATTRIBUTE_TYPE_RPF 0 /* RFC5496 */ |
102 | | #define PIM_JOIN_ATTRIBUTE_TYPE_MVPN 1 /* RFC6513 */ |
103 | | #define PIM_JOIN_ATTRIBUTE_TYPE_MTID 2 /* RFC6420 */ |
104 | | #define PIM_JOIN_ATTRIBUTE_TYPE_PC 3 /* RFC6807 */ |
105 | | #define PIM_JOIN_ATTRIBUTE_TYPE_EX_RPF 4 /* RFC7891 */ |
106 | 94 | #define PIM_JOIN_ATTRIBUTE_TYPE_TA 5 /* RFC8059 */ |
107 | 33 | #define PIM_JOIN_ATTRIBUTE_TYPE_RLOC 6 /* RFC8059 */ |
108 | | |
109 | 14 | #define PIM_GROUP_ADDR_FLAGS_B 0x80 |
110 | 14 | #define PIM_GROUP_ADDR_FLAGS_RESERVED 0x7E |
111 | 14 | #define PIM_GROUP_ADDR_FLAGS_Z 0x01 |
112 | | |
113 | 14 | #define PIM_SOURCE_ADDR_FLAGS_RESERVED 0xF8 |
114 | 14 | #define PIM_SOURCE_ADDR_FLAGS_S 0x04 |
115 | 14 | #define PIM_SOURCE_ADDR_FLAGS_W 0x02 |
116 | 14 | #define PIM_SOURCE_ADDR_FLAGS_R 0x01 |
117 | | |
118 | 14 | #define PIM_SOURCE_JA_FLAGS_F 0x80 |
119 | 14 | #define PIM_SOURCE_JA_FLAGS_E 0x40 |
120 | 14 | #define PIM_SOURCE_JA_FLAGS_ATTR_TYPE 0x3F |
121 | | |
122 | | static const value_string pimtypevals[] = { |
123 | | { PIM_TYPE_HELLO, "Hello" }, |
124 | | { PIM_TYPE_REGISTER, "Register" }, |
125 | | { PIM_TYPE_REGISTER_STOP, "Register-stop" }, |
126 | | { PIM_TYPE_JOIN_PRUNE, "Join/Prune" }, |
127 | | { PIM_TYPE_BOOTSTRAP, "Bootstrap" }, |
128 | | { PIM_TYPE_ASSERT, "Assert" }, |
129 | | { PIM_TYPE_GRAFT, "Graft" }, |
130 | | { PIM_TYPE_GRAFT_ACK, "Graft-Ack" }, |
131 | | { PIM_TYPE_CAND_RP_ADV, "Candidate-RP-Advertisement" }, |
132 | | { PIM_TYPE_STATE_REFRESH, "State-Refresh" }, |
133 | | { PIM_TYPE_DF_ELECT, "DF election"}, |
134 | | { PIM_TYPE_ECMP_REDIR, "ECMP redirect" }, |
135 | | { PIM_TYPE_PFM, "PFM source discovery"}, |
136 | | { PIM_TYPE_PACKED_REGISTER, "Packed Register"}, |
137 | | { 0, NULL } |
138 | | }; |
139 | | |
140 | | /* |
141 | | * List of subtypes for PIM message Type 13. |
142 | | */ |
143 | | static const value_string pimtype13subtypevals[] = { |
144 | | { PIM_TYPE_PACKED_NULL_REGISTER, "Packed Null-Register" }, |
145 | | { PIM_TYPE_PACKED_REGISTER_STOP, "Packed Register-Stop" }, |
146 | | { 0, NULL } |
147 | | }; |
148 | | |
149 | | static const value_string pimbdirdfvals[] = { |
150 | | { PIM_BDIR_DF_OFFER, "offer"}, |
151 | | { PIM_BDIR_DF_WINNER, "DF Winner"}, |
152 | | { PIM_BDIR_DF_BACKOFF, "DF Backoff"}, |
153 | | { PIM_BDIR_DF_PASS, "DF Pass"}, |
154 | | { 0, NULL } |
155 | | }; |
156 | | |
157 | | static const value_string pim_opt_vals[] = { |
158 | | { PIM_HELLO_HOLD_T, "Hold Time" }, |
159 | | { PIM_HELLO_LAN_PRUNE_DELAY, "LAN Prune Delay" }, |
160 | | { PIM_HELLO_LABEL_PARA, "Label Parameters" }, |
161 | | { PIM_HELLO_DEPRECATED_18, "Deprecated" }, |
162 | | { PIM_HELLO_DR_PRIORITY, "DR Priority" }, |
163 | | { PIM_HELLO_GEN_ID, "Generation ID" }, |
164 | | { PIM_HELLO_STATE_REFRESH, "State-Refresh" }, |
165 | | { PIM_HELLO_BIDIR_CAPA, "Bidirectional Capable" }, |
166 | | { PIM_HELLO_VCI_CAPA, "VCI Capability" }, |
167 | | { PIM_HELLO_VAR_ADDR_LST, "Address List" }, |
168 | | { PIM_HELLO_VAR_NEIG_LST, "Neighbor List TLV" }, |
169 | | { PIM_HELL0_JOIN_ATTR, "Join Attribute" }, |
170 | | { PIM_HELLO_O_TCP_CAPA, "PIM-over-TCP-Capable" }, |
171 | | { PIM_HELLO_O_SCTP_CAPA, "PIM-over-SCTP-Capable" }, |
172 | | { PIM_HELLO_VAR_POP_COUNT, "Pop-Count" }, |
173 | | { PIM_HELLO_MT_ID, "PIM MT-ID" }, |
174 | | { PIM_HELLO_INT_ID, "Interface ID" }, |
175 | | { PIM_HELLO_ECMP_REDIR, "PIM ECMP Redirect Hello Option" }, |
176 | | { PIM_HELLO_VPC_PEER_ID, "vPC Peer ID" }, |
177 | | { PIM_HELLO_DR_LB_CAPA, "DR Load Balancing Capability" }, |
178 | | { PIM_HELLO_DR_LB_LIST, "DR Load Balancing List" }, |
179 | | { PIM_HELLO_HIER_JP_ATTR, "Hierarchical Join/Prune Attribute" }, |
180 | | { PIM_HELLO_ADDR_LST, "Address list, old implementation" }, |
181 | | { PIM_HELLO_RPF_PROXY, "RPF Proxy Vector (Cisco proprietary)" }, |
182 | | { 0, NULL } |
183 | | }; |
184 | | |
185 | | static const value_string pim_opt_vals1[] = { |
186 | | { PIM_PFM_GROUP_SOURCE, "Group Source Holdtime TLV" }, |
187 | | { 0, NULL } |
188 | | }; |
189 | | |
190 | | |
191 | | |
192 | | static const value_string pim_addr_et_vals[] = { |
193 | | { PIM_ADDR_ET_NATIVE, "Native"}, |
194 | | { PIM_ADDR_ET_NATIVE_JA, "Native with Join Attribute"}, |
195 | | { 0, NULL } |
196 | | }; |
197 | | |
198 | | static const value_string attribute_transport_mode[] = { |
199 | | {PIM_TRANSPORT_MODE_UNICAST_REPLICATION, "Unicast Replication"}, |
200 | | {PIM_TRANSPORT_MODE_MULTICAST, "Multicast"}, |
201 | | {0, NULL}}; |
202 | | |
203 | | static const value_string pim_join_attribute_type_vals[] = { |
204 | | { PIM_JOIN_ATTRIBUTE_TYPE_RPF, "RPF Vector TLV"}, |
205 | | { PIM_JOIN_ATTRIBUTE_TYPE_MVPN, "MVPN Join Attribute"}, |
206 | | { PIM_JOIN_ATTRIBUTE_TYPE_MTID, "MT-ID Join Attribute"}, |
207 | | { PIM_JOIN_ATTRIBUTE_TYPE_PC, "Pop-Count"}, |
208 | | { PIM_JOIN_ATTRIBUTE_TYPE_EX_RPF, "Explicit RPF Vector"}, |
209 | | { PIM_JOIN_ATTRIBUTE_TYPE_TA, "Transport Attribute"}, |
210 | | { PIM_JOIN_ATTRIBUTE_TYPE_RLOC, "Receiver RLOC Attribute"}, |
211 | | { 0, NULL } |
212 | | }; |
213 | | |
214 | | enum pimv2_addrtype { |
215 | | pimv2_unicast, pimv2_group, pimv2_source |
216 | | }; |
217 | | |
218 | | static int proto_pim; |
219 | | static int hf_pim_version; |
220 | | static int hf_pim_type; |
221 | | static int hf_pim_code; |
222 | | static int hf_pim_igmp_type; |
223 | | static int hf_pim_df_elect_subtype; |
224 | | static int hf_pim_df_elect_rsvd; |
225 | | static int hf_pim_cksum; |
226 | | static int hf_pim_cksum_status; |
227 | | static int hf_pim_res_bytes; |
228 | | static int hf_pim_reg_stop_p_bit; |
229 | | static int hf_pim_type_13_subtype; |
230 | | static int hf_pim_type_13_flagbits; |
231 | | /* PIM Hello options (RFC 4601, section 4.9.2 and RFC 3973, section 4.7.5) */ |
232 | | static int hf_pim_option; |
233 | | static int hf_pim_optiontype; |
234 | | static int hf_pim_optionlength; |
235 | | static int hf_pim_optionvalue; |
236 | | static int hf_pim_register_flag; |
237 | | static int hf_pim_register_flag_border; |
238 | | static int hf_pim_register_flag_null_register; |
239 | | static int hf_pim_mode; |
240 | | static int hf_pim_holdtime; |
241 | | static int hf_pim_holdtime_t; |
242 | | static int hf_pim_numgroups; |
243 | | static int hf_pim_numjoins; |
244 | | static int hf_pim_numprunes; |
245 | | static int hf_pim_t; |
246 | | static int hf_pim_propagation_delay; |
247 | | static int hf_pim_override_interval; |
248 | | static int hf_pim_dr_priority; |
249 | | static int hf_pim_generation_id; |
250 | | static int hf_pim_state_refresh_version; |
251 | | static int hf_pim_state_refresh_interval; |
252 | | static int hf_pim_state_refresh_reserved; |
253 | | /* Assert fields */ |
254 | | static int hf_pim_rpt; |
255 | | static int hf_pim_metric_pref; |
256 | | static int hf_pim_df_metric_pref; |
257 | | static int hf_pim_metric; |
258 | | static int hf_pim_prune_indicator; |
259 | | static int hf_pim_prune_now; |
260 | | static int hf_pim_assert_override; |
261 | | static int hf_pim_ip_version; |
262 | | static int hf_pim_dummy_header; |
263 | | static int hf_pim_source_ip4; |
264 | | static int hf_pim_source_ip6; |
265 | | static int hf_pim_group_ip4; |
266 | | static int hf_pim_group_ip6; |
267 | | static int hf_pim_group_mask_ip4; |
268 | | static int hf_pim_upstream_neighbor_ip4; |
269 | | static int hf_pim_upstream_neighbor_ip6; |
270 | | static int hf_pim_join_ip4; |
271 | | static int hf_pim_join_ip6; |
272 | | static int hf_pim_prune_ip4; |
273 | | static int hf_pim_prune_ip6; |
274 | | static int hf_pim_address_list_ip4; |
275 | | static int hf_pim_address_list_ip6; |
276 | | static int hf_pim_bsr_ip4; |
277 | | static int hf_pim_bsr_ip6; |
278 | | static int hf_pim_rp_ip4; |
279 | | static int hf_pim_rp_ip6; |
280 | | static int hf_pim_bd_bo_offer_ip4; |
281 | | static int hf_pim_bd_bo_offer_ip6; |
282 | | static int hf_pim_bd_offer_metric_pref; |
283 | | static int hf_pim_bd_offer_metric; |
284 | | static int hf_pim_bd_offer_interval; |
285 | | static int hf_pim_bd_pass_ip4; |
286 | | static int hf_pim_bd_pass_ip6; |
287 | | static int hf_pim_bd_pass_metric_pref; |
288 | | static int hf_pim_bd_pass_metric; |
289 | | static int hf_pim_originator_ip4; |
290 | | static int hf_pim_originator_ip6; |
291 | | static int hf_pim_group_address_ip4; |
292 | | static int hf_pim_fragment_tag; |
293 | | static int hf_pim_hash_mask_len; |
294 | | static int hf_pim_bsr_priority; |
295 | | static int hf_pim_rp_count; |
296 | | static int hf_pim_frp_count; |
297 | | static int hf_pim_priority; |
298 | | static int hf_pim_prefix_count; |
299 | | static int hf_pim_addr_len; |
300 | | static int hf_pim_src_flags_a; |
301 | | static int hf_pim_src_flags_s; |
302 | | static int hf_pim_src_flags_w; |
303 | | static int hf_pim_src_flags_r; |
304 | | static int hf_pim_src_flags_rsv; |
305 | | static int hf_pim_mask_len; |
306 | | static int hf_pim_addr_af; |
307 | | static int hf_pim_addr_et; |
308 | | static int hf_pim_unicast_addr_ipv4; |
309 | | static int hf_pim_unicast_addr_ipv6; |
310 | | static int hf_pim_rloc_addr_ipv4; |
311 | | static int hf_pim_rloc_addr_ipv6; |
312 | | static int hf_pim_attribute_transport_mode; |
313 | | static int hf_pim_group; |
314 | | static int hf_pim_group_addr_flags; |
315 | | static int hf_pim_group_addr_flags_b; |
316 | | static int hf_pim_group_addr_flags_reserved; |
317 | | static int hf_pim_group_addr_flags_z; |
318 | | static int hf_pim_source_addr_flags; |
319 | | static int hf_pim_source_addr_flags_reserved; |
320 | | static int hf_pim_source_addr_flags_s; |
321 | | static int hf_pim_source_addr_flags_w; |
322 | | static int hf_pim_source_addr_flags_r; |
323 | | static int hf_pim_source_join_attribute; |
324 | | static int hf_pim_source_ja_flags; |
325 | | static int hf_pim_source_ja_flags_f; |
326 | | static int hf_pim_source_ja_flags_e; |
327 | | static int hf_pim_source_ja_flags_attr_type; |
328 | | static int hf_pim_source_ja_length; |
329 | | static int hf_pim_source_ja_value; |
330 | | static int hf_pim_ttl; |
331 | | static int hf_pim_interval; |
332 | | static int hf_pim_srcount; |
333 | | static int hf_pim_srcholdt; |
334 | | static int hf_pim_transitivetype; |
335 | | static int hf_pim_optiontype1; |
336 | | static int hf_pfm_no_forward_bit; |
337 | | |
338 | | static int ett_pim; |
339 | | static int ett_pim_opts; |
340 | | static int ett_pim_opt; |
341 | | static int ett_pim_addr_flags; |
342 | | |
343 | | static expert_field ei_pim_cksum; |
344 | | static expert_field ei_pim_unknown_src_type; |
345 | | |
346 | | static dissector_handle_t pim_handle; |
347 | | static dissector_handle_t pimv1_handle; |
348 | | |
349 | | static dissector_handle_t ip_handle; |
350 | | static dissector_handle_t ipv6_handle; |
351 | | |
352 | | static bool use_main_tree = true; |
353 | | |
354 | | /* |
355 | | * The Story About Ping^WPIM: |
356 | | * |
357 | | * http://www.cs.usc.edu/assets/003/83187.pdf |
358 | | * |
359 | | * dated January 11, 1995, entitled "Protocol Independent Multicast (PIM): |
360 | | * Protocol Specification", calls itself draft-ietf-idmr-pim-spec-01, |
361 | | * and is in PostScript-converted-to-PDF form. It describes a protocol |
362 | | * that runs atop IGMP, with a type of 4 for "Router PIM Messages", and |
363 | | * a PIM version number field of 1. |
364 | | * |
365 | | * https://tools.ietf.org/html/draft-ietf-idmr-pim-sm-spec-00 |
366 | | * |
367 | | * dated September 7, 1995, and |
368 | | * |
369 | | * https://tools.ietf.org/html/draft-ietf-idmr-pim-spec-02 |
370 | | * |
371 | | * dated September 7, 1995, both entitled "Protocol Independent Multicast- |
372 | | * Sparse Mode (PIM-SM): Protocol Specification", describe a protocol that |
373 | | * runs atop IGMP, with a type of 4 for "Router PIM Messages", and a PIM |
374 | | * version number field of 2. |
375 | | * |
376 | | * https://tools.ietf.org/html/draft-ietf-idmr-pim-sm-spec-03 |
377 | | * |
378 | | * dated June 6, 1996, and all subsequent drafts, and RFC 2117, dated |
379 | | * June 1997, all entitled "Protocol Independent Multicast-Sparse Mode |
380 | | * (PIM-SM): Protocol Specification", describe a protocol that runs |
381 | | * atop IP, with a protocol number of 103, and with a PIM version number |
382 | | * field of 2. RFC 2117 was obsoleted by RFC 2362, which was obsoleted by |
383 | | * RFC 4601. |
384 | | * |
385 | | * None of them, including the PDF from USC, appear to describe the protocol |
386 | | * dissected by the dissect_pimv1() code. In particular, none have a |
387 | | * packet type value of 8 meaning "Mode"; the PDF from USC doesn't mention |
388 | | * it at all, and subsequent drafts and RFC 2117 have (Candidate-)RP- |
389 | | * Advertisement. Perhaps what's dissected by dissect_pimv1() was |
390 | | * something between the PDF and draft-ietf-idmr-pim-spec-02. |
391 | | * |
392 | | * Looking at the Dense Mode specs, |
393 | | * |
394 | | * https://tools.ietf.org/html/draft-ietf-idmr-pim-dm-spec-02 |
395 | | * |
396 | | * entitled "Protocol Independent Multicast-Dense Mode (PIM-DM): Protocol |
397 | | * Specification", dated September 1995, describes a protocol that runs |
398 | | * atop IGMP, with a type of 4 for "Router PIM Messages", and with a PIM |
399 | | * version number field of 2. |
400 | | * |
401 | | * RFC 3973, entitled "Protocol Independent Multicast-Dense Mode (PIM-DM): |
402 | | * Protocol Specification", also describes a protocol that runs atop IP, |
403 | | * with a protocol number of 103, and with a PIM version number field of 2. |
404 | | */ |
405 | | static int * const pim_src_flags_fields[] = { |
406 | | &hf_pim_src_flags_a, |
407 | | &hf_pim_src_flags_s, |
408 | | &hf_pim_src_flags_w, |
409 | | &hf_pim_src_flags_r, |
410 | | &hf_pim_src_flags_rsv, |
411 | | NULL |
412 | | }; |
413 | | |
414 | | static int * const pim_group_addr_flags[] = { |
415 | | &hf_pim_group_addr_flags_b, |
416 | | &hf_pim_group_addr_flags_reserved, |
417 | | &hf_pim_group_addr_flags_z, |
418 | | NULL |
419 | | }; |
420 | | |
421 | | static int * const pim_source_addr_flags[] = { |
422 | | &hf_pim_source_addr_flags_reserved, |
423 | | &hf_pim_source_addr_flags_s, |
424 | | &hf_pim_source_addr_flags_w, |
425 | | &hf_pim_source_addr_flags_r, |
426 | | NULL |
427 | | }; |
428 | | |
429 | | static int * const pim_source_ja_flags[] = { |
430 | | &hf_pim_source_ja_flags_f, |
431 | | &hf_pim_source_ja_flags_e, |
432 | | &hf_pim_source_ja_flags_attr_type, |
433 | | NULL |
434 | | }; |
435 | | |
436 | | static void |
437 | 495 | dissect_pimv1_addr(tvbuff_t *tvb, int offset, proto_tree *pim_tree, int hf_ip) { |
438 | | |
439 | 495 | proto_tree_add_bitmask_list(pim_tree, tvb, offset, 1, pim_src_flags_fields, ENC_BIG_ENDIAN); |
440 | 495 | offset += 1; |
441 | | |
442 | 495 | proto_tree_add_item(pim_tree, hf_pim_mask_len, tvb, offset, 1, ENC_BIG_ENDIAN); |
443 | 495 | offset += 1; |
444 | | |
445 | 495 | proto_tree_add_item(pim_tree, hf_ip, tvb, offset, 4, ENC_BIG_ENDIAN); |
446 | | |
447 | 495 | } |
448 | | |
449 | | static const value_string pim_type1_vals[] = { |
450 | | { 0, "Query" }, |
451 | | { 1, "Register" }, |
452 | | { 2, "Register-stop" }, |
453 | | { 3, "Join/Prune" }, |
454 | | { 4, "RP-Reachable" }, |
455 | | { 5, "Assert" }, |
456 | | { 6, "Graft" }, |
457 | | { 7, "Graft-Ack" }, |
458 | | { 8, "Mode" }, |
459 | | { 0, NULL }, |
460 | | }; |
461 | | |
462 | | static const value_string pimv1_modevals[] = { |
463 | | { 0, "Dense" }, |
464 | | { 1, "Sparse" }, |
465 | | { 2, "Sparse-Dense" }, |
466 | | { 0, NULL } |
467 | | }; |
468 | | |
469 | | static const value_string pim_ip_version_vals[] = { |
470 | | { 0, "Dummy Header" }, |
471 | | { 4, "IPv4" }, |
472 | | { 6, "IPv6" }, |
473 | | { 0, NULL } |
474 | | }; |
475 | | |
476 | | static const value_string unique_infinity[] = { |
477 | | { 0xffff, "Infinity" }, |
478 | | { 0, NULL } |
479 | | }; |
480 | | |
481 | | static const value_string unique_infinity_t[] = { |
482 | | { 0, "goodbye" }, |
483 | | { 0xffff, "Infinity" }, |
484 | | { 0, NULL } |
485 | | }; |
486 | | |
487 | | /* This function is only called from the IGMP dissector */ |
488 | | static int |
489 | 29 | dissect_pimv1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) { |
490 | 29 | uint32_t pim_type; |
491 | 29 | uint8_t pim_ver; |
492 | 29 | unsigned length, pim_length; |
493 | 29 | vec_t cksum_vec[1]; |
494 | 29 | proto_tree *pim_tree = NULL; |
495 | 29 | proto_item *ti; |
496 | 29 | proto_tree *pimopt_tree = NULL; |
497 | 29 | int offset = 0; |
498 | | |
499 | 29 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "PIMv1"); |
500 | 29 | col_clear(pinfo->cinfo, COL_INFO); |
501 | | |
502 | 29 | ti = proto_tree_add_item(tree, proto_pim, tvb, offset, -1, ENC_NA); |
503 | 29 | pim_tree = proto_item_add_subtree(ti, ett_pim); |
504 | | |
505 | | /* Put IGMP type, 0x14, into the tree */ |
506 | 29 | proto_tree_add_string(pim_tree, hf_pim_igmp_type, tvb, offset, 0, "PIM (0x14)"); |
507 | | |
508 | 29 | offset += 1; |
509 | | |
510 | 29 | proto_tree_add_item_ret_uint(pim_tree, hf_pim_code, tvb, offset, 1, ENC_NA, &pim_type); |
511 | 29 | col_add_str(pinfo->cinfo, COL_INFO, val_to_str(pinfo->pool, pim_type, pim_type1_vals, "Unknown (%u)")); |
512 | 29 | offset += 1; |
513 | | |
514 | 29 | pim_ver = PIM_VER(tvb_get_uint8(tvb, offset + 2)); |
515 | 29 | if (pim_ver != 1) { |
516 | 2 | proto_tree_add_checksum(pim_tree, tvb, offset, hf_pim_cksum, hf_pim_cksum_status, &ei_pim_cksum, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS); |
517 | | |
518 | | /* |
519 | | * Not PIMv1; should we bother dissecting the PIM drafts |
520 | | * with a version number of 2 and with PIM running atop |
521 | | * IGMP? |
522 | | */ |
523 | 2 | offset += 2; |
524 | 2 | proto_tree_add_item(pim_tree, hf_pim_version, tvb, offset, 1, ENC_BIG_ENDIAN); |
525 | 2 | return offset+tvb_reported_length_remaining(tvb, offset); |
526 | 2 | } |
527 | | |
528 | | /* |
529 | | * Well, it's PIM v1, so we can check whether this is a |
530 | | * Register message, and thus can figure out how much to |
531 | | * checksum and whether to make the columns read-only. |
532 | | */ |
533 | 27 | length = tvb_reported_length(tvb); |
534 | 27 | if (pim_type == 1) { |
535 | | /* |
536 | | * Register message - the PIM header is 8 bytes long. |
537 | | * Also set the columns non-writable. Otherwise the IPv4 or |
538 | | * IPv6 dissector for the encapsulated packet that caused |
539 | | * this register will overwrite the PIM info in the columns. |
540 | | * |
541 | | * XXX - that's not what draft-ietf-idmr-pim-spec-01 or |
542 | | * draft-ietf-idmr-pim-spec-02 say; they say that the checksum |
543 | | * covers the entire IGMP message. Later drafts say it |
544 | | * doesn't cover the encapsulated packet; perhaps that's what |
545 | | * was always intended, and they just felt they needed to |
546 | | * explicitly state that. |
547 | | */ |
548 | 1 | pim_length = 8; |
549 | 1 | col_set_writable(pinfo->cinfo, -1, false); |
550 | 26 | } else { |
551 | | /* |
552 | | * Other message - checksum the entire packet. |
553 | | */ |
554 | 26 | pim_length = length; |
555 | 26 | } |
556 | | |
557 | 27 | if (!pinfo->fragmented && length >= pim_length && |
558 | 3 | tvb_captured_length(tvb) >= pim_length) { |
559 | | /* |
560 | | * The packet isn't part of a fragmented datagram and isn't |
561 | | * truncated, so we can checksum it. |
562 | | */ |
563 | 3 | SET_CKSUM_VEC_TVB(cksum_vec[0], tvb, 0, pim_length); |
564 | 3 | proto_tree_add_checksum(pim_tree, tvb, offset, hf_pim_cksum, hf_pim_cksum_status, &ei_pim_cksum, |
565 | 3 | pinfo, in_cksum(&cksum_vec[0], 1), ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY|PROTO_CHECKSUM_IN_CKSUM); |
566 | 24 | } else { |
567 | 24 | proto_tree_add_checksum(pim_tree, tvb, offset, hf_pim_cksum, hf_pim_cksum_status, &ei_pim_cksum, |
568 | 24 | pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS); |
569 | 24 | } |
570 | 27 | offset += 2; |
571 | | |
572 | 27 | proto_tree_add_item(pim_tree, hf_pim_version, tvb, offset, 1, ENC_BIG_ENDIAN); |
573 | 27 | offset += 1; |
574 | | |
575 | | /* reserved stuff */ |
576 | 27 | proto_tree_add_item(pim_tree, hf_pim_res_bytes, tvb, offset, 3, ENC_NA); |
577 | 27 | offset += 3; |
578 | | |
579 | 27 | if (tvb_reported_length_remaining(tvb, offset) > 0) { |
580 | 27 | proto_item *subitem; |
581 | 27 | subitem = proto_tree_add_item(pim_tree, hf_pim_option, tvb, offset, -1, ENC_NA); |
582 | 27 | pimopt_tree = proto_item_add_subtree(subitem, ett_pim_opts); |
583 | 27 | } else |
584 | 0 | return offset; |
585 | | |
586 | | /* version 1 decoder */ |
587 | 27 | switch (pim_type) { |
588 | 1 | case 0: /* query */ |
589 | 1 | { |
590 | 1 | proto_tree_add_item(pimopt_tree, hf_pim_mode, tvb, offset, 1, ENC_BIG_ENDIAN); |
591 | 1 | offset += 2; |
592 | | |
593 | 1 | proto_tree_add_item(pimopt_tree, hf_pim_holdtime, tvb, offset, 2, ENC_BIG_ENDIAN); |
594 | 1 | offset += 2; |
595 | 1 | break; |
596 | 0 | } |
597 | | |
598 | 1 | case 1: /* register */ |
599 | 1 | { |
600 | 1 | uint8_t v_hl; |
601 | 1 | tvbuff_t *next_tvb; |
602 | | |
603 | | /* |
604 | | * The rest of the packet is a multicast data packet. |
605 | | */ |
606 | 1 | next_tvb = tvb_new_subset_remaining(tvb, offset); |
607 | | |
608 | | /* |
609 | | * It's an IP packet - determine whether it's IPv4 or IPv6. |
610 | | */ |
611 | 1 | v_hl = tvb_get_uint8(tvb, offset); |
612 | 1 | proto_tree_add_item(pimopt_tree, hf_pim_ip_version, tvb, offset, 1, ENC_BIG_ENDIAN); |
613 | | |
614 | 1 | switch((v_hl & 0xf0) >> 4) { |
615 | 0 | case 0: /* Null-Register dummy header. |
616 | | * Has the same address family as the encapsulating PIM packet, |
617 | | * e.g. an IPv6 data packet is encapsulated in IPv6 PIM packet. |
618 | | */ |
619 | 0 | ti = proto_tree_add_item(pimopt_tree, hf_pim_dummy_header, tvb, offset, -1, ENC_NA); |
620 | 0 | if (pinfo->src.type == AT_IPv4) { |
621 | 0 | proto_item_append_text(ti, " IPv4"); |
622 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_source_ip4, tvb, offset + 12, 4, ENC_BIG_ENDIAN); |
623 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_group_ip4, tvb, offset + 16, 4, ENC_BIG_ENDIAN); |
624 | 0 | } else if (pinfo->src.type == AT_IPv6) { |
625 | 0 | proto_item_append_text(ti, " IPv6"); |
626 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_source_ip6, tvb, offset + 8, 16, ENC_NA); |
627 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_group_ip6, tvb, offset + 8 + 16, 16, ENC_NA); |
628 | 0 | } else |
629 | 0 | proto_item_append_text(ti, " for an unknown protocol"); |
630 | |
|
631 | 0 | break; |
632 | 1 | case 4: /* IPv4 */ |
633 | 1 | if (use_main_tree) { |
634 | 1 | call_dissector(ip_handle, next_tvb, pinfo, tree); |
635 | 1 | } else { |
636 | 0 | call_dissector(ip_handle, next_tvb, pinfo, pimopt_tree); |
637 | 0 | } |
638 | 1 | break; |
639 | 0 | case 6: /* IPv6 */ |
640 | 0 | if (use_main_tree) { |
641 | 0 | call_dissector(ipv6_handle, next_tvb, pinfo, tree); |
642 | 0 | } else { |
643 | 0 | call_dissector(ipv6_handle, next_tvb, pinfo, pimopt_tree); |
644 | 0 | } |
645 | 0 | break; |
646 | 0 | default: |
647 | 0 | break; |
648 | 1 | } |
649 | 1 | break; |
650 | 1 | } |
651 | | |
652 | 1 | case 2: /* register-stop */ |
653 | 0 | { |
654 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_group_ip4, tvb, offset, 4, ENC_BIG_ENDIAN); |
655 | 0 | offset += 4; |
656 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_source_ip4, tvb, offset, 4, ENC_BIG_ENDIAN); |
657 | 0 | offset += 4; |
658 | 0 | break; |
659 | 1 | } |
660 | | |
661 | 0 | case 3: /* join/prune */ |
662 | 22 | case 6: /* graft */ |
663 | 22 | case 7: /* graft-ack */ |
664 | 22 | { |
665 | 22 | int off; |
666 | 22 | int ngroup, i, njoin, nprune, j; |
667 | 22 | proto_tree *grouptree = NULL; |
668 | 22 | proto_item *tigroup; |
669 | 22 | proto_tree *subtree = NULL; |
670 | 22 | proto_item *tisub; |
671 | | |
672 | 22 | proto_tree_add_item(pimopt_tree, hf_pim_upstream_neighbor_ip4, tvb, offset, 4, ENC_BIG_ENDIAN); |
673 | 22 | offset += 4; |
674 | | |
675 | | /* reserved stuff */ |
676 | 22 | proto_tree_add_item(pim_tree, hf_pim_res_bytes, tvb, offset, 2, ENC_NA); |
677 | 22 | offset += 2; |
678 | | |
679 | 22 | proto_tree_add_item(pimopt_tree, hf_pim_holdtime, tvb, offset, 2, ENC_BIG_ENDIAN); |
680 | 22 | offset += 2; |
681 | | |
682 | | /* reserved stuff */ |
683 | 22 | proto_tree_add_item(pim_tree, hf_pim_res_bytes, tvb, offset, 1, ENC_NA); |
684 | 22 | offset += 1; |
685 | | |
686 | 22 | proto_tree_add_item(pimopt_tree, hf_pim_mask_len, tvb, offset, 1, ENC_NA); |
687 | 22 | offset += 1; |
688 | | |
689 | 22 | proto_tree_add_item(pimopt_tree, hf_pim_addr_len, tvb, offset, 1, ENC_NA); |
690 | 22 | offset += 1; |
691 | | |
692 | 22 | ngroup = tvb_get_uint8(tvb, offset); |
693 | 22 | proto_tree_add_item(pimopt_tree, hf_pim_numgroups, tvb, offset, 1, ENC_BIG_ENDIAN); |
694 | 22 | offset += 1; |
695 | | |
696 | 90 | for (i = 0; i < ngroup; i++) { |
697 | | /* |
698 | | * XXX - does the group address have the length "adr_len" |
699 | | * and the group mask the length "mask_len"? |
700 | | */ |
701 | 68 | tigroup = proto_tree_add_ipv4_format(pimopt_tree, hf_pim_group_ip4, tvb, offset, 4, |
702 | 68 | tvb_get_ipv4(tvb, offset), "Group %d: %s", i, tvb_ip_to_str(pinfo->pool, tvb, offset)); |
703 | 68 | grouptree = proto_item_add_subtree(tigroup, ett_pim); |
704 | 68 | offset += 4; |
705 | | |
706 | 68 | proto_tree_add_ipv4_format(grouptree, hf_pim_group_mask_ip4, tvb, offset, 4, |
707 | 68 | tvb_get_ipv4(tvb, offset), "Group %d Mask: %s", i, tvb_ip_to_str(pinfo->pool, tvb, offset)); |
708 | 68 | offset += 4; |
709 | | |
710 | 68 | njoin = tvb_get_ntohs(tvb, offset); |
711 | 68 | nprune = tvb_get_ntohs(tvb, offset + 2); |
712 | 68 | tisub = proto_tree_add_item(grouptree, hf_pim_numjoins, tvb, |
713 | 68 | offset, 2, ENC_BIG_ENDIAN); |
714 | 68 | subtree = proto_item_add_subtree(tisub, ett_pim); |
715 | 68 | off = offset + 4; |
716 | 316 | for (j = 0; j < njoin; j++) { |
717 | 248 | dissect_pimv1_addr(tvb, off, subtree, hf_pim_join_ip4); |
718 | 248 | off += 6; |
719 | 248 | } |
720 | | |
721 | 68 | tisub = proto_tree_add_item(grouptree, hf_pim_numprunes, tvb, |
722 | 68 | offset + 2, 2, ENC_BIG_ENDIAN); |
723 | 68 | subtree = proto_item_add_subtree(tisub, ett_pim); |
724 | 315 | for (j = 0; j < nprune; j++) { |
725 | 247 | dissect_pimv1_addr(tvb, off, subtree, hf_pim_prune_ip4); |
726 | 247 | off += 6; |
727 | 247 | } |
728 | 68 | offset = off; |
729 | 68 | } |
730 | 22 | break; |
731 | 22 | } |
732 | | |
733 | 0 | case 4: /* rp-reachability */ |
734 | 0 | { |
735 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_group_address_ip4, tvb, offset, 4, ENC_BIG_ENDIAN); |
736 | 0 | offset += 4; |
737 | |
|
738 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_group_mask_ip4, tvb, offset, 4, ENC_BIG_ENDIAN); |
739 | 0 | offset += 4; |
740 | |
|
741 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_rp_ip4, tvb, offset, 4, ENC_BIG_ENDIAN); |
742 | 0 | offset += 4; |
743 | | |
744 | | /* reserved stuff */ |
745 | 0 | proto_tree_add_item(pim_tree, hf_pim_res_bytes, tvb, offset, 2, ENC_NA); |
746 | 0 | offset += 2; |
747 | |
|
748 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_holdtime, tvb, offset, 2, ENC_BIG_ENDIAN); |
749 | 0 | offset += 2; |
750 | 0 | break; |
751 | 22 | } |
752 | | |
753 | 0 | case 5: /* assert */ |
754 | 0 | { |
755 | |
|
756 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_group_address_ip4, tvb, offset, 4, ENC_BIG_ENDIAN); |
757 | 0 | offset += 4; |
758 | |
|
759 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_group_mask_ip4, tvb, offset, 4, ENC_BIG_ENDIAN); |
760 | 0 | offset += 4; |
761 | |
|
762 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_rpt, tvb, offset, 1, ENC_BIG_ENDIAN); |
763 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_metric_pref, tvb, |
764 | 0 | offset, 4, ENC_BIG_ENDIAN); |
765 | 0 | offset += 4; |
766 | |
|
767 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_metric, tvb, offset, 4, ENC_BIG_ENDIAN); |
768 | 0 | offset += 4; |
769 | 0 | break; |
770 | 22 | } |
771 | | |
772 | 3 | default: |
773 | 3 | break; |
774 | 27 | } |
775 | | |
776 | 6 | return offset; |
777 | 27 | } |
778 | | |
779 | | static bool |
780 | | // NOLINTNEXTLINE(misc-no-recursion) |
781 | | dissect_pim_addr(packet_info *pinfo, proto_tree* tree, tvbuff_t *tvb, int offset, enum pimv2_addrtype at, |
782 | 218 | const char* label, proto_item** ret_item, int hf_ip4, int hf_ip6, int *advance) { |
783 | 218 | uint8_t af, et, flags, mask_len, ja_af; |
784 | 218 | ws_in6_addr ipv6; |
785 | 218 | uint32_t ipv4 = 0; |
786 | 218 | proto_item* ti = NULL; |
787 | 218 | proto_tree* addr_tree = NULL; |
788 | 218 | proto_item *rloc_tree = NULL; |
789 | 218 | proto_tree *rloc_sub_tree = NULL; |
790 | 218 | proto_tree* ja_tree = NULL; |
791 | 218 | int len = 0; |
792 | 218 | int ja_offset = 0; |
793 | 218 | uint8_t ja_eos_type = 0; |
794 | 218 | uint8_t ja_length = 0; |
795 | 218 | int ja_length_sum = 0; |
796 | | |
797 | 218 | af = tvb_get_uint8(tvb, offset); |
798 | 218 | if (af != AFNUM_IP && af != AFNUM_IP6) { |
799 | | /* |
800 | | * We don't handle the other formats, and addresses don't include |
801 | | * a length field, so we can't even show them as raw bytes. |
802 | | */ |
803 | 43 | return false; |
804 | 43 | } |
805 | | |
806 | 175 | et = tvb_get_uint8(tvb, offset + 1); |
807 | 175 | if ((et != PIM_ADDR_ET_NATIVE) && (et != PIM_ADDR_ET_NATIVE_JA)) { |
808 | | /* |
809 | | * The only defined encoding type is 0 and 1, for the native encoding |
810 | | * and native with Join Attribute TLVs; |
811 | | * again, as addresses don't include a length field, we can't |
812 | | * even show addresses with a different encoding type as raw |
813 | | * bytes. |
814 | | */ |
815 | 3 | return false; |
816 | 3 | } |
817 | | |
818 | 172 | switch (at) { |
819 | 77 | case pimv2_unicast: |
820 | 77 | switch (af) { |
821 | 52 | case AFNUM_IP: |
822 | 52 | len = 4; |
823 | 52 | ipv4 = tvb_get_ipv4(tvb, offset + 2); |
824 | 52 | if (label) |
825 | 0 | { |
826 | 0 | ti = proto_tree_add_ipv4_format(tree, hf_ip4, tvb, offset, 2 + len, |
827 | 0 | ipv4, "%s: %s", label, tvb_ip_to_str(pinfo->pool, tvb, offset + 2)); |
828 | 0 | } |
829 | 52 | else |
830 | 52 | { |
831 | 52 | ti = proto_tree_add_ipv4(tree, hf_ip4, tvb, offset, 2 + len, ipv4); |
832 | 52 | } |
833 | 52 | break; |
834 | | |
835 | 25 | case AFNUM_IP6: |
836 | 25 | len = 16; |
837 | 25 | tvb_get_ipv6(tvb, offset + 2, &ipv6); |
838 | 25 | if (label) |
839 | 0 | { |
840 | 0 | ti = proto_tree_add_ipv6_format(tree, hf_ip6, tvb, offset, 2 + len, |
841 | 0 | &ipv6, "%s: %s", label, tvb_ip6_to_str(pinfo->pool, tvb, offset + 2)); |
842 | 0 | } |
843 | 25 | else |
844 | 25 | { |
845 | 25 | ti = proto_tree_add_ipv6(tree, hf_ip6, tvb, offset, 2 + len, &ipv6); |
846 | 25 | } |
847 | 25 | break; |
848 | 77 | } |
849 | 77 | addr_tree = proto_item_add_subtree(ti, ett_pim); |
850 | 77 | proto_tree_add_item(addr_tree, hf_pim_addr_af, tvb, offset, 1, ENC_NA); |
851 | 77 | proto_tree_add_item(addr_tree, hf_pim_addr_et, tvb, offset+1, 1, ENC_NA); |
852 | 77 | switch (af) { |
853 | 52 | case AFNUM_IP: |
854 | 52 | proto_tree_add_item(addr_tree, hf_pim_unicast_addr_ipv4, tvb, offset+2, 4, ENC_BIG_ENDIAN); |
855 | 52 | break; |
856 | 25 | case AFNUM_IP6: |
857 | 25 | proto_tree_add_item(addr_tree, hf_pim_unicast_addr_ipv6, tvb, offset+2, 16, ENC_NA); |
858 | 25 | break; |
859 | 77 | } |
860 | 77 | if (et == PIM_ADDR_ET_NATIVE_JA){ |
861 | 52 | ja_offset = offset + len + 2; |
862 | 538 | while (((ja_eos_type & 0x40) != 0x40) && (tvb_reported_length_remaining(tvb, ja_offset) >= 2)){ |
863 | 486 | ja_length = tvb_get_uint8(tvb, ja_offset+1); |
864 | 486 | ti = proto_tree_add_item(addr_tree, hf_pim_source_join_attribute, tvb, ja_offset, ja_length + 2, ENC_NA); |
865 | 486 | ja_tree = proto_item_add_subtree(ti, ett_pim); |
866 | 486 | ja_eos_type = tvb_get_uint8(tvb, ja_offset); |
867 | 486 | proto_tree_add_bitmask(ja_tree, tvb, ja_offset, hf_pim_source_ja_flags, |
868 | 486 | ett_pim_addr_flags, pim_source_ja_flags, ENC_BIG_ENDIAN); |
869 | 486 | proto_item_append_text(ti, ": %s", val_to_str_const(ja_eos_type & 0x3F, pim_join_attribute_type_vals, "Unknown")); |
870 | 486 | ja_offset += 1; |
871 | 486 | proto_tree_add_item(ja_tree, hf_pim_source_ja_length, tvb, ja_offset, 1, ENC_BIG_ENDIAN); |
872 | 486 | ja_offset += 1; |
873 | 486 | switch(ja_eos_type & 0x3F){ |
874 | 94 | case PIM_JOIN_ATTRIBUTE_TYPE_TA: |
875 | 94 | proto_tree_add_item(ja_tree, hf_pim_attribute_transport_mode, tvb, ja_offset, 1, ENC_NA); |
876 | 94 | break; |
877 | 11 | case PIM_JOIN_ATTRIBUTE_TYPE_RLOC: |
878 | 11 | ja_af = tvb_get_uint8(tvb, offset); |
879 | 11 | switch(ja_af) { |
880 | 8 | case AFNUM_IP: |
881 | 8 | rloc_tree = proto_tree_add_ipv4_format(ja_tree, hf_ip4, tvb, ja_offset, ja_length, |
882 | 8 | ipv4, "RLOC: %s", tvb_ip_to_str(pinfo->pool, tvb, ja_offset+ 1)); |
883 | 8 | rloc_sub_tree = proto_item_add_subtree(rloc_tree, ett_pim); |
884 | 8 | proto_tree_add_item(rloc_sub_tree, hf_pim_addr_af, tvb, ja_offset, 1, ENC_NA); |
885 | 8 | proto_tree_add_item(rloc_sub_tree, hf_pim_rloc_addr_ipv4, tvb, ja_offset + 1, 4, ENC_BIG_ENDIAN); |
886 | 8 | break; |
887 | 3 | case AFNUM_IP6: |
888 | 3 | rloc_tree = proto_tree_add_ipv6_format(ja_tree, hf_ip6, tvb, ja_offset, ja_length, |
889 | 3 | &ipv6, "RLOC: %s", tvb_ip_to_str(pinfo->pool, tvb, ja_offset+ 1)); |
890 | 3 | rloc_sub_tree = proto_item_add_subtree(rloc_tree, ett_pim); |
891 | 3 | proto_tree_add_item(rloc_sub_tree, hf_pim_addr_af, tvb, ja_offset, 1, ENC_NA); |
892 | 3 | proto_tree_add_item(rloc_sub_tree, hf_pim_rloc_addr_ipv6, tvb, ja_offset + 1, 16, ENC_NA); |
893 | 3 | break; |
894 | 11 | } |
895 | 11 | break; |
896 | 381 | default: |
897 | 381 | break; |
898 | 486 | } |
899 | 486 | ja_offset += ja_length; |
900 | 486 | ja_length_sum += (2 + (int)ja_length); |
901 | 486 | } |
902 | 52 | *advance = 2 + len + ja_length_sum; |
903 | 52 | break; |
904 | 52 | } |
905 | 25 | *advance = 2 + len; |
906 | 25 | break; |
907 | | |
908 | 49 | case pimv2_group: |
909 | 49 | mask_len = tvb_get_uint8(tvb, offset + 3); |
910 | 49 | switch (af) { |
911 | 47 | case AFNUM_IP: |
912 | 47 | len = 4; |
913 | 47 | ipv4 = tvb_get_ipv4(tvb, offset + 4); |
914 | 47 | if (label) |
915 | 41 | { |
916 | 41 | ti = proto_tree_add_ipv4_format(tree, hf_ip4, tvb, offset, 4 + len, |
917 | 41 | ipv4, "%s: %s", label, tvb_ip_to_str(pinfo->pool, tvb, offset + 4)); |
918 | 41 | } |
919 | 6 | else |
920 | 6 | { |
921 | 6 | ti = proto_tree_add_ipv4(tree, hf_ip4, tvb, offset, 4 + len, ipv4); |
922 | 6 | } |
923 | | |
924 | 47 | proto_item_append_text(ti, "/%u", mask_len); |
925 | 47 | break; |
926 | | |
927 | 2 | case AFNUM_IP6: |
928 | 2 | len = 16; |
929 | 2 | tvb_get_ipv6(tvb, offset + 4, &ipv6); |
930 | 2 | if (label) |
931 | 1 | { |
932 | 1 | ti = proto_tree_add_ipv6_format(tree, hf_ip6, tvb, offset, 4 + len, |
933 | 1 | &ipv6, "%s: %s", label, tvb_ip6_to_str(pinfo->pool, tvb, offset + 4)); |
934 | 1 | } |
935 | 1 | else |
936 | 1 | { |
937 | 1 | ti = proto_tree_add_ipv6(tree, hf_ip6, tvb, offset, 4 + len, &ipv6); |
938 | 1 | } |
939 | 2 | proto_item_append_text(ti, "/%u", mask_len); |
940 | 2 | break; |
941 | 49 | } |
942 | 49 | addr_tree = proto_item_add_subtree(ti, ett_pim); |
943 | 49 | proto_tree_add_item(addr_tree, hf_pim_addr_af, tvb, offset, 1, ENC_NA); |
944 | 49 | proto_tree_add_item(addr_tree, hf_pim_addr_et, tvb, offset+1, 1, ENC_NA); |
945 | 49 | proto_tree_add_bitmask(addr_tree, tvb, offset+2, hf_pim_group_addr_flags, |
946 | 49 | ett_pim_addr_flags, pim_group_addr_flags, ENC_BIG_ENDIAN); |
947 | 49 | proto_tree_add_item(addr_tree, hf_pim_mask_len, tvb, offset+3, 1, ENC_NA); |
948 | 49 | switch (af) { |
949 | 47 | case AFNUM_IP: |
950 | 47 | proto_tree_add_item(addr_tree, hf_pim_group_ip4, tvb, offset+4, 4, ENC_BIG_ENDIAN); |
951 | 47 | break; |
952 | 2 | case AFNUM_IP6: |
953 | 2 | proto_tree_add_item(addr_tree, hf_pim_group_ip6, tvb, offset+4, 16, ENC_NA); |
954 | 2 | break; |
955 | 49 | } |
956 | 49 | *advance = 4 + len; |
957 | 49 | break; |
958 | | |
959 | 37 | case pimv2_source: |
960 | 37 | flags = tvb_get_uint8(tvb, offset + 2); |
961 | 37 | mask_len = tvb_get_uint8(tvb, offset + 3); |
962 | 37 | switch (af) { |
963 | 26 | case AFNUM_IP: |
964 | 26 | len = 4; |
965 | 26 | ipv4 = tvb_get_ipv4(tvb, offset + 4); |
966 | 26 | if (label) |
967 | 0 | { |
968 | 0 | ti = proto_tree_add_ipv4_format(tree, hf_ip4, tvb, offset, 4 + len, |
969 | 0 | ipv4, "%s: %s", label, tvb_ip_to_str(pinfo->pool, tvb, offset + 4)); |
970 | 0 | } |
971 | 26 | else |
972 | 26 | { |
973 | 26 | ti = proto_tree_add_ipv4_format_value(tree, hf_ip4, tvb, offset, 4 + len, ipv4, |
974 | 26 | "%s", tvb_ip_to_str(pinfo->pool, tvb, offset + 4)); |
975 | 26 | } |
976 | 26 | proto_item_append_text(ti, "/%u", mask_len); |
977 | 26 | break; |
978 | | |
979 | 11 | case AFNUM_IP6: |
980 | 11 | len = 16; |
981 | 11 | tvb_get_ipv6(tvb, offset + 4, &ipv6); |
982 | 11 | if (label) |
983 | 0 | { |
984 | 0 | ti = proto_tree_add_ipv6_format(tree, hf_ip6, tvb, offset, 4 + len, |
985 | 0 | &ipv6, "%s: %s", label, tvb_ip6_to_str(pinfo->pool, tvb, offset + 4)); |
986 | 0 | } |
987 | 11 | else |
988 | 11 | { |
989 | 11 | ti = proto_tree_add_ipv6_format_value(tree, hf_ip6, tvb, offset, 4 + len, &ipv6, |
990 | 11 | "%s", tvb_ip6_to_str(pinfo->pool, tvb, offset + 4)); |
991 | 11 | } |
992 | 11 | proto_item_append_text(ti, "/%u", mask_len); |
993 | 11 | break; |
994 | 37 | } |
995 | 37 | if (flags) { |
996 | 27 | proto_item_append_text(ti, " (%s%s%s)", |
997 | 27 | flags & 0x04 ? "S" : "", |
998 | 27 | flags & 0x02 ? "W" : "", |
999 | 27 | flags & 0x01 ? "R" : ""); |
1000 | 27 | } |
1001 | 37 | addr_tree = proto_item_add_subtree(ti, ett_pim); |
1002 | 37 | proto_tree_add_item(addr_tree, hf_pim_addr_af, tvb, offset, 1, ENC_NA); |
1003 | 37 | proto_tree_add_item(addr_tree, hf_pim_addr_et, tvb, offset+1, 1, ENC_NA); |
1004 | 37 | proto_tree_add_bitmask(addr_tree, tvb, offset+2, hf_pim_source_addr_flags, |
1005 | 37 | ett_pim_addr_flags, pim_source_addr_flags, ENC_BIG_ENDIAN); |
1006 | 37 | proto_tree_add_item(addr_tree, hf_pim_mask_len, tvb, offset+3, 1, ENC_NA); |
1007 | 37 | switch (af) { |
1008 | 26 | case AFNUM_IP: |
1009 | 26 | proto_tree_add_item(addr_tree, hf_pim_source_ip4, tvb, offset+4, 4, ENC_BIG_ENDIAN); |
1010 | 26 | break; |
1011 | 11 | case AFNUM_IP6: |
1012 | 11 | proto_tree_add_item(addr_tree, hf_pim_source_ip6, tvb, offset+4, 16, ENC_NA); |
1013 | 11 | break; |
1014 | 37 | } |
1015 | | |
1016 | 37 | if (et == PIM_ADDR_ET_NATIVE_JA) { |
1017 | 35 | ja_offset = offset + 4 + len; |
1018 | 820 | while (((ja_eos_type & 0x40) != 0x40) && (tvb_reported_length_remaining(tvb, ja_offset) >= 2)) { |
1019 | 803 | ja_length = tvb_get_uint8(tvb, ja_offset+1); |
1020 | 803 | ti = proto_tree_add_item(addr_tree, hf_pim_source_join_attribute, tvb, ja_offset, ja_length + 2, ENC_NA); |
1021 | 803 | ja_tree = proto_item_add_subtree(ti, ett_pim); |
1022 | 803 | ja_eos_type = tvb_get_uint8(tvb, ja_offset); |
1023 | 803 | proto_tree_add_bitmask(ja_tree, tvb, ja_offset, hf_pim_source_ja_flags, |
1024 | 803 | ett_pim_addr_flags, pim_source_ja_flags, ENC_BIG_ENDIAN); |
1025 | 803 | proto_item_append_text(ti, ": %s", val_to_str_const(ja_eos_type & 0x3F, pim_join_attribute_type_vals, "Unknown")); |
1026 | 803 | ja_offset += 1; |
1027 | 803 | proto_tree_add_item(ja_tree, hf_pim_source_ja_length, tvb, ja_offset, 1, ENC_BIG_ENDIAN); |
1028 | 803 | ja_offset += 1; |
1029 | 803 | switch(ja_eos_type & 0x3F) { |
1030 | 391 | case PIM_JOIN_ATTRIBUTE_TYPE_RPF: |
1031 | 391 | if ((ja_length == 6) || (ja_length == 18)) { |
1032 | 12 | int advance_attr; |
1033 | | // We recurse here, but we'll run out of packet before we run out of stack. |
1034 | 12 | if (!dissect_pim_addr(pinfo, ja_tree, tvb, ja_offset, pimv2_unicast, NULL, NULL, |
1035 | 12 | hf_pim_unicast_addr_ipv4, hf_pim_unicast_addr_ipv6, &advance_attr)) |
1036 | 8 | break; |
1037 | 379 | } else { |
1038 | 379 | proto_tree_add_item(ja_tree, hf_pim_source_ja_value, tvb, ja_offset, ja_length, ENC_NA); |
1039 | 379 | } |
1040 | 383 | break; |
1041 | 383 | case PIM_JOIN_ATTRIBUTE_TYPE_RLOC: |
1042 | 22 | ja_af = tvb_get_uint8(tvb, offset); |
1043 | 22 | switch(ja_af) { |
1044 | 12 | case AFNUM_IP: |
1045 | 12 | rloc_tree = proto_tree_add_ipv4_format(ja_tree, hf_ip4, tvb, ja_offset, ja_length, |
1046 | 12 | ipv4, "RLOC: %s", tvb_ip_to_str(pinfo->pool, tvb, ja_offset+ 1)); |
1047 | 12 | rloc_sub_tree = proto_item_add_subtree(rloc_tree, ett_pim); |
1048 | 12 | proto_tree_add_item(rloc_sub_tree, hf_pim_addr_af, tvb, ja_offset, 1, ENC_NA); |
1049 | 12 | proto_tree_add_item(rloc_sub_tree, hf_pim_rloc_addr_ipv4, tvb, ja_offset + 1, 4, ENC_BIG_ENDIAN); |
1050 | 12 | break; |
1051 | 10 | case AFNUM_IP6: |
1052 | 10 | rloc_tree = proto_tree_add_ipv6_format(ja_tree, hf_ip6, tvb, ja_offset, ja_length, |
1053 | 10 | &ipv6, "RLOC: %s", tvb_ip_to_str(pinfo->pool, tvb, ja_offset+ 1)); |
1054 | 10 | rloc_sub_tree = proto_item_add_subtree(rloc_tree, ett_pim); |
1055 | 10 | proto_tree_add_item(rloc_sub_tree, hf_pim_addr_af, tvb, ja_offset, 1, ENC_NA); |
1056 | 10 | proto_tree_add_item(rloc_sub_tree, hf_pim_rloc_addr_ipv6, tvb, ja_offset + 1, 16, ENC_NA); |
1057 | 10 | break; |
1058 | 22 | } |
1059 | 22 | break; |
1060 | 390 | default: |
1061 | 390 | proto_tree_add_item(ja_tree, hf_pim_source_ja_value, tvb, ja_offset, ja_length, ENC_NA); |
1062 | 803 | } |
1063 | 785 | ja_offset += ja_length; |
1064 | 785 | ja_length_sum += (2 + (int)ja_length); |
1065 | 785 | } |
1066 | 35 | } |
1067 | 19 | *advance = 4 + len + ja_length_sum; |
1068 | | |
1069 | 19 | break; |
1070 | 0 | default: |
1071 | 0 | return false; |
1072 | 172 | } |
1073 | | |
1074 | 145 | if (ret_item != NULL) |
1075 | 0 | *ret_item = ti; |
1076 | | |
1077 | 145 | return true; |
1078 | 172 | } |
1079 | | |
1080 | | |
1081 | | /* |
1082 | | * For PIM v2, see RFC 4601, RFC 3973 and draft-ietf-pim-sm-v2-new-03 |
1083 | | * (when PIM is run over IPv6, the rules for computing the PIM checksum |
1084 | | * from the draft in question, not from RFC 2362, should be used). |
1085 | | */ |
1086 | | static int |
1087 | 161 | dissect_pim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) { |
1088 | 161 | int offset = 0; |
1089 | 161 | uint8_t pim_typever; |
1090 | 161 | uint8_t pim_subtype; |
1091 | 161 | uint8_t pim_bidir_subtype = 0; |
1092 | 161 | unsigned length, pim_length; |
1093 | 161 | vec_t cksum_vec[4]; |
1094 | 161 | uint32_t phdr[2]; |
1095 | 161 | const char *typestr; |
1096 | 161 | proto_tree *pim_tree = NULL; |
1097 | 161 | proto_item *ti; |
1098 | 161 | proto_tree *pimopt_tree = NULL; |
1099 | 161 | proto_item *tiopt; |
1100 | | |
1101 | 161 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "PIM"); |
1102 | 161 | col_clear(pinfo->cinfo, COL_INFO); |
1103 | | |
1104 | 161 | pim_typever = tvb_get_uint8(tvb, 0); |
1105 | 161 | pim_subtype = PIM_SUBTYPE(tvb_get_uint8(tvb, 1)); |
1106 | | |
1107 | 161 | switch (PIM_VER(pim_typever)) { |
1108 | 130 | case 2: |
1109 | 130 | if (PIM_TYPE(pim_typever) < 12) { |
1110 | 99 | typestr = val_to_str(pinfo->pool, PIM_TYPE(pim_typever), pimtypevals, "Unknown (%u)"); |
1111 | 99 | } else if ((PIM_TYPE(pim_typever) == PIM_TYPE_PACKED_REGISTER)) { |
1112 | | /* |
1113 | | * Need only the first 4 bits for subtype as per the new PIM Common header. |
1114 | | */ |
1115 | 13 | typestr = val_to_str(pinfo->pool, pim_subtype, pimtype13subtypevals, "Unknown (%u)"); |
1116 | 18 | } else { |
1117 | 18 | typestr = "Unknown"; |
1118 | 18 | } |
1119 | 130 | break; |
1120 | 0 | case 1: /* PIMv1 - we should never see this */ |
1121 | 30 | default: |
1122 | 30 | typestr = "Unknown"; |
1123 | 30 | break; |
1124 | 161 | } |
1125 | | |
1126 | 160 | col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "PIMv%d", |
1127 | 160 | PIM_VER(pim_typever)); |
1128 | 160 | col_add_str(pinfo->cinfo, COL_INFO, typestr); |
1129 | | |
1130 | 160 | ti = proto_tree_add_item(tree, proto_pim, tvb, offset, -1, ENC_NA); |
1131 | 160 | pim_tree = proto_item_add_subtree(ti, ett_pim); |
1132 | | |
1133 | 160 | proto_tree_add_item(pim_tree, hf_pim_version, tvb, offset, 1, ENC_BIG_ENDIAN); |
1134 | 160 | proto_tree_add_item(pim_tree, hf_pim_type, tvb, offset, 1, ENC_BIG_ENDIAN); |
1135 | 160 | if (PIM_TYPE(pim_typever) == PIM_TYPE_PFM) { |
1136 | 17 | proto_tree_add_item(pim_tree, hf_pfm_no_forward_bit, tvb, offset+1, 1, ENC_BIG_ENDIAN); |
1137 | 17 | } |
1138 | 160 | if (PIM_TYPE(pim_typever) == PIM_TYPE_REGISTER_STOP) { |
1139 | | /* |
1140 | | * [version-4bits][type-4bits][0x01] |
1141 | | */ |
1142 | 15 | proto_tree_add_item(pim_tree, hf_pim_reg_stop_p_bit, tvb, offset+1, 1, ENC_BIG_ENDIAN); |
1143 | 15 | } |
1144 | 160 | if (PIM_TYPE(pim_typever) == PIM_TYPE_DF_ELECT) { |
1145 | 9 | proto_tree_add_item(pim_tree, hf_pim_df_elect_subtype, tvb, offset + 1, 1, ENC_BIG_ENDIAN); |
1146 | 9 | proto_tree_add_item(pim_tree, hf_pim_df_elect_rsvd, tvb, offset + 1, 1, ENC_BIG_ENDIAN); |
1147 | 9 | pim_bidir_subtype = tvb_get_uint8(tvb,offset); |
1148 | 151 | } else if ((PIM_TYPE(pim_typever) == PIM_TYPE_PACKED_REGISTER)) { |
1149 | | /* |
1150 | | * [version-4bits][type-4bits][0x[SubType-4bits][Flagbits-4bits] |
1151 | | */ |
1152 | 15 | proto_tree_add_item(pim_tree, hf_pim_type_13_subtype, tvb, offset+1, 1, ENC_BIG_ENDIAN); |
1153 | 15 | proto_tree_add_item(pim_tree, hf_pim_type_13_flagbits, tvb, offset+1, 1, ENC_BIG_ENDIAN); |
1154 | 136 | } else { |
1155 | 136 | proto_tree_add_item(pim_tree, hf_pim_res_bytes, tvb, offset + 1, 1, ENC_NA); |
1156 | 136 | } |
1157 | | |
1158 | 160 | if (PIM_VER(pim_typever) != 2) { |
1159 | 30 | proto_tree_add_checksum(pim_tree, tvb, offset+2, hf_pim_cksum, hf_pim_cksum_status, &ei_pim_cksum, |
1160 | 30 | pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS); |
1161 | | /* |
1162 | | * We don't know this version, so we don't know how much of the |
1163 | | * packet the checksum covers. |
1164 | | */ |
1165 | 30 | if (tvb_reported_length_remaining(tvb, offset) > 0) { |
1166 | 29 | proto_tree_add_item(pim_tree, hf_pim_option, tvb, offset, -1, ENC_NA); |
1167 | 29 | } |
1168 | 30 | goto done; |
1169 | 30 | } |
1170 | | |
1171 | | /* |
1172 | | * Well, it's PIM v2, so we can check whether this is a Register |
1173 | | * message, and thus can figure out how much to checksum and |
1174 | | * whether to make the columns read-only. |
1175 | | */ |
1176 | 130 | length = tvb_reported_length(tvb); |
1177 | 130 | if (PIM_TYPE(pim_typever) == 1) { |
1178 | | /* |
1179 | | * Register message - the PIM header is 8 bytes long. |
1180 | | * Also set the columns non-writable. Otherwise the IPv4 or |
1181 | | * IPv6 dissector for the encapsulated packet that caused |
1182 | | * this register will overwrite the PIM info in the columns. |
1183 | | */ |
1184 | 7 | pim_length = 8; |
1185 | 7 | col_set_writable(pinfo->cinfo, -1, false); |
1186 | 123 | } else { |
1187 | | /* |
1188 | | * Other message - checksum the entire packet. |
1189 | | */ |
1190 | 123 | pim_length = length; |
1191 | 123 | } |
1192 | 130 | if (!pinfo->fragmented && length >= pim_length && |
1193 | 124 | tvb_captured_length(tvb) >= pim_length) { |
1194 | | /* |
1195 | | * The packet isn't part of a fragmented datagram and isn't |
1196 | | * truncated, so we can checksum it. |
1197 | | */ |
1198 | | |
1199 | 124 | switch (pinfo->src.type) { |
1200 | 67 | case AT_IPv4: |
1201 | 67 | SET_CKSUM_VEC_TVB(cksum_vec[0], tvb, 0, pim_length); |
1202 | 67 | proto_tree_add_checksum(pim_tree, tvb, offset+2, hf_pim_cksum, hf_pim_cksum_status, &ei_pim_cksum, |
1203 | 67 | pinfo, in_cksum(&cksum_vec[0], 1), ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY|PROTO_CHECKSUM_IN_CKSUM); |
1204 | 67 | break; |
1205 | 57 | case AT_IPv6: |
1206 | | /* Set up the fields of the pseudo-header. */ |
1207 | 57 | SET_CKSUM_VEC_PTR(cksum_vec[0], (const uint8_t *)pinfo->src.data, pinfo->src.len); |
1208 | 57 | SET_CKSUM_VEC_PTR(cksum_vec[1], (const uint8_t *)pinfo->dst.data, pinfo->dst.len); |
1209 | 57 | phdr[0] = g_htonl(pim_length); |
1210 | 57 | phdr[1] = g_htonl(IP_PROTO_PIM); |
1211 | 57 | SET_CKSUM_VEC_PTR(cksum_vec[2], (const uint8_t *)&phdr, 8); |
1212 | 57 | SET_CKSUM_VEC_TVB(cksum_vec[3], tvb, 0, pim_length); |
1213 | 57 | proto_tree_add_checksum(pim_tree, tvb, offset+2, hf_pim_cksum, hf_pim_cksum_status, &ei_pim_cksum, |
1214 | 57 | pinfo, in_cksum(&cksum_vec[0], 4), ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY|PROTO_CHECKSUM_IN_CKSUM); |
1215 | 57 | break; |
1216 | 0 | default: |
1217 | | /* PIM is available for IPv4 and IPv6 right now */ |
1218 | 0 | expert_add_info_format(pinfo, ti, &ei_pim_unknown_src_type, |
1219 | 0 | "Unknown/unsupported source type (%u)", |
1220 | 0 | pinfo->src.type); |
1221 | 0 | break; |
1222 | 124 | } |
1223 | 124 | } else { |
1224 | 6 | proto_tree_add_checksum(pim_tree, tvb, offset+2, hf_pim_cksum, hf_pim_cksum_status, &ei_pim_cksum, |
1225 | 6 | pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS); |
1226 | 6 | } |
1227 | 129 | offset += 4; |
1228 | | |
1229 | 129 | if (tvb_reported_length_remaining(tvb, offset) > 0) { |
1230 | 127 | tiopt = proto_tree_add_item(pim_tree, hf_pim_option, tvb, offset, -1, ENC_NA); |
1231 | 127 | pimopt_tree = proto_item_add_subtree(tiopt, ett_pim_opts); |
1232 | 127 | } else |
1233 | 2 | goto done; |
1234 | | |
1235 | | /* version 2 decoder */ |
1236 | 127 | switch (PIM_TYPE(pim_typever)) { |
1237 | 19 | case PIM_TYPE_HELLO: /*hello*/ |
1238 | 19 | { |
1239 | 19 | int opt_count = 0; |
1240 | | |
1241 | 103 | while (tvb_reported_length_remaining(tvb, offset) >= 2) { |
1242 | 98 | uint16_t hello_opt, opt_len; |
1243 | 98 | uint32_t holdtime; |
1244 | 98 | const char* hold_str; |
1245 | 98 | proto_item *opt_item; |
1246 | 98 | proto_tree *opt_tree; |
1247 | | |
1248 | 98 | opt_count++; |
1249 | 98 | hello_opt = tvb_get_ntohs(tvb, offset); |
1250 | 98 | opt_len = tvb_get_ntohs(tvb, offset + 2); |
1251 | 98 | opt_tree = proto_tree_add_subtree_format(pimopt_tree, tvb, offset, 4 + opt_len, |
1252 | 98 | ett_pim_opt, &opt_item, "Option %u: %s", hello_opt, |
1253 | 98 | val_to_str(pinfo->pool, hello_opt, pim_opt_vals, "Unknown: %u")); |
1254 | 98 | proto_tree_add_item(opt_tree, hf_pim_optiontype, tvb, offset, 2, ENC_BIG_ENDIAN); |
1255 | 98 | proto_tree_add_item(opt_tree, hf_pim_optionlength, tvb, offset + 2, 2, ENC_BIG_ENDIAN); |
1256 | | |
1257 | 98 | switch(hello_opt) { |
1258 | 3 | case PIM_HELLO_HOLD_T: /* Hello Hold Time Option */ |
1259 | | |
1260 | 3 | proto_tree_add_item_ret_uint(opt_tree, hf_pim_holdtime_t, tvb, |
1261 | 3 | offset+4, 2, ENC_BIG_ENDIAN, &holdtime); |
1262 | 3 | proto_item_append_text(opt_item, ": %u", holdtime); |
1263 | 3 | hold_str = try_val_to_str(holdtime, unique_infinity_t); |
1264 | 3 | if (hold_str != NULL) |
1265 | 2 | proto_item_append_text(opt_item, " (%s)", hold_str); |
1266 | | |
1267 | 3 | break; |
1268 | | |
1269 | 1 | case PIM_HELLO_LAN_PRUNE_DELAY: /* LAN Prune Delay Option */ |
1270 | 1 | proto_tree_add_item(opt_tree, hf_pim_t, tvb, offset + 4, 1, ENC_BIG_ENDIAN); |
1271 | 1 | proto_tree_add_item(opt_tree, hf_pim_propagation_delay, tvb, offset + 4, 2, ENC_BIG_ENDIAN); |
1272 | 1 | proto_tree_add_item(opt_tree, hf_pim_override_interval, tvb, offset + 6, 2, ENC_BIG_ENDIAN); |
1273 | 1 | proto_item_append_text(opt_item, |
1274 | 1 | ": T = %u, Propagation Delay = %ums, Override Interval = %ums", |
1275 | 1 | tvb_get_uint8(tvb, offset + 4) & 0x80 ? 1 : 0, |
1276 | 1 | tvb_get_ntohs(tvb, offset + 4) & 0x7fff, |
1277 | 1 | tvb_get_ntohs(tvb, offset + 6)); |
1278 | 1 | break; |
1279 | | |
1280 | 1 | case PIM_HELLO_DR_PRIORITY: /* DR priority */ |
1281 | 1 | proto_tree_add_item(opt_tree, hf_pim_dr_priority, tvb, offset + 4, 4, ENC_BIG_ENDIAN); |
1282 | 1 | proto_item_append_text(opt_item, ": %u", tvb_get_ntohl(tvb, offset + 4)); |
1283 | 1 | break; |
1284 | | |
1285 | 1 | case PIM_HELLO_GEN_ID: /* Generation ID */ |
1286 | 1 | proto_tree_add_item(opt_tree, hf_pim_generation_id, tvb, offset + 4, 4, ENC_BIG_ENDIAN); |
1287 | 1 | proto_item_append_text(opt_item, ": %u", tvb_get_ntohl(tvb, offset + 4)); |
1288 | 1 | break; |
1289 | | |
1290 | 0 | case PIM_HELLO_STATE_REFRESH: /* State Refresh Capable Option */ |
1291 | 0 | proto_tree_add_item(opt_tree, hf_pim_state_refresh_version, tvb, offset + 4, 1, ENC_BIG_ENDIAN); |
1292 | 0 | proto_tree_add_item(opt_tree, hf_pim_state_refresh_interval, tvb, offset + 5, 1, ENC_BIG_ENDIAN); |
1293 | 0 | proto_tree_add_item(opt_tree, hf_pim_state_refresh_reserved, tvb, offset + 6, 2, ENC_BIG_ENDIAN); |
1294 | 0 | proto_item_append_text(opt_item, ": Version = %u, Interval = %us", |
1295 | 0 | tvb_get_uint8(tvb, offset + 4), |
1296 | 0 | tvb_get_uint8(tvb, offset + 5)); |
1297 | 0 | break; |
1298 | | |
1299 | 1 | case PIM_HELLO_VAR_ADDR_LST: /* address list */ |
1300 | 1 | case PIM_HELLO_ADDR_LST: /* address list (old implementations) */ |
1301 | 1 | { |
1302 | 1 | int i; |
1303 | 1 | proto_tree *sub_tree = NULL; |
1304 | | |
1305 | 1 | sub_tree = proto_tree_add_subtree_format(opt_tree, tvb, offset, 4 + opt_len, |
1306 | 1 | ett_pim_opt, NULL, "%sAddress List (%u)", |
1307 | 1 | hello_opt == 65001 ? "old " : "", |
1308 | 1 | hello_opt); |
1309 | 2 | for (i = offset + 4; i < offset + 4 + opt_len; ) { |
1310 | 1 | int advance; |
1311 | 1 | if (!dissect_pim_addr(pinfo, sub_tree, tvb, i, pimv2_unicast, NULL, NULL, |
1312 | 1 | hf_pim_address_list_ip4, hf_pim_address_list_ip6, &advance)) |
1313 | 0 | break; |
1314 | 1 | i += advance; |
1315 | 1 | } |
1316 | 1 | break; |
1317 | 1 | } |
1318 | | |
1319 | 91 | default: |
1320 | 91 | if (opt_len) |
1321 | 26 | proto_tree_add_item(opt_tree, hf_pim_optionvalue, tvb, |
1322 | 26 | offset + 4, opt_len, ENC_NA); |
1323 | 91 | break; |
1324 | 98 | } |
1325 | 84 | offset += 4 + opt_len; |
1326 | 84 | } |
1327 | 5 | proto_item_append_text(tiopt, ": %u", opt_count); |
1328 | 5 | break; |
1329 | 19 | } |
1330 | | |
1331 | 6 | case PIM_TYPE_REGISTER: /* register */ |
1332 | 6 | { |
1333 | 6 | uint8_t v_hl; |
1334 | 6 | tvbuff_t *next_tvb; |
1335 | 6 | proto_tree *flag_tree; |
1336 | 6 | proto_item *tiflag; |
1337 | | |
1338 | 6 | tiflag = proto_tree_add_item(pimopt_tree, hf_pim_register_flag, tvb, offset, 4, ENC_BIG_ENDIAN); |
1339 | 6 | flag_tree = proto_item_add_subtree(tiflag, ett_pim); |
1340 | 6 | proto_tree_add_item(flag_tree, hf_pim_register_flag_border, tvb, offset, 4, ENC_BIG_ENDIAN); |
1341 | 6 | proto_tree_add_item(flag_tree, hf_pim_register_flag_null_register, tvb, offset, 4, ENC_BIG_ENDIAN); |
1342 | 6 | offset += 4; |
1343 | | |
1344 | | /* |
1345 | | * The rest of the packet is a multicast data packet. |
1346 | | */ |
1347 | 6 | next_tvb = tvb_new_subset_remaining(tvb, offset); |
1348 | | |
1349 | | /* |
1350 | | * It's an IP packet - determine whether it's IPv4 or IPv6. |
1351 | | */ |
1352 | 6 | v_hl = tvb_get_uint8(tvb, offset); |
1353 | 6 | proto_tree_add_item(pimopt_tree, hf_pim_ip_version, tvb, offset, 1, ENC_BIG_ENDIAN); |
1354 | | |
1355 | 6 | switch((v_hl & 0xf0) >> 4) { |
1356 | 2 | case 0: /* Null-Register dummy header. |
1357 | | * Has the same address family as the encapsulating PIM packet, |
1358 | | * e.g. an IPv6 data packet is encapsulated in IPv6 PIM packet. |
1359 | | */ |
1360 | 2 | ti = proto_tree_add_item(pimopt_tree, hf_pim_dummy_header, tvb, offset, -1, ENC_NA); |
1361 | 2 | if (pinfo->src.type == AT_IPv4) { |
1362 | 1 | proto_item_append_text(ti, "IPv4"); |
1363 | 1 | proto_tree_add_item(pimopt_tree, hf_pim_source_ip4, tvb, offset + 12, 4, ENC_BIG_ENDIAN); |
1364 | 1 | proto_tree_add_item(pimopt_tree, hf_pim_group_ip4, tvb, offset + 16, 4, ENC_BIG_ENDIAN); |
1365 | 1 | } else if (pinfo->src.type == AT_IPv6) { |
1366 | 1 | proto_item_append_text(ti, "IPv6"); |
1367 | 1 | proto_tree_add_item(pimopt_tree, hf_pim_source_ip6, tvb, offset + 8, 16, ENC_NA); |
1368 | 1 | proto_tree_add_item(pimopt_tree, hf_pim_group_ip6, tvb, offset + 8 + 16, 16, ENC_NA); |
1369 | 1 | } else |
1370 | 0 | proto_item_append_text(ti, "for an unknown protocol"); |
1371 | 2 | break; |
1372 | 0 | case 4: /* IPv4 */ |
1373 | 0 | if (use_main_tree) { |
1374 | 0 | call_dissector(ip_handle, next_tvb, pinfo, tree); |
1375 | 0 | } else { |
1376 | 0 | call_dissector(ip_handle, next_tvb, pinfo, pimopt_tree); |
1377 | 0 | } |
1378 | 0 | break; |
1379 | 1 | case 6: /* IPv6 */ |
1380 | 1 | if (use_main_tree) { |
1381 | 1 | call_dissector(ipv6_handle, next_tvb, pinfo, tree); |
1382 | 1 | } else { |
1383 | 0 | call_dissector(ipv6_handle, next_tvb, pinfo, pimopt_tree); |
1384 | 0 | } |
1385 | 1 | break; |
1386 | 3 | default: |
1387 | 3 | break; |
1388 | 6 | } |
1389 | 4 | break; |
1390 | 6 | } |
1391 | | |
1392 | 4 | case PIM_TYPE_REGISTER_STOP: /* register-stop */ |
1393 | 4 | { |
1394 | 4 | int advance; |
1395 | | |
1396 | 4 | if (!dissect_pim_addr(pinfo, pimopt_tree, tvb, offset, pimv2_group, NULL, NULL, |
1397 | 4 | hf_pim_group_ip4, hf_pim_group_ip6, &advance)) |
1398 | 2 | break; |
1399 | 2 | offset += advance; |
1400 | 2 | if (!dissect_pim_addr(pinfo, pimopt_tree, tvb, offset, pimv2_unicast, NULL, NULL, |
1401 | 2 | hf_pim_source_ip4, hf_pim_source_ip6, &advance)) |
1402 | 1 | break; |
1403 | 1 | break; |
1404 | 2 | } |
1405 | | |
1406 | 3 | case PIM_TYPE_JOIN_PRUNE: /* join/prune */ |
1407 | 12 | case PIM_TYPE_GRAFT: /* graft */ |
1408 | 43 | case PIM_TYPE_GRAFT_ACK: /* graft-ack */ |
1409 | 43 | { |
1410 | 43 | int advance; |
1411 | 43 | int off; |
1412 | 43 | int ngroup, i, njoin, nprune, j; |
1413 | 43 | proto_tree *grouptree = NULL; |
1414 | 43 | proto_item *tigroup; |
1415 | 43 | proto_tree *subtree = NULL; |
1416 | 43 | proto_item *tisub; |
1417 | | |
1418 | 43 | if (!dissect_pim_addr(pinfo, pimopt_tree, tvb, offset, pimv2_unicast, NULL, NULL, |
1419 | 43 | hf_pim_upstream_neighbor_ip4, hf_pim_upstream_neighbor_ip6, &advance)) |
1420 | 6 | break; |
1421 | | |
1422 | 37 | offset += advance; |
1423 | | |
1424 | | /* reserved field */ |
1425 | 37 | proto_tree_add_item(pimopt_tree, hf_pim_res_bytes, tvb, offset, 1, ENC_NA); |
1426 | 37 | offset += 1; |
1427 | | |
1428 | 37 | ngroup = tvb_get_uint8(tvb, offset); |
1429 | 37 | proto_tree_add_item(pimopt_tree, hf_pim_numgroups, tvb, offset, 1, ENC_BIG_ENDIAN); |
1430 | 37 | offset += 1; |
1431 | | |
1432 | 37 | proto_tree_add_item(pimopt_tree, hf_pim_holdtime, tvb, offset, 2, ENC_BIG_ENDIAN); |
1433 | 37 | offset += 2; |
1434 | | |
1435 | 62 | for (i = 0; i < ngroup; i++) { |
1436 | 35 | tigroup=proto_tree_add_string_format(pimopt_tree, hf_pim_group, tvb, offset, -1, "", "Group %d", i); |
1437 | 35 | grouptree = proto_item_add_subtree(tigroup, ett_pim); |
1438 | 35 | if (!dissect_pim_addr(pinfo, grouptree, tvb, offset, pimv2_group, |
1439 | 35 | wmem_strdup_printf(pinfo->pool, "Group %d", i), NULL, |
1440 | 35 | hf_pim_group_ip4, hf_pim_group_ip6, &advance)) |
1441 | 4 | goto breakbreak3; |
1442 | | |
1443 | 31 | offset += advance; |
1444 | | |
1445 | 31 | njoin = tvb_get_ntohs(tvb, offset); |
1446 | 31 | nprune = tvb_get_ntohs(tvb, offset + 2); |
1447 | 31 | tisub = proto_tree_add_item(grouptree, hf_pim_numjoins, tvb, |
1448 | 31 | offset, 2, ENC_BIG_ENDIAN); |
1449 | 31 | subtree = proto_item_add_subtree(tisub, ett_pim); |
1450 | 31 | off = offset + 4; |
1451 | 62 | for (j = 0; j < njoin; j++) { |
1452 | 36 | if (!dissect_pim_addr(pinfo, subtree, tvb, off, pimv2_source, NULL, NULL, |
1453 | 36 | hf_pim_join_ip4, hf_pim_join_ip6, &advance)) |
1454 | 5 | goto breakbreak3; |
1455 | | |
1456 | 31 | off += advance; |
1457 | 31 | } |
1458 | | |
1459 | 26 | tisub = proto_tree_add_item(grouptree, hf_pim_numprunes, tvb, |
1460 | 26 | offset + 2, 2, ENC_BIG_ENDIAN); |
1461 | 26 | subtree = proto_item_add_subtree(tisub, ett_pim); |
1462 | 34 | for (j = 0; j < nprune; j++) { |
1463 | 9 | if (!dissect_pim_addr(pinfo, subtree, tvb, off, pimv2_source, NULL, NULL, |
1464 | 9 | hf_pim_prune_ip4, hf_pim_prune_ip6, &advance)) |
1465 | 1 | goto breakbreak3; |
1466 | | |
1467 | 8 | off += advance; |
1468 | 8 | } |
1469 | 25 | offset = off; |
1470 | 25 | } |
1471 | 27 | breakbreak3: |
1472 | 13 | break; |
1473 | 37 | } |
1474 | | |
1475 | 27 | case PIM_TYPE_BOOTSTRAP: /* bootstrap */ |
1476 | 5 | { |
1477 | 5 | int advance; |
1478 | 5 | int i, j; |
1479 | 5 | int frpcnt; |
1480 | 5 | proto_tree *grouptree = NULL; |
1481 | 5 | proto_item *tigroup; |
1482 | | |
1483 | 5 | proto_tree_add_item(pimopt_tree, hf_pim_fragment_tag, tvb, |
1484 | 5 | offset, 2, ENC_BIG_ENDIAN); |
1485 | 5 | offset += 2; |
1486 | | |
1487 | 5 | proto_tree_add_item(pimopt_tree, hf_pim_hash_mask_len, tvb, offset, 1, ENC_BIG_ENDIAN); |
1488 | 5 | offset += 1; |
1489 | 5 | proto_tree_add_item(pimopt_tree, hf_pim_bsr_priority, tvb, offset, 1, ENC_BIG_ENDIAN); |
1490 | 5 | offset += 1; |
1491 | | |
1492 | 5 | if (!dissect_pim_addr(pinfo, pimopt_tree, tvb, offset, pimv2_unicast, NULL, NULL, |
1493 | 5 | hf_pim_bsr_ip4, hf_pim_bsr_ip6, &advance)) |
1494 | 2 | break; |
1495 | 3 | offset += advance; |
1496 | | |
1497 | 3 | for (i = 0; tvb_reported_length_remaining(tvb, offset) > 0; i++) { |
1498 | 1 | if (!dissect_pim_addr(pinfo, pimopt_tree, tvb, offset, pimv2_group, |
1499 | 1 | wmem_strdup_printf(pinfo->pool, "Group %d", i), &tigroup, |
1500 | 1 | hf_pim_group_ip4, hf_pim_group_ip6, &advance)) |
1501 | 1 | goto breakbreak4; |
1502 | | |
1503 | 0 | grouptree = proto_item_add_subtree(tigroup, ett_pim); |
1504 | 0 | offset += advance; |
1505 | |
|
1506 | 0 | proto_tree_add_item(grouptree, hf_pim_rp_count, tvb, offset, 1, ENC_BIG_ENDIAN); |
1507 | 0 | offset += 1; |
1508 | 0 | frpcnt = tvb_get_uint8(tvb, offset); |
1509 | 0 | proto_tree_add_item(grouptree, hf_pim_frp_count, tvb, offset, 1, ENC_BIG_ENDIAN); |
1510 | 0 | offset += 3; |
1511 | |
|
1512 | 0 | for (j = 0; j < frpcnt; j++) { |
1513 | 0 | if (!dissect_pim_addr(pinfo, pimopt_tree, tvb, offset, pimv2_unicast, |
1514 | 0 | wmem_strdup_printf(pinfo->pool, "RP %d", j), NULL, |
1515 | 0 | hf_pim_rp_ip4, hf_pim_rp_ip6, &advance)) |
1516 | | |
1517 | 0 | goto breakbreak4; |
1518 | 0 | offset += advance; |
1519 | |
|
1520 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_holdtime, tvb, offset, 2, ENC_BIG_ENDIAN); |
1521 | 0 | offset += 2; |
1522 | 0 | proto_tree_add_item(grouptree, hf_pim_priority, tvb, offset, 1, ENC_BIG_ENDIAN); |
1523 | 0 | offset += 1; |
1524 | | |
1525 | | /* reserved stuff */ |
1526 | 0 | proto_tree_add_item(pim_tree, hf_pim_res_bytes, tvb, offset, 1, ENC_NA); |
1527 | 0 | offset += 1; |
1528 | 0 | } |
1529 | 0 | } |
1530 | | |
1531 | 3 | breakbreak4: |
1532 | 3 | break; |
1533 | 3 | } |
1534 | | |
1535 | 2 | case PIM_TYPE_ASSERT: /* assert */ |
1536 | 1 | { |
1537 | 1 | int advance; |
1538 | | |
1539 | 1 | if (!dissect_pim_addr(pinfo, pimopt_tree, tvb, offset, pimv2_group, |
1540 | 1 | NULL, NULL, |
1541 | 1 | hf_pim_group_ip4, hf_pim_group_ip6, &advance)) |
1542 | 1 | break; |
1543 | 0 | offset += advance; |
1544 | |
|
1545 | 0 | if (!dissect_pim_addr(pinfo, pimopt_tree, tvb, offset, pimv2_unicast, |
1546 | 0 | NULL, NULL, |
1547 | 0 | hf_pim_source_ip4, hf_pim_source_ip6, &advance)) |
1548 | 0 | break; |
1549 | 0 | offset += advance; |
1550 | |
|
1551 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_rpt, tvb, offset, 1, ENC_BIG_ENDIAN); |
1552 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_metric_pref, tvb, |
1553 | 0 | offset, 4, ENC_BIG_ENDIAN); |
1554 | 0 | offset += 4; |
1555 | |
|
1556 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_metric, tvb, offset, 4, ENC_BIG_ENDIAN); |
1557 | | /* offset += 4;*/ |
1558 | 0 | break; |
1559 | 0 | } |
1560 | | |
1561 | 4 | case PIM_TYPE_CAND_RP_ADV: /* Candidate-RP-Advertisement */ |
1562 | 4 | { |
1563 | 4 | int advance; |
1564 | 4 | int pfxcnt; |
1565 | 4 | int i; |
1566 | | |
1567 | 4 | pfxcnt = tvb_get_uint8(tvb, offset); |
1568 | 4 | proto_tree_add_item(pimopt_tree, hf_pim_prefix_count, tvb, offset, 1, ENC_BIG_ENDIAN); |
1569 | 4 | offset += 1; |
1570 | 4 | proto_tree_add_item(pimopt_tree, hf_pim_priority, tvb, offset, 1, ENC_BIG_ENDIAN); |
1571 | 4 | offset += 1; |
1572 | | |
1573 | 4 | proto_tree_add_item(pimopt_tree, hf_pim_holdtime, tvb, offset, 2, ENC_BIG_ENDIAN); |
1574 | 4 | offset += 2; |
1575 | | |
1576 | 4 | if (!dissect_pim_addr(pinfo, pimopt_tree, tvb, offset, pimv2_unicast, |
1577 | 4 | NULL, NULL, |
1578 | 4 | hf_pim_rp_ip4, hf_pim_rp_ip6, &advance)) |
1579 | 2 | break; |
1580 | 2 | offset += advance; |
1581 | | |
1582 | 4 | for (i = 0; i < pfxcnt; i++) { |
1583 | 3 | if (!dissect_pim_addr(pinfo, pimopt_tree, tvb, offset, pimv2_group, |
1584 | 3 | wmem_strdup_printf(pinfo->pool, "Group %d", i), NULL, |
1585 | 3 | hf_pim_group_ip4, hf_pim_group_ip6, &advance)) |
1586 | 1 | goto breakbreak8; |
1587 | 2 | offset += advance; |
1588 | 2 | } |
1589 | 1 | breakbreak8: |
1590 | 1 | break; |
1591 | 2 | } |
1592 | | |
1593 | 7 | case PIM_TYPE_STATE_REFRESH: /* State-Refresh */ |
1594 | 7 | { |
1595 | 7 | int advance; |
1596 | | |
1597 | 7 | if (!dissect_pim_addr(pinfo, pimopt_tree, tvb, offset, pimv2_group, |
1598 | 7 | NULL, NULL, |
1599 | 7 | hf_pim_group_ip4, hf_pim_group_ip6, &advance)) |
1600 | 2 | break; |
1601 | 5 | offset += advance; |
1602 | | |
1603 | 5 | if (!dissect_pim_addr(pinfo, pimopt_tree, tvb, offset, pimv2_unicast, |
1604 | 5 | NULL, NULL, |
1605 | 5 | hf_pim_source_ip4, hf_pim_source_ip6, &advance)) |
1606 | 1 | break; |
1607 | 4 | offset += advance; |
1608 | | |
1609 | 4 | if (!dissect_pim_addr(pinfo, pimopt_tree, tvb, offset, pimv2_unicast, |
1610 | 4 | NULL, NULL, |
1611 | 4 | hf_pim_originator_ip4, hf_pim_originator_ip6, &advance)) |
1612 | 1 | break; |
1613 | 3 | offset += advance; |
1614 | | |
1615 | 3 | proto_tree_add_item(pimopt_tree, hf_pim_rpt, tvb, offset, 1, ENC_BIG_ENDIAN); |
1616 | 3 | proto_tree_add_item(pimopt_tree, hf_pim_metric_pref, tvb, |
1617 | 3 | offset, 4, ENC_BIG_ENDIAN); |
1618 | 3 | offset += 4; |
1619 | | |
1620 | 3 | proto_tree_add_item(pimopt_tree, hf_pim_metric, tvb, offset, 4, ENC_BIG_ENDIAN); |
1621 | 3 | offset += 4; |
1622 | | |
1623 | 3 | proto_tree_add_item(pimopt_tree, hf_pim_mask_len, tvb, offset, 1, ENC_BIG_ENDIAN); |
1624 | 3 | offset += 1; |
1625 | | |
1626 | 3 | proto_tree_add_item(pimopt_tree, hf_pim_ttl, tvb, offset, 1, ENC_BIG_ENDIAN); |
1627 | 3 | offset += 1; |
1628 | | |
1629 | 3 | proto_tree_add_item(pimopt_tree, hf_pim_prune_indicator, tvb, offset, 1, ENC_BIG_ENDIAN); |
1630 | 3 | proto_tree_add_item(pimopt_tree, hf_pim_prune_now, tvb, offset, 1, ENC_BIG_ENDIAN); |
1631 | 3 | proto_tree_add_item(pimopt_tree, hf_pim_assert_override, tvb, offset, 1, ENC_BIG_ENDIAN); |
1632 | 3 | offset += 1; |
1633 | | |
1634 | 3 | proto_tree_add_item(pimopt_tree, hf_pim_interval, tvb, offset, 1, ENC_BIG_ENDIAN); |
1635 | | /*offset += 1;*/ |
1636 | | |
1637 | 3 | break; |
1638 | 4 | } |
1639 | | |
1640 | 8 | case PIM_TYPE_DF_ELECT: |
1641 | 8 | { |
1642 | 8 | int advance; |
1643 | | |
1644 | 8 | if (!dissect_pim_addr(pinfo, pimopt_tree, tvb, offset, pimv2_unicast, |
1645 | 8 | NULL, NULL, |
1646 | 8 | hf_pim_rp_ip4, hf_pim_rp_ip6, &advance)) |
1647 | 2 | break; |
1648 | 6 | offset += advance; |
1649 | 6 | proto_tree_add_item(pimopt_tree, hf_pim_df_metric_pref, tvb, |
1650 | 6 | offset, 4, ENC_BIG_ENDIAN); |
1651 | 6 | offset += 4; |
1652 | 6 | proto_tree_add_item(pimopt_tree, hf_pim_metric, tvb, offset, 4, ENC_BIG_ENDIAN); |
1653 | 6 | offset += 4; |
1654 | | |
1655 | 6 | switch(PIM_BIDIR_SUBTYPE(pim_bidir_subtype)) { |
1656 | 0 | case PIM_BDIR_DF_BACKOFF : |
1657 | 0 | if (!dissect_pim_addr(pinfo, pimopt_tree, tvb, offset, pimv2_unicast, |
1658 | 0 | NULL, NULL, |
1659 | 0 | hf_pim_bd_bo_offer_ip4, hf_pim_bd_bo_offer_ip6, &advance)) |
1660 | 0 | break; |
1661 | 0 | offset += advance; |
1662 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_bd_offer_metric_pref, tvb, offset, 4, ENC_BIG_ENDIAN); |
1663 | 0 | offset += 4; |
1664 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_bd_offer_metric, tvb, offset, 4, ENC_BIG_ENDIAN); |
1665 | 0 | offset += 4; |
1666 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_bd_offer_interval, tvb, offset, 2, ENC_BIG_ENDIAN); |
1667 | 0 | break; |
1668 | 0 | case PIM_BDIR_DF_PASS: |
1669 | 0 | if (!dissect_pim_addr(pinfo, pimopt_tree, tvb, offset, pimv2_unicast, |
1670 | 0 | NULL, NULL, |
1671 | 0 | hf_pim_bd_pass_ip4, hf_pim_bd_pass_ip6, &advance)) |
1672 | 0 | break; |
1673 | 0 | offset += advance; |
1674 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_bd_pass_metric_pref, tvb, offset, 4, ENC_BIG_ENDIAN); |
1675 | 0 | offset += 4; |
1676 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_bd_pass_metric, tvb, offset, 4, ENC_BIG_ENDIAN); |
1677 | 0 | break; |
1678 | 6 | } |
1679 | 1 | break; |
1680 | 6 | } |
1681 | | |
1682 | 14 | case PIM_TYPE_PFM: /*pfm*/ |
1683 | 14 | { |
1684 | 14 | int opt_count = 0; |
1685 | 14 | int advance; |
1686 | | |
1687 | 14 | if (!dissect_pim_addr(pinfo, pimopt_tree, tvb, offset, pimv2_unicast, NULL, NULL, |
1688 | 14 | hf_pim_originator_ip4, hf_pim_originator_ip6, &advance)) |
1689 | 1 | break; |
1690 | 13 | offset += advance; |
1691 | 133 | while (tvb_reported_length_remaining(tvb, offset) >= 2) { |
1692 | 130 | uint16_t pfm, pfm_opt, opt_len; |
1693 | 130 | proto_item *opt_item; |
1694 | 130 | proto_tree *opt_tree; |
1695 | | |
1696 | 130 | opt_count++; |
1697 | 130 | pfm = tvb_get_ntohs(tvb, offset); |
1698 | 130 | opt_len = tvb_get_ntohs(tvb, offset + 2); |
1699 | 130 | pfm_opt = pfm & 0x7FFF; |
1700 | 130 | opt_tree = proto_tree_add_subtree_format(pimopt_tree, tvb, offset, 4 + opt_len, |
1701 | 130 | ett_pim_opt, &opt_item, "Option %u: %s", pfm_opt, |
1702 | 130 | val_to_str(pinfo->pool, pfm_opt, pim_opt_vals1, "Unknown: %u")); |
1703 | 130 | proto_tree_add_item(opt_tree, hf_pim_transitivetype, tvb, offset, 1, ENC_BIG_ENDIAN); |
1704 | 130 | proto_tree_add_item(opt_tree, hf_pim_optiontype1, tvb, offset, 2, ENC_BIG_ENDIAN); |
1705 | 130 | proto_tree_add_item(opt_tree, hf_pim_optionlength, tvb, offset + 2, 2, ENC_BIG_ENDIAN); |
1706 | 130 | offset += 4; |
1707 | 130 | switch(pfm_opt){ |
1708 | 1 | case PIM_PFM_GROUP_SOURCE: |
1709 | 1 | { |
1710 | 1 | if (!dissect_pim_addr(pinfo, pimopt_tree, tvb, offset, pimv2_group, NULL, NULL, |
1711 | 1 | hf_pim_group_ip4, hf_pim_group_ip6, &advance)) |
1712 | 1 | break; |
1713 | 0 | offset += advance; |
1714 | 0 | uint16_t src_count; |
1715 | 0 | src_count=tvb_get_ntohs(tvb, offset); |
1716 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_srcount, tvb, offset, 2, ENC_BIG_ENDIAN); |
1717 | 0 | offset += 2; |
1718 | 0 | proto_tree_add_item(pimopt_tree, hf_pim_srcholdt, tvb, offset, 2, ENC_BIG_ENDIAN); |
1719 | 0 | offset += 2; |
1720 | 0 | while(src_count>0){ |
1721 | 0 | if (!dissect_pim_addr(pinfo, pimopt_tree, tvb, offset, pimv2_unicast, NULL, NULL, |
1722 | 0 | hf_pim_source_ip4, hf_pim_source_ip6, &advance)) |
1723 | 0 | goto breakbreak12; |
1724 | 0 | offset+=advance; |
1725 | 0 | src_count--; |
1726 | 0 | } |
1727 | 0 | break; |
1728 | 0 | } |
1729 | 129 | default: |
1730 | 129 | if (opt_len) |
1731 | 24 | proto_tree_add_item(opt_tree, hf_pim_optionvalue, tvb, |
1732 | 24 | offset, opt_len, ENC_NA); |
1733 | 129 | offset += opt_len; |
1734 | 129 | break; |
1735 | 130 | } |
1736 | 130 | } |
1737 | 3 | proto_item_append_text(tiopt, ": %u", opt_count); |
1738 | 3 | breakbreak12: |
1739 | 3 | break; |
1740 | 3 | } |
1741 | | |
1742 | 13 | case PIM_TYPE_PACKED_REGISTER: /* Packed Register */ |
1743 | 13 | { |
1744 | 13 | int ngroups; |
1745 | 13 | int advance, i; |
1746 | 13 | proto_tree *grouptree = NULL; |
1747 | 13 | proto_item *tigroup; |
1748 | | |
1749 | 13 | switch (pim_subtype) { |
1750 | 11 | case PIM_TYPE_PACKED_NULL_REGISTER: |
1751 | 11 | case PIM_TYPE_PACKED_REGISTER_STOP: |
1752 | | /* |
1753 | | * Total length minus PIM header length |
1754 | | * divided by 1 encoded record size (14 bytes). |
1755 | | */ |
1756 | 11 | ngroups = (length-4)/14; |
1757 | 26 | for (i = 0; i < ngroups; i++) { |
1758 | | /* |
1759 | | * RFC9465 states that an (S,G) entry is called a "Record". |
1760 | | */ |
1761 | 19 | tigroup=proto_tree_add_string_format(pimopt_tree, hf_pim_group, tvb, offset, -1, "", "Record %d", i+1); |
1762 | 19 | grouptree = proto_item_add_subtree(tigroup, ett_pim); |
1763 | 19 | if (!dissect_pim_addr(pinfo, grouptree, tvb, offset, pimv2_group, |
1764 | 19 | wmem_strdup_printf(pinfo->pool, "Group"), NULL, |
1765 | 19 | hf_pim_group_ip4, hf_pim_group_ip6, &advance)) |
1766 | 3 | goto breakpackedreg; |
1767 | 16 | offset += advance; |
1768 | 16 | if (!dissect_pim_addr(pinfo, grouptree, tvb, offset, pimv2_unicast, NULL, NULL, |
1769 | 16 | hf_pim_source_ip4, hf_pim_source_ip6, &advance)) |
1770 | 1 | goto breakpackedreg; |
1771 | 15 | offset += advance; |
1772 | 15 | } |
1773 | 7 | break; |
1774 | 7 | default: |
1775 | 2 | break; |
1776 | 13 | } |
1777 | 7 | breakpackedreg: |
1778 | 7 | break; |
1779 | 13 | } |
1780 | | |
1781 | 3 | default: |
1782 | 3 | break; |
1783 | 127 | } |
1784 | 91 | done: |
1785 | 91 | return tvb_captured_length(tvb); |
1786 | 127 | } |
1787 | | |
1788 | | void |
1789 | | proto_register_pim(void) |
1790 | 14 | { |
1791 | 14 | static hf_register_info hf[] = |
1792 | 14 | { |
1793 | 14 | { &hf_pim_version, |
1794 | 14 | { "Version", "pim.version", |
1795 | 14 | FT_UINT8, BASE_DEC, NULL, 0xf0, |
1796 | 14 | NULL, HFILL } |
1797 | 14 | }, |
1798 | 14 | { &hf_pim_type, |
1799 | 14 | { "Type", "pim.type", |
1800 | 14 | FT_UINT8, BASE_DEC, VALS(pimtypevals), 0x0f, |
1801 | 14 | NULL, HFILL } |
1802 | 14 | }, |
1803 | 14 | { &hf_pim_df_elect_subtype, |
1804 | 14 | { "DF Subtype", "pim.df_elect.subtype", |
1805 | 14 | FT_UINT8, BASE_DEC, VALS(pimbdirdfvals), 0xf0, |
1806 | 14 | NULL, HFILL} |
1807 | 14 | }, |
1808 | 14 | { &hf_pim_df_elect_rsvd, |
1809 | 14 | { "DF reserved", "pim.df_elect.rsvd", |
1810 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0f, |
1811 | 14 | NULL, HFILL} |
1812 | 14 | }, |
1813 | 14 | { &hf_pim_igmp_type, |
1814 | 14 | { "Type", "pim.igmp_type", |
1815 | 14 | FT_STRING, BASE_NONE, NULL, 0x0, |
1816 | 14 | NULL, HFILL } |
1817 | 14 | }, |
1818 | 14 | { &hf_pim_code, |
1819 | 14 | { "Code", "pim.code", |
1820 | 14 | FT_UINT8, BASE_DEC, VALS(pim_type1_vals), 0x0, |
1821 | 14 | NULL, HFILL } |
1822 | 14 | }, |
1823 | 14 | { &hf_pim_cksum, |
1824 | 14 | { "Checksum", "pim.cksum", |
1825 | 14 | FT_UINT16, BASE_HEX, NULL, 0x0, |
1826 | 14 | NULL, HFILL } |
1827 | 14 | }, |
1828 | 14 | { &hf_pim_cksum_status, |
1829 | 14 | { "Checksum Status", "pim.cksum.status", |
1830 | 14 | FT_UINT8, BASE_NONE, VALS(proto_checksum_vals), 0x0, |
1831 | 14 | NULL, HFILL } |
1832 | 14 | }, |
1833 | 14 | { &hf_pim_res_bytes, |
1834 | 14 | { "Reserved byte(s)", "pim.res_bytes", |
1835 | 14 | FT_BYTES, BASE_NONE, NULL, 0x0, |
1836 | 14 | NULL, HFILL } |
1837 | 14 | }, |
1838 | 14 | { &hf_pim_type_13_subtype, |
1839 | 14 | { "Subtype", "pim.subtype_type13", |
1840 | 14 | FT_UINT8, BASE_DEC, VALS(pimtype13subtypevals), 0xf0, |
1841 | 14 | NULL, HFILL } |
1842 | 14 | }, |
1843 | 14 | { &hf_pim_type_13_flagbits, |
1844 | 14 | { "Flag Bits", "pim.flag_bits_type13", |
1845 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0f, |
1846 | 14 | NULL, HFILL } |
1847 | 14 | }, |
1848 | | |
1849 | 14 | { &hf_pim_option, |
1850 | 14 | { "PIM Options", "pim.option", |
1851 | 14 | FT_NONE, BASE_NONE, NULL, 0x0, |
1852 | 14 | NULL, HFILL } |
1853 | 14 | }, |
1854 | 14 | { &hf_pim_optiontype, |
1855 | 14 | { "Type", "pim.optiontype", |
1856 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
1857 | 14 | NULL, HFILL } |
1858 | 14 | }, |
1859 | 14 | { &hf_pim_optiontype1, |
1860 | 14 | { "Type", "pim.optiontype", |
1861 | 14 | FT_UINT16, BASE_DEC, NULL, 0x7fff, |
1862 | 14 | NULL, HFILL } |
1863 | 14 | }, |
1864 | 14 | { &hf_pim_optionlength, |
1865 | 14 | { "Length", "pim.optionlength", |
1866 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
1867 | 14 | NULL, HFILL } |
1868 | 14 | }, |
1869 | 14 | { &hf_pim_optionvalue, |
1870 | 14 | { "Unknown", "pim.optionvalue", |
1871 | 14 | FT_BYTES, BASE_NONE, NULL, 0x0, |
1872 | 14 | NULL, HFILL } |
1873 | 14 | }, |
1874 | 14 | { &hf_pim_register_flag, |
1875 | 14 | { "Flags", "pim.register_flag", |
1876 | 14 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1877 | 14 | NULL, HFILL } |
1878 | 14 | }, |
1879 | 14 | { &hf_pim_register_flag_border, |
1880 | 14 | { "Border", "pim.register_flag.border", |
1881 | 14 | FT_BOOLEAN, 32, TFS(&tfs_yes_no), 0x80000000, |
1882 | 14 | NULL, HFILL } |
1883 | 14 | }, |
1884 | 14 | { &hf_pim_register_flag_null_register, |
1885 | 14 | { "Null-Register", "pim.register_flag.null_register", |
1886 | 14 | FT_BOOLEAN, 32, TFS(&tfs_yes_no), 0x40000000, |
1887 | 14 | NULL, HFILL } |
1888 | 14 | }, |
1889 | 14 | { &hf_pim_mode, |
1890 | 14 | { "Mode", "pim.mode", |
1891 | 14 | FT_UINT8, BASE_DEC, VALS(pimv1_modevals), 0xf0, |
1892 | 14 | NULL, HFILL } |
1893 | 14 | }, |
1894 | 14 | { &hf_pim_holdtime, |
1895 | 14 | { "Holdtime", "pim.holdtime", |
1896 | 14 | FT_UINT16, BASE_DEC|BASE_SPECIAL_VALS, VALS(unique_infinity), 0x0, |
1897 | 14 | "The amount of time a receiver must keep the neighbor " |
1898 | 14 | "reachable, in seconds.", HFILL } |
1899 | 14 | }, |
1900 | 14 | { &hf_pim_holdtime_t, |
1901 | 14 | { "Holdtime", "pim.holdtime", |
1902 | 14 | FT_UINT16, BASE_DEC|BASE_SPECIAL_VALS, VALS(unique_infinity_t), 0x0, |
1903 | 14 | "The amount of time a receiver must keep the neighbor " |
1904 | 14 | "reachable, in seconds.", HFILL } |
1905 | 14 | }, |
1906 | 14 | { &hf_pim_numgroups, |
1907 | 14 | { "Num Groups", "pim.numgroups", |
1908 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
1909 | 14 | "Number of multicast group sets contained in the message.", |
1910 | 14 | HFILL } |
1911 | 14 | }, |
1912 | 14 | { &hf_pim_numjoins, |
1913 | 14 | { "Num Joins", "pim.numjoins", |
1914 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
1915 | 14 | "Number of joined sources.", HFILL } |
1916 | 14 | }, |
1917 | 14 | { &hf_pim_numprunes, |
1918 | 14 | { "Num Prunes", "pim.numprunes", |
1919 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
1920 | 14 | "Number of pruned sources.", HFILL } |
1921 | 14 | }, |
1922 | 14 | { &hf_pim_t, |
1923 | 14 | { "T", "pim.t", |
1924 | 14 | FT_BOOLEAN, 8, NULL, 0x80, |
1925 | 14 | "Specifies the ability of the sending router to disable joins " |
1926 | 14 | "suppression.", HFILL } |
1927 | 14 | }, |
1928 | 14 | { &hf_pim_propagation_delay, |
1929 | 14 | { "Propagation Delay", "pim.propagation_delay", |
1930 | 14 | FT_UINT16, BASE_DEC, NULL, 0x7fff, |
1931 | 14 | "Units are milli-seconds", HFILL } |
1932 | 14 | }, |
1933 | 14 | { &hf_pim_override_interval, |
1934 | 14 | { "Override Interval", "pim.override_interval", |
1935 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
1936 | 14 | "Units are milli-seconds", HFILL } |
1937 | 14 | }, |
1938 | 14 | { &hf_pim_dr_priority, |
1939 | 14 | { "DR Priority", "pim.dr_priority", |
1940 | 14 | FT_UINT32, BASE_DEC, NULL, 0x0, |
1941 | 14 | NULL, HFILL } |
1942 | 14 | }, |
1943 | 14 | { &hf_pim_generation_id, |
1944 | 14 | { "Generation ID", "pim.generation_id", |
1945 | 14 | FT_UINT32, BASE_DEC, NULL, 0x0, |
1946 | 14 | NULL, HFILL } |
1947 | 14 | }, |
1948 | 14 | { &hf_pim_state_refresh_version, |
1949 | 14 | { "Version", "pim.state_refresh_version", |
1950 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1951 | 14 | NULL, HFILL } |
1952 | 14 | }, |
1953 | 14 | { &hf_pim_state_refresh_interval, |
1954 | 14 | { "Interval", "pim.state_refresh_interval", |
1955 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1956 | 14 | "Units in seconds.", HFILL } |
1957 | 14 | }, |
1958 | 14 | { &hf_pim_state_refresh_reserved, |
1959 | 14 | { "Reserved", "pim.state_refresh_reserved", |
1960 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
1961 | 14 | NULL, HFILL } |
1962 | 14 | }, |
1963 | 14 | { &hf_pim_rpt, |
1964 | 14 | { "RP Tree", "pim.rpt", |
1965 | 14 | FT_BOOLEAN, 8, NULL, 0x80, |
1966 | 14 | "Set to 1 for assert(*,G) messages and 0 for assert(S,G) " |
1967 | 14 | "messages.", HFILL } |
1968 | 14 | }, |
1969 | 14 | { &hf_pim_metric_pref, |
1970 | 14 | { "Metric Preference", "pim.metric_pref", |
1971 | 14 | FT_UINT32, BASE_DEC, NULL, 0x7fffffff, |
1972 | 14 | NULL, HFILL } |
1973 | 14 | }, |
1974 | 14 | { &hf_pim_df_metric_pref, |
1975 | 14 | { "DF Metric Preference", "pim.metric_pref", |
1976 | 14 | FT_UINT32, BASE_DEC, NULL, 0, |
1977 | 14 | NULL, HFILL } |
1978 | 14 | }, |
1979 | 14 | { &hf_pim_metric, |
1980 | 14 | { "Metric", "pim.metric", |
1981 | 14 | FT_UINT32, BASE_DEC, NULL, 0x0, |
1982 | 14 | NULL, HFILL } |
1983 | 14 | }, |
1984 | 14 | { &hf_pim_prune_indicator, |
1985 | 14 | { "Prune indicator", "pim.prune_indicator", |
1986 | 14 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80, |
1987 | 14 | NULL, HFILL } |
1988 | 14 | }, |
1989 | 14 | { &hf_pim_prune_now, |
1990 | 14 | { "Prune now", "pim.prune_now", |
1991 | 14 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x40, |
1992 | 14 | NULL, HFILL } |
1993 | 14 | }, |
1994 | 14 | { &hf_pim_assert_override, |
1995 | 14 | { "Assert override", "pim.assert_override", |
1996 | 14 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x20, |
1997 | 14 | NULL, HFILL } |
1998 | 14 | }, |
1999 | 14 | { &hf_pim_ip_version, |
2000 | 14 | { "IP Version", "pim.ip_version", |
2001 | 14 | FT_UINT8, BASE_DEC, VALS(pim_ip_version_vals), 0xF0, |
2002 | 14 | NULL, HFILL } |
2003 | 14 | }, |
2004 | 14 | { &hf_pim_dummy_header, |
2005 | 14 | { "Dummy Header", "pim.dummy_header", |
2006 | 14 | FT_NONE, BASE_NONE, NULL, 0, |
2007 | 14 | NULL, HFILL } |
2008 | 14 | }, |
2009 | 14 | { &hf_pim_source_ip4, |
2010 | 14 | { "Source", "pim.source", |
2011 | 14 | FT_IPv4, BASE_NONE, NULL, 0, |
2012 | 14 | NULL, HFILL } |
2013 | 14 | }, |
2014 | 14 | { &hf_pim_source_ip6, |
2015 | 14 | { "Source", "pim.source_ip6", |
2016 | 14 | FT_IPv6, BASE_NONE, NULL, 0, |
2017 | 14 | NULL, HFILL } |
2018 | 14 | }, |
2019 | 14 | { &hf_pim_group_ip4, |
2020 | 14 | { "Group", "pim.group", |
2021 | 14 | FT_IPv4, BASE_NONE, NULL, 0, |
2022 | 14 | NULL, HFILL } |
2023 | 14 | }, |
2024 | 14 | { &hf_pim_group_mask_ip4, |
2025 | 14 | { "Mask", "pim.group_mask", |
2026 | 14 | FT_IPv4, BASE_NONE, NULL, 0, |
2027 | 14 | NULL, HFILL } |
2028 | 14 | }, |
2029 | 14 | { &hf_pim_group_ip6, |
2030 | 14 | { "Group", "pim.group_ip6", |
2031 | 14 | FT_IPv6, BASE_NONE, NULL, 0, |
2032 | 14 | NULL, HFILL } |
2033 | 14 | }, |
2034 | 14 | { &hf_pim_upstream_neighbor_ip4, |
2035 | 14 | { "Upstream-neighbor", "pim.upstream_neighbor", |
2036 | 14 | FT_IPv4, BASE_NONE, NULL, 0, |
2037 | 14 | NULL, HFILL } |
2038 | 14 | }, |
2039 | 14 | { &hf_pim_upstream_neighbor_ip6, |
2040 | 14 | { "Upstream-neighbor", "pim.upstream_neighbor_ip6", |
2041 | 14 | FT_IPv6, BASE_NONE, NULL, 0, |
2042 | 14 | NULL, HFILL } |
2043 | 14 | }, |
2044 | 14 | { &hf_pim_join_ip4, |
2045 | 14 | { "IP address", "pim.join_ip", |
2046 | 14 | FT_IPv4, BASE_NONE, NULL, 0, |
2047 | 14 | NULL, HFILL } |
2048 | 14 | }, |
2049 | 14 | { &hf_pim_join_ip6, |
2050 | 14 | { "IP address", "pim.join_ip6", |
2051 | 14 | FT_IPv6, BASE_NONE, NULL, 0, |
2052 | 14 | NULL, HFILL } |
2053 | 14 | }, |
2054 | 14 | { &hf_pim_prune_ip4, |
2055 | 14 | { "IP address", "pim.prune_ip", |
2056 | 14 | FT_IPv4, BASE_NONE, NULL, 0, |
2057 | 14 | NULL, HFILL } |
2058 | 14 | }, |
2059 | 14 | { &hf_pim_prune_ip6, |
2060 | 14 | { "IP address", "pim.prune_ip6", |
2061 | 14 | FT_IPv6, BASE_NONE, NULL, 0, |
2062 | 14 | NULL, HFILL } |
2063 | 14 | }, |
2064 | 14 | { &hf_pim_address_list_ip4, |
2065 | 14 | { "Address", "pim.address_list", |
2066 | 14 | FT_IPv4, BASE_NONE, NULL, 0, |
2067 | 14 | NULL, HFILL } |
2068 | 14 | }, |
2069 | 14 | { &hf_pim_address_list_ip6, |
2070 | 14 | { "Address", "pim.address_list_ip6", |
2071 | 14 | FT_IPv6, BASE_NONE, NULL, 0, |
2072 | 14 | NULL, HFILL } |
2073 | 14 | }, |
2074 | 14 | { &hf_pim_bsr_ip4, |
2075 | 14 | { "BSR", "pim.bsr", |
2076 | 14 | FT_IPv4, BASE_NONE, NULL, 0, |
2077 | 14 | NULL, HFILL } |
2078 | 14 | }, |
2079 | 14 | { &hf_pim_bsr_ip6, |
2080 | 14 | { "BSR", "pim.bsr_ip6", |
2081 | 14 | FT_IPv6, BASE_NONE, NULL, 0, |
2082 | 14 | NULL, HFILL } |
2083 | 14 | }, |
2084 | 14 | { &hf_pim_rp_ip4, |
2085 | 14 | { "RP", "pim.rp", |
2086 | 14 | FT_IPv4, BASE_NONE, NULL, 0, |
2087 | 14 | NULL, HFILL } |
2088 | 14 | }, |
2089 | 14 | { &hf_pim_rp_ip6, |
2090 | 14 | { "RP", "pim.rp_ip6", |
2091 | 14 | FT_IPv6, BASE_NONE, NULL, 0, |
2092 | 14 | NULL, HFILL } |
2093 | 14 | }, |
2094 | 14 | { &hf_pim_originator_ip4, |
2095 | 14 | { "Originator", "pim.originator", |
2096 | 14 | FT_IPv4, BASE_NONE, NULL, 0, |
2097 | 14 | NULL, HFILL } |
2098 | 14 | }, |
2099 | 14 | { &hf_pim_originator_ip6, |
2100 | 14 | { "Originator", "pim.originator_ip6", |
2101 | 14 | FT_IPv6, BASE_NONE, NULL, 0, |
2102 | 14 | NULL, HFILL } |
2103 | 14 | }, |
2104 | 14 | { &hf_pim_group_address_ip4, |
2105 | 14 | { "Group Address", "pim.group_address", |
2106 | 14 | FT_IPv4, BASE_NONE, NULL, 0, |
2107 | 14 | NULL, HFILL } |
2108 | 14 | }, |
2109 | 14 | { &hf_pim_bd_pass_ip4, |
2110 | 14 | { "New Winner IP", "pim.bidir_winner_ip4", |
2111 | 14 | FT_IPv4, BASE_NONE, NULL, 0, |
2112 | 14 | NULL, HFILL } |
2113 | 14 | }, |
2114 | 14 | { &hf_pim_bd_pass_ip6, |
2115 | 14 | { "New Winner IP", "pim.bidir_winner_ip6", |
2116 | 14 | FT_IPv6, BASE_NONE, NULL, 0, |
2117 | 14 | NULL, HFILL } |
2118 | 14 | }, |
2119 | 14 | { &hf_pim_bd_pass_metric_pref, |
2120 | 14 | { "Winner Metric Preference", "pim.bidir_win_metric_pref", |
2121 | 14 | FT_UINT32, BASE_DEC, NULL, 0, |
2122 | 14 | NULL, HFILL } |
2123 | 14 | }, |
2124 | 14 | { &hf_pim_bd_pass_metric, |
2125 | 14 | { "Winner Metric", "pim.bidir_win_metric", |
2126 | 14 | FT_UINT32, BASE_DEC, NULL, 0, |
2127 | 14 | NULL, HFILL } |
2128 | 14 | }, |
2129 | 14 | { &hf_pim_bd_bo_offer_ip4, |
2130 | 14 | { "Offering IP", "pim.bidir_offering_ip4", |
2131 | 14 | FT_IPv4, BASE_NONE, NULL, 0, |
2132 | 14 | NULL, HFILL } |
2133 | 14 | }, |
2134 | 14 | { &hf_pim_bd_bo_offer_ip6, |
2135 | 14 | { "Offering IP", "pim.bidir_offering_ip6", |
2136 | 14 | FT_IPv6, BASE_NONE, NULL, 0, |
2137 | 14 | NULL, HFILL } |
2138 | 14 | }, |
2139 | 14 | { &hf_pim_bd_offer_metric_pref, |
2140 | 14 | { "Offering Metric Preference", "pim.bidir_off_metric_pref", |
2141 | 14 | FT_UINT32, BASE_DEC, NULL, 0, |
2142 | 14 | NULL, HFILL } |
2143 | 14 | }, |
2144 | 14 | { &hf_pim_bd_offer_metric, |
2145 | 14 | { "Offering Metric", "pim.bidir_off_metric", |
2146 | 14 | FT_UINT32, BASE_DEC, NULL, 0, |
2147 | 14 | NULL, HFILL } |
2148 | 14 | }, |
2149 | 14 | { &hf_pim_bd_offer_interval, |
2150 | 14 | { "Offering interval (ms)", "pim.bidir_offering_interval", |
2151 | 14 | FT_UINT16, BASE_DEC, NULL, 0, |
2152 | 14 | NULL, HFILL } |
2153 | 14 | }, |
2154 | 14 | { &hf_pim_fragment_tag, |
2155 | 14 | { "Fragment tag", "pim.fragment_tag", |
2156 | 14 | FT_UINT16, BASE_HEX, NULL, 0x0, |
2157 | 14 | NULL, HFILL } |
2158 | 14 | }, |
2159 | 14 | { &hf_pim_hash_mask_len, |
2160 | 14 | { "Hash mask len", "pim.hash_mask_len", |
2161 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
2162 | 14 | NULL, HFILL } |
2163 | 14 | }, |
2164 | 14 | { &hf_pim_bsr_priority, |
2165 | 14 | { "BSR priority", "pim.bsr_priority", |
2166 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
2167 | 14 | NULL, HFILL } |
2168 | 14 | }, |
2169 | 14 | { &hf_pim_rp_count, |
2170 | 14 | { "RP count", "pim.rp_count", |
2171 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
2172 | 14 | NULL, HFILL } |
2173 | 14 | }, |
2174 | 14 | { &hf_pim_frp_count, |
2175 | 14 | { "FRP count", "pim.frp_count", |
2176 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
2177 | 14 | NULL, HFILL } |
2178 | 14 | }, |
2179 | 14 | { &hf_pim_priority, |
2180 | 14 | { "Priority", "pim.priority", |
2181 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
2182 | 14 | NULL, HFILL } |
2183 | 14 | }, |
2184 | 14 | { &hf_pim_prefix_count, |
2185 | 14 | { "Prefix-count", "pim.prefix_count", |
2186 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
2187 | 14 | NULL, HFILL } |
2188 | 14 | }, |
2189 | 14 | { &hf_pim_src_flags_a, |
2190 | 14 | { "Annotated", "pim.src_flags.a", |
2191 | 14 | FT_UINT8, BASE_DEC, NULL, 0x08, |
2192 | 14 | NULL, HFILL } |
2193 | 14 | }, |
2194 | 14 | { &hf_pim_src_flags_s, |
2195 | 14 | { "Sparse", "pim.src_flags.s", |
2196 | 14 | FT_UINT8, BASE_DEC, NULL, 0x04, |
2197 | 14 | NULL, HFILL } |
2198 | 14 | }, |
2199 | 14 | { &hf_pim_src_flags_w, |
2200 | 14 | { "WC", "pim.src_flags.w", |
2201 | 14 | FT_UINT8, BASE_DEC, NULL, 0x02, |
2202 | 14 | NULL, HFILL } |
2203 | 14 | }, |
2204 | 14 | { &hf_pim_src_flags_r, |
2205 | 14 | { "RP", "pim.src_flags.r", |
2206 | 14 | FT_UINT8, BASE_DEC, NULL, 0x01, |
2207 | 14 | NULL, HFILL } |
2208 | 14 | }, |
2209 | 14 | { &hf_pim_src_flags_rsv, |
2210 | 14 | { "Reserved", "pim.src_flags.rsv", |
2211 | 14 | FT_UINT8, BASE_DEC, NULL, 0xF0, |
2212 | 14 | NULL, HFILL } |
2213 | 14 | }, |
2214 | 14 | { &hf_pim_mask_len, |
2215 | 14 | { "Masklen", "pim.mask_len", |
2216 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
2217 | 14 | NULL, HFILL } |
2218 | 14 | }, |
2219 | 14 | { &hf_pim_addr_len, |
2220 | 14 | { "Address Len", "pim.addr_len", |
2221 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
2222 | 14 | NULL, HFILL } |
2223 | 14 | }, |
2224 | 14 | { &hf_pim_ttl, |
2225 | 14 | { "TTL", "pim.ttl", |
2226 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
2227 | 14 | NULL, HFILL } |
2228 | 14 | }, |
2229 | 14 | { &hf_pim_interval, |
2230 | 14 | { "Interval", "pim.interval", |
2231 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
2232 | 14 | NULL, HFILL } |
2233 | 14 | }, |
2234 | 14 | { &hf_pim_addr_af, |
2235 | 14 | { "Address Family", "pim.addr_address_family", |
2236 | 14 | FT_UINT8, BASE_DEC, VALS(afn_vals), 0x0, |
2237 | 14 | NULL, HFILL } |
2238 | 14 | }, |
2239 | 14 | { &hf_pim_addr_et, |
2240 | 14 | { "Encoding Type", "pim.addr_encoding_type", |
2241 | 14 | FT_UINT8, BASE_DEC, VALS(pim_addr_et_vals), 0x0, |
2242 | 14 | NULL, HFILL } |
2243 | 14 | }, |
2244 | 14 | { &hf_pim_unicast_addr_ipv4, |
2245 | 14 | { "Unicast", "pim.unicast", |
2246 | 14 | FT_IPv4, BASE_NONE, NULL, 0x0, |
2247 | 14 | NULL, HFILL } |
2248 | 14 | }, |
2249 | 14 | { &hf_pim_unicast_addr_ipv6, |
2250 | 14 | { "Unicast", "pim.unicast_ipv6", |
2251 | 14 | FT_IPv6, BASE_NONE, NULL, 0x0, |
2252 | 14 | NULL, HFILL } |
2253 | 14 | }, |
2254 | 14 | { &hf_pim_attribute_transport_mode, |
2255 | 14 | { "Attribute Transport Mode", "pim.attribute_transport_mode", |
2256 | 14 | FT_UINT8, BASE_DEC, VALS(attribute_transport_mode), 0x0, |
2257 | 14 | NULL, HFILL } |
2258 | 14 | }, |
2259 | 14 | { &hf_pim_rloc_addr_ipv4, |
2260 | 14 | { "RLOC", "pim.rloc", |
2261 | 14 | FT_IPv4, BASE_NONE, NULL, 0x0, |
2262 | 14 | NULL, HFILL } |
2263 | 14 | }, |
2264 | 14 | { &hf_pim_rloc_addr_ipv6, |
2265 | 14 | { "RLOC", "pim.rloc_ipv6", |
2266 | 14 | FT_IPv6, BASE_NONE, NULL, 0x0, |
2267 | 14 | NULL, HFILL } |
2268 | 14 | }, |
2269 | 14 | { &hf_pim_group, |
2270 | 14 | { "Group", "pim.group_set", |
2271 | 14 | FT_STRING, BASE_NONE, NULL, 0x0, |
2272 | 14 | NULL, HFILL } |
2273 | 14 | }, |
2274 | 14 | { &hf_pim_group_addr_flags, |
2275 | 14 | { "Flags", "pim.group_addr.flags", |
2276 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
2277 | 14 | NULL, HFILL } |
2278 | 14 | }, |
2279 | 14 | { &hf_pim_group_addr_flags_b, |
2280 | 14 | { "Bidirectional PIM", "pim.group_addr.flags.b", |
2281 | 14 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), PIM_GROUP_ADDR_FLAGS_B, |
2282 | 14 | NULL, HFILL } |
2283 | 14 | }, |
2284 | 14 | { &hf_pim_group_addr_flags_reserved, |
2285 | 14 | { "Reserved", "pim.group_addr.flags.reserved", |
2286 | 14 | FT_UINT8, BASE_HEX, NULL, PIM_GROUP_ADDR_FLAGS_RESERVED, |
2287 | 14 | NULL, HFILL } |
2288 | 14 | }, |
2289 | 14 | { &hf_pim_group_addr_flags_z, |
2290 | 14 | { "Admin Scope Zone", "pim.group_addr.flags.z", |
2291 | 14 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), PIM_GROUP_ADDR_FLAGS_Z, |
2292 | 14 | NULL, HFILL } |
2293 | 14 | }, |
2294 | 14 | { &hf_pim_source_addr_flags, |
2295 | 14 | { "Flags", "pim.source_addr.flags", |
2296 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
2297 | 14 | NULL, HFILL } |
2298 | 14 | }, |
2299 | 14 | { &hf_pim_source_addr_flags_reserved, |
2300 | 14 | { "Reserved", "pim.source_addr.flags.reserved", |
2301 | 14 | FT_UINT8, BASE_HEX, NULL, PIM_SOURCE_ADDR_FLAGS_RESERVED, |
2302 | 14 | NULL, HFILL } |
2303 | 14 | }, |
2304 | 14 | { &hf_pim_source_addr_flags_s, |
2305 | 14 | { "Sparse", "pim.source_addr.flags.s", |
2306 | 14 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), PIM_SOURCE_ADDR_FLAGS_S, |
2307 | 14 | NULL, HFILL } |
2308 | 14 | }, |
2309 | 14 | { &hf_pim_source_addr_flags_w, |
2310 | 14 | { "WildCard", "pim.source_addr.flags.w", |
2311 | 14 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), PIM_SOURCE_ADDR_FLAGS_W, |
2312 | 14 | NULL, HFILL } |
2313 | 14 | }, |
2314 | 14 | { &hf_pim_source_addr_flags_r, |
2315 | 14 | { "Rendezvous Point Tree", "pim.source_addr.flags.r", |
2316 | 14 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), PIM_SOURCE_ADDR_FLAGS_R, |
2317 | 14 | NULL, HFILL } |
2318 | 14 | }, |
2319 | 14 | { &hf_pim_source_join_attribute, |
2320 | 14 | { "Join Attribute", "pim.source_ja", |
2321 | 14 | FT_NONE, BASE_NONE, NULL, 0x0, |
2322 | 14 | NULL, HFILL } |
2323 | 14 | }, |
2324 | 14 | { &hf_pim_source_ja_flags, |
2325 | 14 | { "Flags", "pim.source_ja.flags", |
2326 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0, |
2327 | 14 | NULL, HFILL } |
2328 | 14 | }, |
2329 | 14 | { &hf_pim_source_ja_flags_f, |
2330 | 14 | { "Forward", "pim.source_ja.flags.f", |
2331 | 14 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), PIM_SOURCE_JA_FLAGS_F, |
2332 | 14 | NULL, HFILL } |
2333 | 14 | }, |
2334 | 14 | { &hf_pim_source_ja_flags_e, |
2335 | 14 | { "End of Attributes", "pim.source_ja.flags.e", |
2336 | 14 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), PIM_SOURCE_JA_FLAGS_E, |
2337 | 14 | NULL, HFILL } |
2338 | 14 | }, |
2339 | 14 | { &hf_pim_source_ja_flags_attr_type, |
2340 | 14 | { "Attribute Type", "pim.source_ja.flags.attr_type", |
2341 | 14 | FT_UINT8, BASE_DEC, VALS(pim_join_attribute_type_vals), PIM_SOURCE_JA_FLAGS_ATTR_TYPE, |
2342 | 14 | NULL, HFILL } |
2343 | 14 | }, |
2344 | 14 | { &hf_pim_source_ja_length, |
2345 | 14 | { "Length", "pim.source_ja.length", |
2346 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
2347 | 14 | NULL, HFILL } |
2348 | 14 | }, |
2349 | 14 | { &hf_pim_source_ja_value, |
2350 | 14 | { "Value", "pim.source_ja.value", |
2351 | 14 | FT_BYTES, BASE_NONE, NULL, 0x0, |
2352 | 14 | NULL, HFILL } |
2353 | 14 | }, |
2354 | 14 | { &hf_pim_srcount, |
2355 | 14 | { "Source Count", "pim.srccount", |
2356 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, |
2357 | 14 | "Number of sources.", HFILL } |
2358 | 14 | }, |
2359 | 14 | { &hf_pim_srcholdt, |
2360 | 14 | { "Source Holdtime", "pim.srcholdtime", |
2361 | 14 | FT_UINT16, BASE_DEC|BASE_SPECIAL_VALS, VALS(unique_infinity_t), 0x0, |
2362 | 14 | "The amount of time a receiver must keep the source reachable, in seconds.", HFILL } |
2363 | 14 | }, |
2364 | 14 | { &hf_pim_transitivetype, |
2365 | 14 | { "Transitive Type", "pim.transitivetype", |
2366 | 14 | FT_BOOLEAN, 8, NULL, 0x80, |
2367 | 14 | "Set to 1 if this type is to be forwarded even if a router does not support it.", HFILL } |
2368 | 14 | }, |
2369 | 14 | { &hf_pfm_no_forward_bit, |
2370 | 14 | { "Pfm no forward bit", "pim.pfmnoforwardbit", |
2371 | 14 | FT_BOOLEAN, 8, NULL, 0x80, |
2372 | 14 | "When set, this bit means that the PFM message is not to be forwarded.", HFILL } |
2373 | 14 | }, |
2374 | 14 | { &hf_pim_reg_stop_p_bit, |
2375 | 14 | { "P-bit", "pim.packedregstoppbit", |
2376 | 14 | FT_BOOLEAN, 8, NULL, 0x01, |
2377 | 14 | "RP is indicating Register-Packing capability (RFC9465).", HFILL } |
2378 | 14 | } |
2379 | 14 | }; |
2380 | | |
2381 | 14 | static int *ett[] = { |
2382 | 14 | &ett_pim, |
2383 | 14 | &ett_pim_opts, /* Tree for all options */ |
2384 | 14 | &ett_pim_opt, /* Tree for each option */ |
2385 | 14 | &ett_pim_addr_flags /* Tree for flags */ |
2386 | 14 | }; |
2387 | | |
2388 | 14 | static ei_register_info ei[] = { |
2389 | 14 | { &ei_pim_cksum, { "pim.bad_checksum", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }}, |
2390 | 14 | { &ei_pim_unknown_src_type, { "pim.unsupported_address_family", PI_UNDECODED, PI_ERROR, "Unsupported address family type", EXPFILL }} |
2391 | 14 | }; |
2392 | | |
2393 | 14 | expert_module_t* expert_pim; |
2394 | 14 | module_t *pim_module; |
2395 | | |
2396 | 14 | proto_pim = proto_register_protocol("Protocol Independent Multicast", "PIM", "pim"); |
2397 | 14 | proto_register_field_array(proto_pim, hf, array_length(hf)); |
2398 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
2399 | 14 | expert_pim = expert_register_protocol(proto_pim); |
2400 | 14 | expert_register_field_array(expert_pim, ei, array_length(ei)); |
2401 | | |
2402 | 14 | pim_handle = register_dissector("pim", dissect_pim, proto_pim); |
2403 | 14 | pimv1_handle = register_dissector("pimv1", dissect_pimv1, proto_pim); |
2404 | | |
2405 | 14 | pim_module = prefs_register_protocol(proto_pim, NULL); |
2406 | 14 | prefs_register_bool_preference(pim_module, "payload_tree", |
2407 | 14 | "PIM payload shown on main tree", |
2408 | 14 | "Whether the PIM payload is shown off of the main tree or encapsulated within the PIM options", |
2409 | 14 | &use_main_tree); |
2410 | | |
2411 | 14 | } |
2412 | | |
2413 | | void |
2414 | | proto_reg_handoff_pim(void) |
2415 | 14 | { |
2416 | 14 | dissector_add_uint("ip.proto", IP_PROTO_PIM, pim_handle); |
2417 | 14 | dissector_add_uint("igmp.type", IGMP_V1_PIM_ROUTING_MESSAGE, pimv1_handle); |
2418 | | |
2419 | | /* |
2420 | | * Get handles for the IPv4 and IPv6 dissectors. |
2421 | | */ |
2422 | 14 | ip_handle = find_dissector_add_dependency("ip", proto_pim); |
2423 | 14 | ipv6_handle = find_dissector_add_dependency("ipv6", proto_pim); |
2424 | 14 | } |
2425 | | |
2426 | | /* |
2427 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
2428 | | * |
2429 | | * Local variables: |
2430 | | * c-basic-offset: 4 |
2431 | | * tab-width: 8 |
2432 | | * indent-tabs-mode: nil |
2433 | | * End: |
2434 | | * |
2435 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
2436 | | * :indentSize=4:tabSize=8:noTabs=true: |
2437 | | */ |