/src/wireshark/epan/dissectors/packet-bfd.c
Line | Count | Source |
1 | | /* packet-bfd.c |
2 | | * Routines for Bidirectional Forwarding Detection (BFD) message dissection |
3 | | * RFCs |
4 | | * 5880: Bidirectional Forwarding Detection (BFD) |
5 | | * 5881: Bidirectional Forwarding Detection (BFD) for IPv4 and IPv6 (Single Hop) |
6 | | * 5882: Generic Application of Bidirectional Forwarding Detection (BFD) |
7 | | * 5883: Bidirectional Forwarding Detection (BFD) for Multihop Paths |
8 | | * 5884: Bidirectional Forwarding Detection (BFD) for MPLS Label Switched Paths (LSPs) |
9 | | * 5885: Bidirectional Forwarding Detection (BFD) for the Pseudowire Virtual Circuit Connectivity Verification (VCCV) |
10 | | * 7130: Bidirectional Forwarding Detection (BFD) on Link Aggregation Group (LAG) Interfaces |
11 | | * 7881: Seamless Bidirectional Forwarding Detection (S-BFD) for IPv4, IPv6, and MPLS |
12 | | * (and https://tools.ietf.org/html/draft-ietf-bfd-base-01 for version 0) |
13 | | * |
14 | | * Copyright 2003, Hannes Gredler <hannes@juniper.net> |
15 | | * Copyright 2006, Balint Reczey <Balint.Reczey@ericsson.com> |
16 | | * Copyright 2007, Todd J Martin <todd.martin@acm.org> |
17 | | * |
18 | | * Copyright 2011, Jaihari Kalijanakiraman <jaiharik@ipinfusion.com> |
19 | | * Krishnamurthy Mayya <krishnamurthy.mayya@ipinfusion.com> |
20 | | * Nikitha Malgi <malgi.nikitha@ipinfusion.com> |
21 | | * - support for MPLS-TP BFD Proactive CV Message Format as per RFC 6428 |
22 | | * - includes decoding support for Section MEP-ID, LSP MEP-ID, PW MEP-ID |
23 | | * |
24 | | * Wireshark - Network traffic analyzer |
25 | | * By Gerald Combs <gerald@wireshark.org> |
26 | | * Copyright 1998 Gerald Combs |
27 | | * |
28 | | * SPDX-License-Identifier: GPL-2.0-or-later |
29 | | */ |
30 | | |
31 | | #include "config.h" |
32 | | |
33 | | #include <epan/packet.h> |
34 | | #include <epan/expert.h> |
35 | | #include <epan/tfs.h> |
36 | | #include <epan/unit_strings.h> |
37 | | |
38 | | #include "packet-bfd.h" |
39 | | #include "packet-mpls.h" |
40 | | |
41 | | void proto_register_bfd(void); |
42 | | void proto_reg_handoff_bfd(void); |
43 | | |
44 | | static dissector_handle_t bfd_control_handle; |
45 | | static dissector_handle_t bfd_echo_handle; |
46 | | |
47 | | /* 3784: BFD control, 3785: BFD echo, 4784: BFD multi hop control */ |
48 | | /* 6784: BFD on LAG, 7784: seamless BFD */ |
49 | | /* https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=bfd */ |
50 | 14 | #define UDP_PORT_RANGE_BFD_CTRL "3784,4784,6784,7784" |
51 | 14 | #define UDP_PORT_BFD_ECHO 3785 |
52 | | |
53 | | /* As per RFC 6428 : https://tools.ietf.org/html/rfc6428 |
54 | | Section: 3.5 */ |
55 | 1 | #define TLV_TYPE_MPLSTP_SECTION_MEP 0 |
56 | 0 | #define TLV_TYPE_MPLSTP_LSP_MEP 1 |
57 | 0 | #define TLV_TYPE_MPLSTP_PW_MEP 2 |
58 | | |
59 | | static const value_string mplstp_mep_tlv_type_values [] = { |
60 | | { TLV_TYPE_MPLSTP_SECTION_MEP, "Section MEP-ID" }, |
61 | | { TLV_TYPE_MPLSTP_LSP_MEP, "LSP MEP-ID" }, |
62 | | { TLV_TYPE_MPLSTP_PW_MEP, "PW MEP-ID" }, |
63 | | { 0, NULL} |
64 | | }; |
65 | | static const value_string bfd_control_v0_diag_values[] = { |
66 | | { 0, "No Diagnostic" }, |
67 | | { 1, "Control Detection Time Expired" }, |
68 | | { 2, "Echo Function Failed" }, |
69 | | { 3, "Neighbor Signaled Session Down" }, |
70 | | { 4, "Forwarding Plane Reset" }, |
71 | | { 5, "Path Down" }, |
72 | | { 6, "Concatenated Path Down" }, |
73 | | { 7, "Administratively Down" }, |
74 | | { 0, NULL } |
75 | | }; |
76 | | |
77 | | static const value_string bfd_control_v1_diag_values[] = { |
78 | | { 0, "No Diagnostic" }, |
79 | | { 1, "Control Detection Time Expired" }, |
80 | | { 2, "Echo Function Failed" }, |
81 | | { 3, "Neighbor Signaled Session Down" }, |
82 | | { 4, "Forwarding Plane Reset" }, |
83 | | { 5, "Path Down" }, |
84 | | { 6, "Concatenated Path Down" }, |
85 | | { 7, "Administratively Down" }, |
86 | | { 8, "Reverse Concatenated Path Down" }, |
87 | | { 9, "Mis-Connectivity Defect" }, |
88 | | { 0, NULL } |
89 | | }; |
90 | | |
91 | | static const value_string bfd_control_sta_values[] = { |
92 | | { 0, "AdminDown" }, |
93 | | { 1, "Down" }, |
94 | | { 2, "Init" }, |
95 | | { 3, "Up" }, |
96 | | { 0, NULL } |
97 | | }; |
98 | | |
99 | 2 | #define BFD_AUTH_SIMPLE 1 |
100 | 3 | #define BFD_AUTH_MD5 2 |
101 | 6 | #define BFD_AUTH_MET_MD5 3 |
102 | 4 | #define BFD_AUTH_SHA1 4 |
103 | 6 | #define BFD_AUTH_MET_SHA1 5 |
104 | | static const value_string bfd_control_auth_type_values[] = { |
105 | | { BFD_AUTH_SIMPLE , "Simple Password" }, |
106 | | { BFD_AUTH_MD5 , "Keyed MD5" }, |
107 | | { BFD_AUTH_MET_MD5 , "Meticulous Keyed MD5" }, |
108 | | { BFD_AUTH_SHA1 , "Keyed SHA1" }, |
109 | | { BFD_AUTH_MET_SHA1 , "Meticulous Keyed SHA1" }, |
110 | | { 0, NULL } |
111 | | }; |
112 | | /* Per the standard, the simple password must by 1-16 bytes in length */ |
113 | | #define MAX_PASSWORD_LEN 16 |
114 | | /* Per the standard, the length of the MD5 authentication packets must be 24 |
115 | | * bytes and the checksum is 16 bytes */ |
116 | 2 | #define MD5_AUTH_LEN 24 |
117 | 2 | #define MD5_CHECKSUM_LEN 16 |
118 | | /* Per the standard, the length of the SHA1 authentication packets must be 28 |
119 | | * bytes and the checksum is 20 bytes */ |
120 | 2 | #define SHA1_AUTH_LEN 28 |
121 | 0 | #define SHA1_CHECKSUM_LEN 20 |
122 | | |
123 | | static int proto_bfd; |
124 | | static int proto_bfd_echo; |
125 | | |
126 | | static int hf_bfd_version; |
127 | | static int hf_bfd_diag; |
128 | | static int hf_bfd_sta; |
129 | | static int hf_bfd_flags; |
130 | | static int hf_bfd_flags_h; |
131 | | static int hf_bfd_flags_p; |
132 | | static int hf_bfd_flags_f; |
133 | | static int hf_bfd_flags_c; |
134 | | static int hf_bfd_flags_a; |
135 | | static int hf_bfd_flags_d; |
136 | | static int hf_bfd_flags_m; |
137 | | static int hf_bfd_flags_d_v0; |
138 | | static int hf_bfd_flags_p_v0; |
139 | | static int hf_bfd_flags_f_v0; |
140 | | static int hf_bfd_detect_time_multiplier; |
141 | | static int hf_bfd_message_length; |
142 | | static int hf_bfd_my_discriminator; |
143 | | static int hf_bfd_your_discriminator; |
144 | | static int hf_bfd_desired_min_tx_interval; |
145 | | static int hf_bfd_required_min_rx_interval; |
146 | | static int hf_bfd_required_min_echo_interval; |
147 | | static int hf_bfd_checksum; |
148 | | |
149 | | static int hf_bfd_auth_type; |
150 | | static int hf_bfd_auth_len; |
151 | | static int hf_bfd_auth_key; |
152 | | static int hf_bfd_auth_password; |
153 | | static int hf_bfd_auth_seq_num; |
154 | | |
155 | | static int hf_bfd_echo; |
156 | | |
157 | | static int ett_bfd; |
158 | | static int ett_bfd_flags; |
159 | | static int ett_bfd_auth; |
160 | | |
161 | | static int ett_bfd_echo; |
162 | | |
163 | | static expert_field ei_bfd_auth_len_invalid; |
164 | | static expert_field ei_bfd_auth_no_data; |
165 | | |
166 | | static int hf_mep_type; |
167 | | static int hf_mep_len; |
168 | | static int hf_mep_global_id; |
169 | | static int hf_mep_node_id; |
170 | | /* static int hf_mep_interface_no; */ |
171 | | static int hf_mep_tunnel_no; |
172 | | static int hf_mep_lsp_no; |
173 | | static int hf_mep_ac_id; |
174 | | static int hf_mep_agi_type; |
175 | | static int hf_mep_agi_len; |
176 | | static int hf_mep_agi_val; |
177 | | static int hf_section_interface_no; |
178 | | /* |
179 | | * Control packet version 0, draft-katz-ward-bfd-01.txt |
180 | | * |
181 | | * 0 1 2 3 |
182 | | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
183 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
184 | | * |Vers | Diag |H|D|P|F| Rsvd | Detect Mult | Length | |
185 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
186 | | * | My Discriminator | |
187 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
188 | | * | Your Discriminator | |
189 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
190 | | * | Desired Min TX Interval | |
191 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
192 | | * | Required Min RX Interval | |
193 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
194 | | * | Required Min Echo RX Interval | |
195 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
196 | | */ |
197 | | |
198 | | /* |
199 | | * Control packet version 1, RFC 5880 |
200 | | * |
201 | | * 0 1 2 3 |
202 | | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
203 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
204 | | * |Vers | Diag |Sta|P|F|C|A|D|M| Detect Mult | Length | |
205 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
206 | | * | My Discriminator | |
207 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
208 | | * | Your Discriminator | |
209 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
210 | | * | Desired Min TX Interval | |
211 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
212 | | * | Required Min RX Interval | |
213 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
214 | | * | Required Min Echo RX Interval | |
215 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
216 | | * |
217 | | * An optional Authentication Section may be present: |
218 | | * 0 1 2 3 |
219 | | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
220 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
221 | | * | Auth Type | Auth Len | Authentication Data... | |
222 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
223 | | * |
224 | | * There are 5 types of authentication defined: |
225 | | * 1 - Simple Password |
226 | | * 2 - Keyed MD5 |
227 | | * 3 - Meticulous Keyed MD5 |
228 | | * 4 - Keyed SHA1 |
229 | | * 5 - Meticulous Keyed SHA1 |
230 | | * |
231 | | * The format for Simple Password authentication is: |
232 | | * 0 1 2 3 |
233 | | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
234 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
235 | | * | Auth Type | Auth Len | Auth Key ID | Password... | |
236 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
237 | | * | ... | |
238 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
239 | | * |
240 | | * The format for Keyed MD5 and Meticulous Keyed MD5 authentication is: |
241 | | * 0 1 2 3 |
242 | | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
243 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
244 | | * | Auth Type | Auth Len | Auth Key ID | Reserved | |
245 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
246 | | * | Sequence Number | |
247 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
248 | | * | Auth Key/Checksum... | |
249 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
250 | | * | ... | |
251 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
252 | | * |
253 | | * The format for Keyed SHA1 and Meticulous Keyed SHA1 authentication is: |
254 | | * 0 1 2 3 |
255 | | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
256 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
257 | | * | Auth Type | Auth Len | Auth Key ID | Reserved | |
258 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
259 | | * | Sequence Number | |
260 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
261 | | * | Auth Key/Checksum... | |
262 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
263 | | * | ... | |
264 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
265 | | * |
266 | | * |
267 | | */ |
268 | | |
269 | | |
270 | | /* Given the type of authentication being used, return the required length of |
271 | | * the authentication header |
272 | | */ |
273 | | static uint8_t |
274 | | get_bfd_required_auth_len(uint8_t auth_type) |
275 | 4 | { |
276 | 4 | uint8_t auth_len = 0; |
277 | | |
278 | 4 | switch (auth_type) { |
279 | 1 | case BFD_AUTH_MD5: |
280 | 2 | case BFD_AUTH_MET_MD5: |
281 | 2 | auth_len = MD5_AUTH_LEN; |
282 | 2 | break; |
283 | 1 | case BFD_AUTH_SHA1: |
284 | 2 | case BFD_AUTH_MET_SHA1: |
285 | 2 | auth_len = SHA1_AUTH_LEN; |
286 | 2 | break; |
287 | 0 | default: |
288 | 0 | break; |
289 | 4 | } |
290 | 4 | return auth_len; |
291 | 4 | } |
292 | | |
293 | | /* Given the type of authentication being used, return the length of |
294 | | * checksum field |
295 | | */ |
296 | | static uint8_t |
297 | | get_bfd_checksum_len(uint8_t auth_type) |
298 | 2 | { |
299 | 2 | uint8_t checksum_len = 0; |
300 | 2 | switch (auth_type) { |
301 | 1 | case BFD_AUTH_MD5: |
302 | 2 | case BFD_AUTH_MET_MD5: |
303 | 2 | checksum_len = MD5_CHECKSUM_LEN; |
304 | 2 | break; |
305 | 0 | case BFD_AUTH_SHA1: |
306 | 0 | case BFD_AUTH_MET_SHA1: |
307 | 0 | checksum_len = SHA1_CHECKSUM_LEN; |
308 | 0 | break; |
309 | 0 | default: |
310 | 0 | break; |
311 | 2 | } |
312 | 2 | return checksum_len; |
313 | 2 | } |
314 | | |
315 | | static void |
316 | | dissect_bfd_authentication(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) |
317 | 9 | { |
318 | 9 | int offset = 24; |
319 | 9 | uint8_t auth_type; |
320 | 9 | uint8_t auth_len; |
321 | 9 | proto_item *auth_item = NULL; |
322 | 9 | proto_tree *auth_tree = NULL; |
323 | 9 | const uint8_t *password; |
324 | | |
325 | 9 | auth_type = tvb_get_uint8(tvb, offset); |
326 | 9 | auth_len = tvb_get_uint8(tvb, offset + 1); |
327 | | |
328 | 9 | if (tree) { |
329 | 9 | auth_tree = proto_tree_add_subtree_format(tree, tvb, offset, auth_len, |
330 | 9 | ett_bfd_auth, NULL, "Authentication: %s", |
331 | 9 | val_to_str(pinfo->pool, auth_type, |
332 | 9 | bfd_control_auth_type_values, |
333 | 9 | "Unknown Authentication Type (%d)") ); |
334 | | |
335 | 9 | proto_tree_add_item(auth_tree, hf_bfd_auth_type, tvb, offset, 1, ENC_BIG_ENDIAN); |
336 | | |
337 | 9 | proto_tree_add_item(auth_tree, hf_bfd_auth_len, tvb, offset + 1, 1, ENC_BIG_ENDIAN); |
338 | | |
339 | 9 | proto_tree_add_item(auth_tree, hf_bfd_auth_key, tvb, offset + 2, 1, ENC_BIG_ENDIAN); |
340 | 9 | } |
341 | | |
342 | 9 | switch (auth_type) { |
343 | 2 | case BFD_AUTH_SIMPLE: |
344 | 2 | proto_tree_add_item_ret_string(auth_tree, hf_bfd_auth_password, tvb, offset+3, |
345 | 2 | auth_len-3, ENC_ASCII|ENC_NA, pinfo->pool, &password); |
346 | 2 | proto_item_append_text(auth_item, ": %s", password); |
347 | 2 | break; |
348 | 1 | case BFD_AUTH_MD5: |
349 | 2 | case BFD_AUTH_MET_MD5: |
350 | 3 | case BFD_AUTH_SHA1: |
351 | 4 | case BFD_AUTH_MET_SHA1: |
352 | 4 | if (auth_len != get_bfd_required_auth_len(auth_type)) { |
353 | 4 | proto_tree_add_expert_format(auth_tree, pinfo, &ei_bfd_auth_len_invalid, tvb, offset, auth_len, |
354 | 4 | "Length of authentication section (%d) is invalid for Authentication Type: %s", |
355 | 4 | auth_len, val_to_str(pinfo->pool, auth_type, bfd_control_auth_type_values, "Unknown Authentication Type (%d)") ); |
356 | | |
357 | 4 | proto_item_append_text(auth_item, ": Invalid Authentication Section"); |
358 | 4 | } |
359 | | |
360 | 4 | if (tree) { |
361 | 2 | proto_tree_add_item(auth_tree, hf_bfd_auth_seq_num, tvb, offset+4, 4, ENC_BIG_ENDIAN); |
362 | | |
363 | 2 | proto_tree_add_item(auth_tree, hf_bfd_checksum, tvb, offset+8, get_bfd_checksum_len(auth_type), ENC_NA); |
364 | 2 | } |
365 | 4 | break; |
366 | 1 | default: |
367 | 1 | break; |
368 | 9 | } |
369 | 9 | } |
370 | | |
371 | | static int |
372 | | dissect_bfd_echo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
373 | 0 | { |
374 | 0 | proto_tree *bfd_tree = NULL; |
375 | 0 | unsigned bfd_length = tvb_reported_length_remaining(tvb, 0); |
376 | |
|
377 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "BFD Echo"); |
378 | | /* XXX Add direction */ |
379 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Originator specific content"); |
380 | |
|
381 | 0 | if (tree) { |
382 | 0 | proto_item *ti; |
383 | |
|
384 | 0 | ti = proto_tree_add_protocol_format(tree, proto_bfd_echo, tvb, 0, bfd_length, |
385 | 0 | "BFD Echo message"); |
386 | |
|
387 | 0 | bfd_tree = proto_item_add_subtree(ti, ett_bfd_echo); |
388 | |
|
389 | 0 | proto_tree_add_item(bfd_tree, hf_bfd_echo, tvb, 0, bfd_length, ENC_NA); |
390 | 0 | } |
391 | |
|
392 | 0 | return bfd_length; |
393 | 0 | } |
394 | | |
395 | | static int |
396 | | dissect_bfd_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
397 | 19 | { |
398 | 19 | unsigned flags; |
399 | 19 | unsigned bfd_version; |
400 | 19 | unsigned bfd_diag; |
401 | 19 | unsigned bfd_sta = 0; |
402 | 19 | unsigned bfd_flags; |
403 | 19 | unsigned bfd_flags_a = 0; |
404 | 19 | unsigned bfd_detect_time_multiplier; |
405 | 19 | unsigned bfd_length; |
406 | 19 | unsigned bfd_my_discriminator; |
407 | 19 | unsigned bfd_your_discriminator; |
408 | 19 | unsigned bfd_desired_min_tx_interval; |
409 | 19 | unsigned bfd_required_min_rx_interval; |
410 | 19 | unsigned bfd_required_min_echo_interval; |
411 | 19 | proto_tree *bfd_tree = NULL; |
412 | | |
413 | 19 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "BFD Control"); |
414 | 19 | col_clear(pinfo->cinfo, COL_INFO); |
415 | | |
416 | 19 | bfd_version = (tvb_get_uint8(tvb, 0) & 0xe0) >> 5; |
417 | 19 | bfd_diag = (tvb_get_uint8(tvb, 0) & 0x1f); |
418 | 19 | flags = tvb_get_uint8(tvb, 1); |
419 | 19 | switch (bfd_version) { |
420 | 4 | case 0: |
421 | 4 | bfd_flags = flags; |
422 | 4 | break; |
423 | 3 | case 1: |
424 | 15 | default: |
425 | 15 | bfd_sta = flags & 0xc0; |
426 | 15 | bfd_flags = flags & 0x3e; |
427 | 15 | bfd_flags_a = flags & 0x04; |
428 | 15 | break; |
429 | 19 | } |
430 | | |
431 | 19 | bfd_detect_time_multiplier = tvb_get_uint8(tvb, 2); |
432 | 19 | bfd_length = tvb_get_uint8(tvb, 3); |
433 | 19 | bfd_my_discriminator = tvb_get_ntohl(tvb, 4); |
434 | 19 | bfd_your_discriminator = tvb_get_ntohl(tvb, 8); |
435 | 19 | bfd_desired_min_tx_interval = tvb_get_ntohl(tvb, 12); |
436 | 19 | bfd_required_min_rx_interval = tvb_get_ntohl(tvb, 16); |
437 | 19 | bfd_required_min_echo_interval = tvb_get_ntohl(tvb, 20); |
438 | | |
439 | 19 | switch (bfd_version) { |
440 | 2 | case 0: |
441 | 2 | col_add_fstr(pinfo->cinfo, COL_INFO, "Diag: %s, Flags: 0x%02x", |
442 | 2 | val_to_str_const(bfd_diag, bfd_control_v0_diag_values, "Unknown"), |
443 | 2 | bfd_flags); |
444 | 2 | break; |
445 | 3 | case 1: |
446 | 14 | default: |
447 | 14 | col_add_fstr(pinfo->cinfo, COL_INFO, "Diag: %s, State: %s, Flags: 0x%02x", |
448 | 14 | val_to_str_const(bfd_diag, bfd_control_v1_diag_values, "Unknown"), |
449 | 14 | val_to_str_const(bfd_sta >> 6 , bfd_control_sta_values, "Unknown"), |
450 | 14 | bfd_flags); |
451 | 14 | break; |
452 | 19 | } |
453 | | |
454 | 16 | if (tree) { |
455 | 16 | proto_item *ti; |
456 | | |
457 | 16 | ti = proto_tree_add_protocol_format(tree, proto_bfd, tvb, 0, bfd_length, |
458 | 16 | "BFD Control message"); |
459 | | |
460 | 16 | bfd_tree = proto_item_add_subtree(ti, ett_bfd); |
461 | | |
462 | 16 | proto_tree_add_uint(bfd_tree, hf_bfd_version, tvb, 0, |
463 | 16 | 1, bfd_version << 5); |
464 | | |
465 | 16 | proto_tree_add_uint(bfd_tree, hf_bfd_diag, tvb, 0, |
466 | 16 | 1, bfd_diag); |
467 | | |
468 | 16 | switch (bfd_version) { |
469 | 2 | case 0: |
470 | 2 | break; |
471 | 3 | case 1: |
472 | 14 | default: |
473 | 14 | proto_tree_add_uint(bfd_tree, hf_bfd_sta, tvb, 1, |
474 | 14 | 1, bfd_sta); |
475 | | |
476 | 14 | break; |
477 | 16 | } |
478 | 16 | switch (bfd_version) { |
479 | 2 | case 0: |
480 | 2 | { |
481 | 2 | static int * const bfd_message_flags[] = { |
482 | 2 | &hf_bfd_flags_h, |
483 | 2 | &hf_bfd_flags_d_v0, |
484 | 2 | &hf_bfd_flags_p_v0, |
485 | 2 | &hf_bfd_flags_f_v0, |
486 | 2 | NULL |
487 | 2 | }; |
488 | 2 | proto_tree_add_bitmask_with_flags(bfd_tree, tvb, 1, hf_bfd_flags, ett_bfd_flags, bfd_message_flags, ENC_NA, BMT_NO_FALSE); |
489 | 2 | } |
490 | 2 | break; |
491 | 3 | case 1: |
492 | 14 | default: |
493 | 14 | { |
494 | 14 | static int * const bfd_message_flags[] = { |
495 | 14 | &hf_bfd_flags_p, |
496 | 14 | &hf_bfd_flags_f, |
497 | 14 | &hf_bfd_flags_c, |
498 | 14 | &hf_bfd_flags_a, |
499 | 14 | &hf_bfd_flags_d, |
500 | 14 | &hf_bfd_flags_m, |
501 | 14 | NULL |
502 | 14 | }; |
503 | 14 | proto_tree_add_bitmask_with_flags(bfd_tree, tvb, 1, hf_bfd_flags, ett_bfd_flags, bfd_message_flags, ENC_NA, BMT_NO_FALSE); |
504 | 14 | } |
505 | 14 | break; |
506 | 16 | } |
507 | | |
508 | 16 | proto_tree_add_uint_format_value(bfd_tree, hf_bfd_detect_time_multiplier, tvb, 2, |
509 | 16 | 1, bfd_detect_time_multiplier, |
510 | 16 | "%u (= %u ms Detection time)", |
511 | 16 | bfd_detect_time_multiplier, |
512 | 16 | bfd_detect_time_multiplier * (bfd_desired_min_tx_interval/1000)); |
513 | | |
514 | 16 | proto_tree_add_uint(bfd_tree, hf_bfd_message_length, tvb, 3, 1, bfd_length); |
515 | | |
516 | 16 | proto_tree_add_uint(bfd_tree, hf_bfd_my_discriminator, tvb, 4, |
517 | 16 | 4, bfd_my_discriminator); |
518 | | |
519 | 16 | proto_tree_add_uint(bfd_tree, hf_bfd_your_discriminator, tvb, 8, |
520 | 16 | 4, bfd_your_discriminator); |
521 | | |
522 | 16 | proto_tree_add_uint_format_value(bfd_tree, hf_bfd_desired_min_tx_interval, tvb, 12, |
523 | 16 | 4, bfd_desired_min_tx_interval, |
524 | 16 | "%4u ms (%u us)", |
525 | 16 | bfd_desired_min_tx_interval/1000, |
526 | 16 | bfd_desired_min_tx_interval); |
527 | | |
528 | 16 | proto_tree_add_uint_format_value(bfd_tree, hf_bfd_required_min_rx_interval, tvb, 16, |
529 | 16 | 4, bfd_required_min_rx_interval, |
530 | 16 | "%4u ms (%u us)", |
531 | 16 | bfd_required_min_rx_interval/1000, |
532 | 16 | bfd_required_min_rx_interval); |
533 | | |
534 | 16 | proto_tree_add_uint_format_value(bfd_tree, hf_bfd_required_min_echo_interval, tvb, 20, |
535 | 16 | 4, bfd_required_min_echo_interval, |
536 | 16 | "%4u ms (%u us)", |
537 | 16 | bfd_required_min_echo_interval/1000, |
538 | 16 | bfd_required_min_echo_interval); |
539 | 16 | } /* if (tree) */ |
540 | | |
541 | | /* Dissect the authentication fields if the Authentication flag has |
542 | | * been set |
543 | | */ |
544 | 16 | if (bfd_version && bfd_flags_a) { |
545 | 11 | if (bfd_length >= 28) { |
546 | 9 | dissect_bfd_authentication(tvb, pinfo, bfd_tree); |
547 | 9 | } else { |
548 | 2 | proto_tree_add_expert_format(bfd_tree, pinfo, &ei_bfd_auth_no_data, tvb, 24, bfd_length-24, |
549 | 2 | "Authentication: Length of the BFD frame is invalid (%d)", bfd_length); |
550 | 2 | } |
551 | 11 | } |
552 | | |
553 | 16 | return tvb_captured_length(tvb); |
554 | 16 | } |
555 | | |
556 | | /* BFD CV Source MEP-ID TLV Decoder, |
557 | | As per RFC 6428 : https://tools.ietf.org/html/rfc6428 |
558 | | sections - 3.5.1, 3.5.2, 3.5.3 */ |
559 | | void |
560 | | dissect_bfd_mep (tvbuff_t *tvb, proto_tree *tree, const int hfindex) |
561 | 2 | { |
562 | 2 | proto_item *ti; |
563 | 2 | proto_tree *bfd_tree; |
564 | 2 | int offset = 0; |
565 | 2 | int mep_type; |
566 | 2 | int mep_len; |
567 | 2 | int mep_agi_len; |
568 | | |
569 | 2 | if (!tree) |
570 | 0 | return; |
571 | | |
572 | | /* Fetch the BFD control message length and move the offset |
573 | | to point to the data portion after the control message */ |
574 | | |
575 | | /* The parameter hfindex is used for determining the tree under which MEP-ID TLV |
576 | | has to be determined. Since according to RFC 6428, MEP-ID TLV can be used by any |
577 | | OAM function, if hfindex is 0, as per this function the MEP-TLV is a part of |
578 | | BFD-CV payload. If a non-zero hfindex comes, then tht TLV info will be displayed |
579 | | under a particular protocol-tree. */ |
580 | 2 | if (!hfindex) |
581 | 0 | { |
582 | 0 | offset = tvb_get_uint8(tvb, 3); |
583 | 0 | mep_type = tvb_get_ntohs (tvb, offset); |
584 | 0 | mep_len = tvb_get_ntohs (tvb, (offset + 2)); |
585 | 0 | ti = proto_tree_add_protocol_format (tree, proto_bfd, tvb, offset, (mep_len + 4), |
586 | 0 | "MPLS-TP SOURCE MEP-ID TLV"); |
587 | 0 | } |
588 | 2 | else |
589 | 2 | { |
590 | 2 | mep_type = tvb_get_ntohs (tvb, offset); |
591 | 2 | mep_len = tvb_get_ntohs (tvb, (offset + 2)); |
592 | 2 | ti = proto_tree_add_protocol_format (tree, hfindex, tvb, offset, (mep_len + 4), |
593 | 2 | "MPLS-TP SOURCE MEP-ID TLV"); |
594 | 2 | } |
595 | | |
596 | 2 | switch (mep_type) { |
597 | 1 | case TLV_TYPE_MPLSTP_SECTION_MEP: |
598 | | |
599 | 1 | bfd_tree = proto_item_add_subtree (ti, ett_bfd); |
600 | 1 | proto_tree_add_uint (bfd_tree, hf_mep_type , tvb, offset, |
601 | 1 | 2, mep_type); |
602 | 1 | proto_tree_add_uint (bfd_tree, hf_mep_len, tvb, (offset + 2), |
603 | 1 | 2, mep_len); |
604 | 1 | proto_tree_add_item (bfd_tree, hf_mep_global_id, tvb, (offset + 4), |
605 | 1 | 4, ENC_BIG_ENDIAN); |
606 | 1 | proto_tree_add_item (bfd_tree, hf_mep_node_id, tvb, (offset + 8), |
607 | 1 | 4, ENC_BIG_ENDIAN); |
608 | 1 | proto_tree_add_item (bfd_tree, hf_section_interface_no, tvb, (offset + 12), |
609 | 1 | 4, ENC_BIG_ENDIAN); |
610 | | |
611 | 1 | break; |
612 | | |
613 | 0 | case TLV_TYPE_MPLSTP_LSP_MEP: |
614 | |
|
615 | 0 | bfd_tree = proto_item_add_subtree (ti, ett_bfd); |
616 | 0 | proto_tree_add_uint (bfd_tree, hf_mep_type , tvb, offset, |
617 | 0 | 2, mep_type); |
618 | 0 | proto_tree_add_uint (bfd_tree, hf_mep_len, tvb, (offset + 2), |
619 | 0 | 2, mep_len); |
620 | 0 | proto_tree_add_item (bfd_tree, hf_mep_global_id, tvb, (offset + 4), |
621 | 0 | 4, ENC_BIG_ENDIAN); |
622 | 0 | proto_tree_add_item (bfd_tree, hf_mep_node_id, tvb, (offset + 8), |
623 | 0 | 4, ENC_BIG_ENDIAN); |
624 | 0 | proto_tree_add_item (bfd_tree, hf_mep_tunnel_no, tvb, (offset + 12), |
625 | 0 | 2, ENC_BIG_ENDIAN); |
626 | 0 | proto_tree_add_item (bfd_tree, hf_mep_lsp_no, tvb, (offset + 14), |
627 | 0 | 2, ENC_BIG_ENDIAN); |
628 | |
|
629 | 0 | break; |
630 | | |
631 | 0 | case TLV_TYPE_MPLSTP_PW_MEP: |
632 | |
|
633 | 0 | mep_agi_len = tvb_get_uint8 (tvb, (offset + 17)); |
634 | 0 | bfd_tree = proto_item_add_subtree (ti, ett_bfd); |
635 | 0 | proto_tree_add_uint (bfd_tree, hf_mep_type, tvb, offset, |
636 | 0 | 2, (mep_type)); |
637 | 0 | proto_tree_add_uint (bfd_tree, hf_mep_len, tvb, (offset + 2), |
638 | 0 | 2, mep_len); |
639 | 0 | proto_tree_add_item (bfd_tree, hf_mep_global_id, tvb, (offset + 4), |
640 | 0 | 4, ENC_BIG_ENDIAN); |
641 | 0 | proto_tree_add_item (bfd_tree, hf_mep_node_id, tvb, (offset + 8), |
642 | 0 | 4, ENC_BIG_ENDIAN); |
643 | 0 | proto_tree_add_item (bfd_tree, hf_mep_ac_id, tvb, (offset + 12), |
644 | 0 | 4, ENC_BIG_ENDIAN); |
645 | 0 | proto_tree_add_item (bfd_tree, hf_mep_agi_type, tvb, (offset + 16), |
646 | 0 | 1, ENC_BIG_ENDIAN); |
647 | 0 | proto_tree_add_uint (bfd_tree, hf_mep_agi_len, tvb, (offset + 17), |
648 | 0 | 1, mep_agi_len); |
649 | 0 | proto_tree_add_item (bfd_tree, hf_mep_agi_val, tvb, (offset + 18), |
650 | 0 | mep_agi_len, ENC_ASCII); |
651 | |
|
652 | 0 | break; |
653 | | |
654 | 1 | default: |
655 | 1 | break; |
656 | 2 | } |
657 | 2 | return; |
658 | 2 | } |
659 | | |
660 | | /* Register the protocol with Wireshark */ |
661 | | void |
662 | | proto_register_bfd(void) |
663 | 14 | { |
664 | | |
665 | | /* Setup list of header fields */ |
666 | 14 | static hf_register_info hf[] = { |
667 | 14 | { &hf_bfd_version, |
668 | 14 | { "Protocol Version", "bfd.version", |
669 | 14 | FT_UINT8, BASE_DEC, NULL , 0xe0, |
670 | 14 | "The version number of the BFD protocol", HFILL } |
671 | 14 | }, |
672 | 14 | { &hf_bfd_diag, |
673 | 14 | { "Diagnostic Code", "bfd.diag", |
674 | 14 | FT_UINT8, BASE_HEX, VALS(bfd_control_v1_diag_values), 0x1f, |
675 | 14 | "This field give the reason for a BFD session failure", HFILL } |
676 | 14 | }, |
677 | 14 | { &hf_bfd_sta, |
678 | 14 | { "Session State", "bfd.sta", |
679 | 14 | FT_UINT8, BASE_HEX, VALS(bfd_control_sta_values), 0xc0, |
680 | 14 | "The BFD state as seen by the transmitting system", HFILL } |
681 | 14 | }, |
682 | 14 | { &hf_bfd_flags, |
683 | 14 | { "Message Flags", "bfd.flags", |
684 | 14 | FT_UINT8, BASE_HEX, NULL, 0x00, |
685 | 14 | NULL, HFILL } |
686 | 14 | }, |
687 | 14 | { &hf_bfd_flags_h, |
688 | 14 | { "I hear you", "bfd.flags.h", |
689 | 14 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x80, |
690 | 14 | NULL, HFILL } |
691 | 14 | }, |
692 | 14 | { &hf_bfd_flags_d_v0, |
693 | 14 | { "Demand", "bfd.flags.d", |
694 | 14 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x40, |
695 | 14 | NULL, HFILL } |
696 | 14 | }, |
697 | 14 | { &hf_bfd_flags_p_v0, |
698 | 14 | { "Poll", "bfd.flags.p", |
699 | 14 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x20, |
700 | 14 | NULL, HFILL } |
701 | 14 | }, |
702 | 14 | { &hf_bfd_flags_f_v0, |
703 | 14 | { "Final", "bfd.flags.f", |
704 | 14 | FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x10, |
705 | 14 | NULL, HFILL } |
706 | 14 | }, |
707 | 14 | { &hf_bfd_flags_p, |
708 | 14 | { "Poll", "bfd.flags.p", |
709 | 14 | FT_BOOLEAN, 6, TFS(&tfs_set_notset), 0x20, /* 6 flag bits; Sta is shown separately */ |
710 | 14 | "If set, the transmitting system is expecting a packet with the Final (F) bit in reply", |
711 | 14 | HFILL } |
712 | 14 | }, |
713 | 14 | { &hf_bfd_flags_f, |
714 | 14 | { "Final", "bfd.flags.f", |
715 | 14 | FT_BOOLEAN, 6, TFS(&tfs_set_notset), 0x10, /* 6 flag bits; Sta is shown separately */ |
716 | 14 | "If set, the transmitting system is replying to a packet with the Poll (P) bit set", |
717 | 14 | HFILL } |
718 | 14 | }, |
719 | 14 | { &hf_bfd_flags_c, |
720 | 14 | { "Control Plane Independent", "bfd.flags.c", |
721 | 14 | FT_BOOLEAN, 6, TFS(&tfs_set_notset), 0x08, /* 6 flag bits; Sta is shown separately */ |
722 | 14 | "If set, the BFD implementation is implemented in the forwarding plane", HFILL } |
723 | 14 | }, |
724 | 14 | { &hf_bfd_flags_a, |
725 | 14 | { "Authentication Present", "bfd.flags.a", |
726 | 14 | FT_BOOLEAN, 6, TFS(&tfs_set_notset), 0x04, /* 6 flag bits; Sta is shown separately */ |
727 | 14 | "The Authentication Section is present", HFILL } |
728 | 14 | }, |
729 | 14 | { &hf_bfd_flags_d, |
730 | 14 | { "Demand", "bfd.flags.d", |
731 | 14 | FT_BOOLEAN, 6, TFS(&tfs_set_notset), 0x02, /* 6 flag bits; Sta is shown separately */ |
732 | 14 | "If set, Demand mode is active in the transmitting system", HFILL } |
733 | 14 | }, |
734 | 14 | { &hf_bfd_flags_m, |
735 | 14 | { "Multipoint", "bfd.flags.m", |
736 | 14 | FT_BOOLEAN, 6, TFS(&tfs_set_notset), 0x01, /* 6 flag bits; Sta is shown separately */ |
737 | 14 | "Reserved for future point-to-multipoint extensions", HFILL } |
738 | 14 | }, |
739 | 14 | { &hf_bfd_detect_time_multiplier, |
740 | 14 | { "Detect Time Multiplier", "bfd.detect_time_multiplier", |
741 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
742 | 14 | "The transmit interval multiplied by this value is the failure detection time", HFILL } |
743 | 14 | }, |
744 | 14 | { &hf_bfd_message_length, |
745 | 14 | { "Message Length", "bfd.message_length", |
746 | 14 | FT_UINT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0, |
747 | 14 | "Length of the BFD Control packet, in bytes", HFILL } |
748 | 14 | }, |
749 | 14 | { &hf_bfd_my_discriminator, |
750 | 14 | { "My Discriminator", "bfd.my_discriminator", |
751 | 14 | FT_UINT32, BASE_HEX, NULL, 0x0, |
752 | 14 | NULL, HFILL } |
753 | 14 | }, |
754 | 14 | { &hf_bfd_your_discriminator, |
755 | 14 | { "Your Discriminator", "bfd.your_discriminator", |
756 | 14 | FT_UINT32, BASE_HEX, NULL, 0x0, |
757 | 14 | NULL, HFILL } |
758 | 14 | }, |
759 | 14 | { &hf_bfd_desired_min_tx_interval, |
760 | 14 | { "Desired Min TX Interval", "bfd.desired_min_tx_interval", |
761 | 14 | FT_UINT32, BASE_DEC, NULL, 0x0, |
762 | 14 | "The minimum interval to use when transmitting BFD Control packets", HFILL } |
763 | 14 | }, |
764 | 14 | { &hf_bfd_required_min_rx_interval, |
765 | 14 | { "Required Min RX Interval", "bfd.required_min_rx_interval", |
766 | 14 | FT_UINT32, BASE_DEC, NULL, 0x0, |
767 | 14 | "The minimum interval between received BFD Control packets that this system can support", HFILL } |
768 | 14 | }, |
769 | 14 | { &hf_bfd_required_min_echo_interval, |
770 | 14 | { "Required Min Echo Interval", "bfd.required_min_echo_interval", |
771 | 14 | FT_UINT32, BASE_DEC, NULL, 0x0, |
772 | 14 | "The minimum interval between received BFD Echo packets that this system can support", HFILL } |
773 | 14 | }, |
774 | 14 | { &hf_bfd_checksum, |
775 | 14 | { "Checksum", "bfd.checksum", |
776 | 14 | FT_BYTES, BASE_NONE, NULL, 0x0, |
777 | 14 | NULL, HFILL } |
778 | 14 | }, |
779 | 14 | { &hf_bfd_auth_type, |
780 | 14 | { "Authentication Type", "bfd.auth.type", |
781 | 14 | FT_UINT8, BASE_DEC, VALS(bfd_control_auth_type_values), 0x0, |
782 | 14 | "The type of authentication in use on this session", HFILL } |
783 | 14 | }, |
784 | 14 | { &hf_bfd_auth_len, |
785 | 14 | { "Authentication Length", "bfd.auth.len", |
786 | 14 | FT_UINT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0, |
787 | 14 | "The length, in bytes, of the authentication section", HFILL } |
788 | 14 | }, |
789 | 14 | { &hf_bfd_auth_key, |
790 | 14 | { "Authentication Key ID", "bfd.auth.key", |
791 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, |
792 | 14 | "The Authentication Key ID, identifies which password is in use for this packet", HFILL } |
793 | 14 | }, |
794 | 14 | { &hf_bfd_auth_password, |
795 | 14 | { "Password", "bfd.auth.password", |
796 | 14 | FT_STRING, BASE_NONE, NULL, 0x0, |
797 | 14 | "The simple password in use on this session", HFILL } |
798 | 14 | }, |
799 | 14 | { &hf_bfd_auth_seq_num, |
800 | 14 | { "Sequence Number", "bfd.auth.seq_num", |
801 | 14 | FT_UINT32, BASE_HEX, NULL, 0x0, |
802 | 14 | "The Sequence Number is periodically incremented to prevent replay attacks", HFILL } |
803 | 14 | }, |
804 | 14 | { &hf_mep_type, |
805 | 14 | { "Type", "bfd.mep.type", |
806 | 14 | FT_UINT16, BASE_DEC, VALS(mplstp_mep_tlv_type_values), 0x0, |
807 | 14 | "The type of the MEP Id", HFILL } |
808 | 14 | }, |
809 | 14 | { &hf_mep_len, |
810 | 14 | { "Length", "bfd.mep.len", |
811 | 14 | FT_UINT16, BASE_DEC, NULL , 0x0, |
812 | 14 | "The length of the MEP Id", HFILL } |
813 | 14 | }, |
814 | 14 | { &hf_mep_global_id, |
815 | 14 | { "Global Id", "bfd.mep.global.id", |
816 | 14 | FT_UINT32, BASE_DEC, NULL , 0x0, |
817 | 14 | "MPLS-TP Global MEP Id", HFILL } |
818 | 14 | }, |
819 | 14 | { &hf_mep_node_id, |
820 | 14 | { "Node Id", "bfd.mep.node.id", |
821 | 14 | FT_IPv4, BASE_NONE, NULL , 0x0, |
822 | 14 | "MPLS-TP Node Identifier", HFILL } |
823 | 14 | }, |
824 | | #if 0 |
825 | | { &hf_mep_interface_no, |
826 | | { "Interface Number", "bfd.mep.interface.no", |
827 | | FT_UINT32, BASE_DEC, NULL , 0x0, |
828 | | "MPLS-TP Interface Number", HFILL } |
829 | | }, |
830 | | #endif |
831 | 14 | { &hf_mep_tunnel_no, |
832 | 14 | { "Tunnel Number", "bfd.mep.tunnel.no", |
833 | 14 | FT_UINT16, BASE_DEC, NULL , 0x0, |
834 | 14 | NULL, HFILL } |
835 | 14 | }, |
836 | 14 | { &hf_mep_lsp_no, |
837 | 14 | { "LSP Number", "bfd.mep.lsp.no", |
838 | 14 | FT_UINT16, BASE_DEC, NULL , 0x0, |
839 | 14 | NULL, HFILL } |
840 | 14 | }, |
841 | 14 | { &hf_mep_ac_id, |
842 | 14 | { "AC Id", "bfd.mep.ac.id", |
843 | 14 | FT_UINT32, BASE_DEC, NULL , 0x0, |
844 | 14 | NULL, HFILL } |
845 | 14 | }, |
846 | 14 | { &hf_mep_agi_type, |
847 | 14 | { "AGI TYPE", "bfd.mep.agi.type", |
848 | 14 | FT_UINT8, BASE_DEC, NULL , 0x0, |
849 | 14 | NULL, HFILL } |
850 | 14 | }, |
851 | 14 | { &hf_mep_agi_len, |
852 | 14 | { "AGI Length", "bfd.mep.agi.len", |
853 | 14 | FT_UINT8, BASE_DEC, NULL , 0x0, |
854 | 14 | NULL, HFILL } |
855 | 14 | }, |
856 | 14 | { &hf_mep_agi_val, |
857 | 14 | { "AGI value", "bfd.mep.agi.val", |
858 | 14 | FT_STRING, BASE_NONE, NULL , 0x0, |
859 | 14 | NULL, HFILL } |
860 | 14 | }, |
861 | 14 | { &hf_section_interface_no, |
862 | 14 | { "Interface Number", "bfd.mep.interface.no", |
863 | 14 | FT_UINT32, BASE_DEC, NULL , 0x0, |
864 | 14 | "MPLS-TP Interface Number", HFILL } |
865 | 14 | } |
866 | 14 | }; |
867 | | /* BFD Echo */ |
868 | 14 | static hf_register_info hf_echo[] = { |
869 | 14 | { &hf_bfd_echo, |
870 | 14 | { "Echo", "bfd_echo.packet", |
871 | 14 | FT_BYTES, BASE_NONE, NULL, 0x0, |
872 | 14 | "Originator specific echo packet", HFILL } |
873 | 14 | } |
874 | 14 | }; |
875 | | |
876 | | /* Setup protocol subtree array */ |
877 | 14 | static int *ett[] = { |
878 | 14 | &ett_bfd, |
879 | 14 | &ett_bfd_flags, |
880 | 14 | &ett_bfd_auth, |
881 | 14 | &ett_bfd_echo |
882 | 14 | }; |
883 | | |
884 | 14 | static ei_register_info ei[] = { |
885 | 14 | { &ei_bfd_auth_len_invalid, { "bfd.auth.len.invalid", PI_MALFORMED, PI_WARN, "Length of authentication section is invalid", EXPFILL }}, |
886 | 14 | { &ei_bfd_auth_no_data, { "bfd.auth.no_data", PI_MALFORMED, PI_WARN, "Authentication flag is set in a BFD packet, but no authentication data is present", EXPFILL }}, |
887 | 14 | }; |
888 | | |
889 | 14 | expert_module_t* expert_bfd; |
890 | | |
891 | | /* Register the protocol name and description */ |
892 | 14 | proto_bfd = proto_register_protocol("Bidirectional Forwarding Detection Control Message", |
893 | 14 | "BFD Control", |
894 | 14 | "bfd"); |
895 | 14 | proto_bfd_echo = proto_register_protocol("Bidirectional Forwarding Detection Echo Packet", |
896 | 14 | "BFD Echo", |
897 | 14 | "bfd_echo"); |
898 | | |
899 | | /* Required function calls to register the header fields and subtrees used */ |
900 | 14 | proto_register_field_array(proto_bfd, hf, array_length(hf)); |
901 | 14 | proto_register_field_array(proto_bfd_echo, hf_echo, array_length(hf_echo)); |
902 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
903 | 14 | expert_bfd = expert_register_protocol(proto_bfd); |
904 | 14 | expert_register_field_array(expert_bfd, ei, array_length(ei)); |
905 | | |
906 | | /* Register dissectors */ |
907 | 14 | bfd_control_handle = register_dissector("bfd", dissect_bfd_control, proto_bfd); |
908 | 14 | bfd_echo_handle = register_dissector("bfd_echo", dissect_bfd_echo, proto_bfd_echo); |
909 | 14 | } |
910 | | |
911 | | void |
912 | | proto_reg_handoff_bfd(void) |
913 | 14 | { |
914 | 14 | dissector_add_uint_range_with_preference("udp.port", UDP_PORT_RANGE_BFD_CTRL, bfd_control_handle); |
915 | 14 | dissector_add_uint("udp.port", UDP_PORT_BFD_ECHO, bfd_echo_handle); |
916 | | |
917 | 14 | dissector_add_uint("pwach.channel_type", PW_ACH_TYPE_BFD_CC, bfd_control_handle); |
918 | 14 | dissector_add_uint("pwach.channel_type", PW_ACH_TYPE_BFD_CV, bfd_control_handle); |
919 | 14 | dissector_add_uint("pwach.channel_type", PW_ACH_TYPE_BFD, bfd_control_handle); |
920 | 14 | } |
921 | | |
922 | | /* |
923 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
924 | | * |
925 | | * Local variables: |
926 | | * c-basic-offset: 4 |
927 | | * tab-width: 8 |
928 | | * indent-tabs-mode: nil |
929 | | * End: |
930 | | * |
931 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
932 | | * :indentSize=4:tabSize=8:noTabs=true: |
933 | | */ |