Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-bmp.c
blobe709276784132205a9447ef7f00353670cb8fb19
1 /* packet-bmp.c
2 * Routines for BMP packet dissection
3 * (c) Copyright Ebben Aries <exa@fb.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 * Supports:
13 * RFC7854 BGP Monitoring Protocol
14 * RFC8671 Support for Adj-RIB-Out in the BGP Monitoring Protocol (BMP)
15 * RFC9069 Support for Local RIB in BGP Monitoring Protocol (BMP)
16 * draft-xu-grow-bmp-route-policy-attr-trace-04 BGP Route Policy and Attribute Trace Using BMP
17 * draft-ietf-grow-bmp-tlv-13 BMP v4: TLV support for BMP Route Monitoring and Peer Down Messages
18 * draft-ietf-grow-bmp-path-marking-tlv-02: BMP Extension for Path Status TLV
21 #include "config.h"
23 #include <epan/packet.h>
24 #include <epan/expert.h>
25 #include <epan/prefs.h>
26 #include <epan/tfs.h>
28 #include "packet-tcp.h"
29 #include "packet-bgp.h"
31 void proto_register_bmp(void);
32 void proto_reg_handoff_bmp(void);
34 #define FRAME_HEADER_LEN 5
36 /* BMP Common Header Message Types */
37 #define BMP_MSG_TYPE_ROUTE_MONITORING 0x00 /* Route Monitoring */
38 #define BMP_MSG_TYPE_STAT_REPORT 0x01 /* Statistics Report */
39 #define BMP_MSG_TYPE_PEER_DOWN 0x02 /* Peer Down Notification */
40 #define BMP_MSG_TYPE_PEER_UP 0x03 /* Peer Up Notification */
41 #define BMP_MSG_TYPE_INIT 0x04 /* Initiation Message */
42 #define BMP_MSG_TYPE_TERM 0x05 /* Termination Message */
43 #define BMP_MSG_TYPE_ROUTE_MIRRORING 0x06 /* Route Mirroring */
44 #define BMP_MSG_TYPE_ROUTE_POLICY 0x64 /* Route Policy and Attribute Trace Message */
46 /* BMP Initiation Message Types */
47 #define BMP_INIT_INFO_STRING 0x00 /* String */
48 #define BMP_INIT_SYSTEM_DESCRIPTION 0x01 /* sysDescr */
49 #define BMP_INIT_SYSTEM_NAME 0x02 /* sysName */
50 #define BMP_INIT_VRF_TABLE_NAME 0x03 /* VRF/Table Name */
51 #define BMP_INIT_ADMIN_LABEL 0x04 /* Admin Label */
53 /* BMP Per Peer Types */
54 #define BMP_PEER_GLOBAL_INSTANCE 0x00 /* Global Instance Peer */
55 #define BMP_PEER_RD_INSTANCE 0x01 /* RD Instance Peer */
56 #define BMP_PEER_LOCAL_INSTANCE 0x02 /* Local Instance Peer */
57 #define BMP_PEER_LOC_RIB_INSTANCE 0x03 /* Loc-RIB Instance Peer */
59 /* BMP Per Peer Header Flags */
60 #define BMP_PEER_FLAG_IPV6 0x80 /* V Flag: IPv6 */
61 #define BMP_PEER_FLAG_POST_POLICY 0x40 /* L Flag: Post-policy */
62 #define BMP_PEER_FLAG_AS_PATH 0x20 /* A Flag: AS_PATH */
63 #define BMP_PEER_FLAG_ADJ_RIB_OUT 0x10
64 #define BMP_PEER_FLAG_RES 0x0F /* Reserved */
65 #define BMP_PEER_FLAG_MASK 0xFF
67 /* BMP Per Peer Loc-RIB Header Flags : RFC9069 */
68 #define BMP_PEER_FLAG_LOC_RIB 0x80 /* F Flag : Loc-RIB */
69 #define BMP_PEER_FLAG_LOC_RIB_RES 0x7F /* Reserved */
71 /* BMP Stat Types */
72 #define BMP_STAT_PREFIX_REJ 0x00 /* Number of prefixes rejected by inbound policy */
73 #define BMP_STAT_PREFIX_DUP 0x01 /* Number of (known) duplicate prefix advertisements */
74 #define BMP_STAT_WITHDRAW_DUP 0x02 /* Number of (known) duplicate withdraws */
75 #define BMP_STAT_CLUSTER_LOOP 0x03 /* Number of updates invalidated due to CLUSTER_LIST loop */
76 #define BMP_STAT_AS_LOOP 0x04 /* Number of updates invalidated due to AS_PATH loop */
77 #define BMP_STAT_INV_ORIGINATOR 0x05 /* Number of updates invalidated due to ORIGINATOR_ID loop */
78 #define BMP_STAT_AS_CONFED_LOOP 0x06 /* Number of updates invalidated due to AS_CONFED loop */
79 #define BMP_STAT_ROUTES_ADJ_RIB_IN 0x07 /* Number of routes in Adj-RIBs-In */
80 #define BMP_STAT_ROUTES_LOC_RIB 0x08 /* Number of routes in Loc-RIB */
81 #define BMP_STAT_ROUTES_PER_ADJ_RIB_IN 0x09 /* Number of routes in per-AFI/SAFI Adj-RIBs-In */
82 #define BMP_STAT_ROUTES_PER_LOC_RIB 0x0A /* Number of routes in per-AFI/SAFI Loc-RIB */
83 #define BMP_STAT_UPDATE_TREAT 0x0B /* Number of updates subjected to treat-as-withdraw treatment */
84 #define BMP_STAT_PREFIXES_TREAT 0x0C /* Number of prefixes subjected to treat-as-withdraw treatment */
85 #define BMP_STAT_DUPLICATE_UPDATE 0x0D /* Number of duplicate update messages received */
86 #define BMP_STAT_ROUTES_PRE_ADJ_RIB_OUT 0x0E /* Number of routes in pre-policy Adj-RIB-Out */
87 #define BMP_STAT_ROUTES_POST_ADJ_RIB_OUT 0x0F /* Number of routes in post-policy Adj-RIB-Out */
88 #define BMP_STAT_ROUTES_PRE_PER_ADJ_RIB_OUT 0x10 /* Number of routes in per-AFI/SAFI pre-policy Adj-RIB-Out */
89 #define BMP_STAT_ROUTES_POST_PER_ADJ_RIB_OUT 0x11 /* Number of routes in per-AFI/SAFI post-policy Adj RIB-Out */
91 /* BMP Peer Down Reason Codes */
92 #define BMP_PEER_DOWN_LOCAL_NOTIFY 0x1 /* Local system closed the session, NOTIFICATION PDU follows */
93 #define BMP_PEER_DOWN_LOCAL_NO_NOTIFY 0x2 /* Local system closed the session, FSM Event follows */
94 #define BMP_PEER_DOWN_REMOTE_NOTIFY 0x3 /* Remote system closed the session, NOTIFICATION PDU follows */
95 #define BMP_PEER_DOWN_REMOTE_NO_NOTIFY 0x4 /* Remote system closed the session without notification */
96 #define BMP_PEER_DOWN_INFO_NO_LONGER 0x5 /* Information for this peer will no longer be sent to the monitoring station for configuration reasons */
97 #define BMP_PEER_DOWN_LOCAL_SYSTEM_CLOSED 0x6 /* Local system closed, TLV data Follows */ //RFC9069
99 /* BMP Termination Message Types */
100 #define BMP_TERM_TYPE_STRING 0x00 /* String */
101 #define BMP_TERM_TYPE_REASON 0x01 /* Reason */
103 /* BMP Termination Reason Codes */
104 #define BMP_TERM_REASON_ADMIN_CLOSE 0x00 /* Session administratively closed */
105 #define BMP_TERM_REASON_UNSPECIFIED 0x01 /* Unspecified reason */
106 #define BMP_TERM_REASON_RESOURCES 0x02 /* Out of resources */
107 #define BMP_TERM_REASON_REDUNDANT 0x03 /* Redundant connection */
108 #define BMP_TERM_REASON_PERM_CLOSE 0x04 /* Session permanently administratively closed */
110 /* BMP Route Policy TLV */
111 #define BMP_ROUTE_POLICY_TLV_VRF 0x00
112 #define BMP_ROUTE_POLICY_TLV_POLICY 0x01
113 #define BMP_ROUTE_POLICY_TLV_PRE_POLICY 0x02
114 #define BMP_ROUTE_POLICY_TLV_POST_POLICY 0x03
115 #define BMP_ROUTE_POLICY_TLV_STRING 0x04
117 /* BMP Peer Up TLV */
118 #define BMP_PEER_UP_TLV_STRING 0x00
119 #define BMP_PEER_UP_TLV_SYS_DESCR 0x01
120 #define BMP_PEER_UP_TLV_SYS_NAME 0x02
121 /* this one is called peer state because both peer up and down use it */
122 #define BMP_PEER_STATE_TLV_VRF_TABLE_NAME 0x03
123 #define BMP_PEER_UP_TLV_ADMIN_LABEL 0x04
125 /* BMP Route Mirroring TLV */
126 #define BMP_ROUTE_MIRRORING_TLV_BGP_MESSAGE 0x00
127 #define BMP_ROUTE_MIRRORING_TLV_INFORMATION 0x01
129 /* BMP draft-ietf-grow-bmp-tlv TLV */
130 #define BMPv4_TLV_TYPE_VRF_TABLE_NAME 0x03
131 #define BMPv4_TLV_TYPE_BGP_MSG 0x04
132 #define BMPv4_TLV_TYPE_GROUP 0x05
133 #define BMPv4_TLV_TYPE_BGP_CAP_ADDPATH 0x06
134 #define BMPv4_TLV_TYPE_BGP_CAP_MULTIPLE_LBL 0x07
135 #define BMPv4_TLV_TYPE_BGP_PATH_STATUS 0x09
137 /* BMP draft-item-grow-bmp-tlv TLV Lengths */
138 #define BMPv4_TLV_LENGTH_BGP_CAPABILITY 0x01
139 #define BMPv4_TLV_LENGTH_GROUP_ITEM 0x02
140 #define BMPv4_TLV_LENGTH_VRF_TABLE_NAME_MAX_LENGTH 0xFF
141 #define BMPv4_TLV_LENGTH_PATH_STATUS_STATUS_LENGTH 0x04
142 #define BMPv4_TLV_LENGTH_PATH_STATUS_REASON_LENGTH 0x02
144 static const value_string bmp_typevals[] = {
145 { BMP_MSG_TYPE_ROUTE_MONITORING, "Route Monitoring" },
146 { BMP_MSG_TYPE_STAT_REPORT, "Statistics Report" },
147 { BMP_MSG_TYPE_PEER_DOWN, "Peer Down Notification" },
148 { BMP_MSG_TYPE_PEER_UP, "Peer Up Notification" },
149 { BMP_MSG_TYPE_INIT, "Initiation Message" },
150 { BMP_MSG_TYPE_TERM, "Termination Message" },
151 { BMP_MSG_TYPE_ROUTE_MIRRORING, "Route Mirroring" },
152 { BMP_MSG_TYPE_ROUTE_POLICY, "Route Policy and Attribute Trace Message" },
153 { 0, NULL }
156 static const value_string init_typevals[] = {
157 { BMP_INIT_INFO_STRING, "String" },
158 { BMP_INIT_SYSTEM_DESCRIPTION, "sysDescr" },
159 { BMP_INIT_SYSTEM_NAME, "sysName" },
160 { BMP_INIT_VRF_TABLE_NAME, "VRF/Table" },
161 { BMP_INIT_ADMIN_LABEL, "Admin Label" },
162 { 0, NULL }
165 static const value_string peer_typevals[] = {
166 { BMP_PEER_GLOBAL_INSTANCE, "Global Instance Peer" },
167 { BMP_PEER_RD_INSTANCE, "RD Instance Peer" },
168 { BMP_PEER_LOCAL_INSTANCE, "Local Instance Peer" },
169 { BMP_PEER_LOC_RIB_INSTANCE, "Loc-RIB Instance Peer" },
170 { 0, NULL }
173 static const value_string down_reason_typevals[] = {
174 { BMP_PEER_DOWN_LOCAL_NOTIFY, "Local System, Notification" },
175 { BMP_PEER_DOWN_LOCAL_NO_NOTIFY, "Local System, No Notification" },
176 { BMP_PEER_DOWN_REMOTE_NOTIFY, "Remote System, Notification" },
177 { BMP_PEER_DOWN_REMOTE_NO_NOTIFY, "Remote System, No Notification" },
178 { BMP_PEER_DOWN_INFO_NO_LONGER, "Peer no longer be sent Information (Configuration reasons)" },
179 { BMP_PEER_DOWN_LOCAL_SYSTEM_CLOSED, "Local system closed, TLV data Follows" },
180 { 0, NULL }
183 static const value_string term_typevals[] = {
184 { BMP_TERM_TYPE_STRING, "String" },
185 { BMP_TERM_TYPE_REASON, "Reason" },
186 { 0, NULL }
189 static const value_string term_reason_typevals[] = {
190 { BMP_TERM_REASON_ADMIN_CLOSE, "Session administratively closed" },
191 { BMP_TERM_REASON_UNSPECIFIED, "Unspecified reason" },
192 { BMP_TERM_REASON_RESOURCES, "Out of resources" },
193 { BMP_TERM_REASON_REDUNDANT, "Redundant connection" },
194 { BMP_TERM_REASON_PERM_CLOSE, "Session permanently administratively closed" },
195 { 0, NULL }
198 static const value_string stat_typevals[] = {
199 { BMP_STAT_PREFIX_REJ, "Rejected Prefixes" },
200 { BMP_STAT_PREFIX_DUP, "Duplicate Prefixes" },
201 { BMP_STAT_WITHDRAW_DUP, "Duplicate Withdraws" },
202 { BMP_STAT_CLUSTER_LOOP, "Invalid CLUSTER_LIST Loop" },
203 { BMP_STAT_AS_LOOP, "Invalid AS_PATH Loop" },
204 { BMP_STAT_INV_ORIGINATOR, "Invalid ORIGINATOR_ID" },
205 { BMP_STAT_AS_CONFED_LOOP, "Invalid AS_CONFED Loop" },
206 { BMP_STAT_ROUTES_ADJ_RIB_IN, "Routes in Adj-RIB-In" },
207 { BMP_STAT_ROUTES_LOC_RIB, "Routes in Loc-RIB" },
208 { BMP_STAT_ROUTES_PER_ADJ_RIB_IN, "Routes in per-AFI/SAF Adj-RIB-In" },
209 { BMP_STAT_ROUTES_PER_LOC_RIB, "Routes in per-AFI/SAFLoc-RIB" },
210 { BMP_STAT_UPDATE_TREAT, "Updates subjected to treat-as-withdraw treatment" },
211 { BMP_STAT_PREFIXES_TREAT, "Prefixes subjected to treat-as-withdraw treatment" },
212 { BMP_STAT_DUPLICATE_UPDATE, "Duplicate update messages received" },
213 { BMP_STAT_ROUTES_PRE_ADJ_RIB_OUT, "Routes in pre-policy Adj-RIB-Out" },
214 { BMP_STAT_ROUTES_POST_ADJ_RIB_OUT, "Routes in post-policy Adj-RIB-Out" },
215 { BMP_STAT_ROUTES_PRE_PER_ADJ_RIB_OUT, "Routes in per-AFI/SAFI pre-policy Adj-RIB-Out" },
216 { BMP_STAT_ROUTES_POST_PER_ADJ_RIB_OUT, "Routes in per-AFI/SAFI post-policy Adj RIB-Out" },
217 { 0, NULL }
220 static const value_string route_policy_tlv_typevals[] = {
221 { BMP_ROUTE_POLICY_TLV_VRF, "VRF/Table" },
222 { BMP_ROUTE_POLICY_TLV_POLICY, "Policy TLV" },
223 { BMP_ROUTE_POLICY_TLV_PRE_POLICY, "Pre Policy Attribute" },
224 { BMP_ROUTE_POLICY_TLV_POST_POLICY, "Post Policy Attribute" },
225 { BMP_ROUTE_POLICY_TLV_STRING, "String" },
226 { 0, NULL }
229 static const value_string route_policy_tlv_policy_class_typevals[] = {
230 { 0, "Inbound policy" },
231 { 1, "Outbound policy" },
232 { 2, "Multi-protocol Redistribute" },
233 { 3, "Cross-VRF Redistribute" },
234 { 4, "VRF import" },
235 { 5, "VRF export" },
236 { 6, "Network" },
237 { 7, "Aggregation" },
238 { 8, "Route Withdraw" },
239 { 0, NULL }
242 static const value_string bmpv4_tlv_typevals[] = {
243 { BMPv4_TLV_TYPE_BGP_MSG, "BGP Message" },
244 { BMPv4_TLV_TYPE_GROUP, "Group" },
245 { BMPv4_TLV_TYPE_VRF_TABLE_NAME, "VRF/Table Name" },
246 { BMPv4_TLV_TYPE_BGP_CAP_ADDPATH, "BGP Add-Path Capability" },
247 { BMPv4_TLV_TYPE_BGP_CAP_MULTIPLE_LBL, "BGP Multi-Label Capability" },
248 { BMPv4_TLV_TYPE_BGP_PATH_STATUS, "BGP Path Status" },
249 { 0, NULL }
253 enum bmp_path_status {
254 BMP_PATH_STATUS_RESERVED = 0x00000000,
255 BMP_PATH_STATUS_INVALID = 0x00000001,
256 BMP_PATH_STATUS_BEST = 0x00000002,
257 BMP_PATH_STATUS_NON_SELECTED = 0x00000004,
258 BMP_PATH_STATUS_PRIMARY = 0x00000008,
259 BMP_PATH_STATUS_BACKUP = 0x00000010,
260 BMP_PATH_STATUS_NON_INSTALLED = 0x00000020,
261 BMP_PATH_STATUS_BEST_EXTERNAL = 0x00000040,
262 BMP_PATH_STATUS_ADDPATH = 0x00000080,
263 BMP_PATH_STATUS_FILTERED_IN = 0x00000100,
264 BMP_PATH_STATUS_FILTERED_OUT = 0x00000200,
265 BMP_PATH_STATUS_INVALID_ROV = 0x00000400,
268 #define BMP_PATH_STATUS_MASK 0x000007ff
270 enum bmp_path_status_reason {
271 BMP_PATH_STATUS_REASON_RESERVED = 0x0000,
272 BMP_PATH_STATUS_REASON_INVALID_FOR_AS_LOOP = 0x0001,
273 BMP_PATH_STATUS_REASON_INVALID_FOR_UNRESOLVABLE_NEXTHOP = 0x0002,
274 BMP_PATH_STATUS_REASON_NOT_PREFERRED_FOR_LOCAL_PREFERENCE = 0x0003,
275 BMP_PATH_STATUS_REASON_NOT_PREFERRED_FOR_AS_PATH_LENGTH = 0x0004,
276 BMP_PATH_STATUS_REASON_NOT_PREFERRED_FOR_ORIGIN = 0x0005,
277 BMP_PATH_STATUS_REASON_NOT_PREFERRED_FOR_MED = 0x0006,
278 BMP_PATH_STATUS_REASON_NOT_PREFERRED_FOR_PEER_TYPE = 0x0007,
279 BMP_PATH_STATUS_REASON_NOT_PREFERRED_FOR_IGP_COST = 0x0008,
280 BMP_PATH_STATUS_REASON_NOT_PREFERRED_FOR_ROUTER_ID = 0x0009,
281 BMP_PATH_STATUS_REASON_NOT_PREFERRED_FOR_PEER_ADDRESS = 0x000A,
282 BMP_PATH_STATUS_REASON_NOT_PREFERRED_FOR_AIGP = 0x000B
285 static const value_string bmpv4_tlv_path_status_reason_typevals[] = {
287 { BMP_PATH_STATUS_REASON_RESERVED, "Reserved" },
288 { BMP_PATH_STATUS_REASON_INVALID_FOR_AS_LOOP, "Invalid for AS Loop" },
289 { BMP_PATH_STATUS_REASON_INVALID_FOR_UNRESOLVABLE_NEXTHOP, "Invalid for unresolvable nexthop" },
290 { BMP_PATH_STATUS_REASON_NOT_PREFERRED_FOR_LOCAL_PREFERENCE, "Not Preferred for Local Preference" },
291 { BMP_PATH_STATUS_REASON_NOT_PREFERRED_FOR_AS_PATH_LENGTH, "Not Preferred for AS Path Length" },
292 { BMP_PATH_STATUS_REASON_NOT_PREFERRED_FOR_ORIGIN, "Not Preferred for Origin" },
293 { BMP_PATH_STATUS_REASON_NOT_PREFERRED_FOR_MED, "Not Preferred for MED" },
294 { BMP_PATH_STATUS_REASON_NOT_PREFERRED_FOR_PEER_TYPE, "Not Preferred for Peer Type" },
295 { BMP_PATH_STATUS_REASON_NOT_PREFERRED_FOR_IGP_COST, "Not Preferred for IGP Cost" },
296 { BMP_PATH_STATUS_REASON_NOT_PREFERRED_FOR_ROUTER_ID, "Not Preferred for Router ID" },
297 { BMP_PATH_STATUS_REASON_NOT_PREFERRED_FOR_PEER_ADDRESS, "Not Preferred for Peer Address" },
298 { BMP_PATH_STATUS_REASON_NOT_PREFERRED_FOR_AIGP, "Not Preferred for AIGP" },
299 { 0, NULL }
302 static const value_string peer_up_tlv_typevals[] = {
303 { BMP_PEER_UP_TLV_STRING, "String" },
304 { BMP_PEER_UP_TLV_SYS_DESCR, "sysDescr" },
305 { BMP_PEER_UP_TLV_SYS_NAME, "sysName" },
306 { BMP_PEER_STATE_TLV_VRF_TABLE_NAME, "VRF/Table" },
307 { BMP_PEER_UP_TLV_ADMIN_LABEL, "Admin Label" },
308 { 0, NULL }
311 static const value_string peer_down_tlv_typevals[] = {
312 { BMP_PEER_STATE_TLV_VRF_TABLE_NAME, "VRF/Table" },
313 { 0, NULL }
316 static const value_string route_mirroring_typevals[] = {
317 { BMP_ROUTE_MIRRORING_TLV_BGP_MESSAGE, "BGP Message" },
318 { BMP_ROUTE_MIRRORING_TLV_INFORMATION, "Information" },
319 { 0, NULL }
322 static const value_string route_mirroring_information_typevals[] = {
323 { 0, "Errored PDU" },
324 { 1, "Messages Lost" },
325 { 0, NULL }
329 static int proto_bmp;
331 /* BMP Common Header field */
332 static int hf_bmp_version;
333 static int hf_bmp_length;
334 static int hf_bmp_type;
336 /* BMP Unused Bytes field */
337 static int hf_bmp_unused;
339 /* BMP Initiation Header field */
340 static int hf_init_types;
341 static int hf_init_type;
342 static int hf_init_length;
343 static int hf_init_info;
345 /* BMP Per Peer Header field */
346 static int hf_peer_header;
347 static int hf_peer_type;
348 static int hf_peer_flags;
349 static int hf_peer_flags_ipv6;
350 static int hf_peer_flags_post_policy;
351 static int hf_peer_flags_as_path;
352 static int hf_peer_flags_adj_rib_out;
353 static int hf_peer_flags_res;
354 static int hf_peer_flags_loc_rib;
355 static int hf_peer_flags_loc_rib_res;
356 static int hf_peer_distinguisher;
357 static int hf_peer_ipv4_address;
358 static int hf_peer_ipv6_address;
359 static int hf_peer_asn;
360 static int hf_peer_bgp_id;
361 static int hf_peer_timestamp_sec;
362 static int hf_peer_timestamp_msec;
364 static int hf_peer_route_mirroring_type;
365 static int hf_peer_route_mirroring_length;
366 static int hf_peer_route_mirroring_code;
368 /* BMP Peer Up Notification field */
369 static int hf_peer_up_ipv4_address;
370 static int hf_peer_up_ipv6_address;
371 static int hf_peer_up_local_port;
372 static int hf_peer_up_remote_port;
374 static int hf_peer_state_tlv;
375 static int hf_peer_state_tlv_type;
376 static int hf_peer_state_tlv_length;
377 static int hf_peer_state_tlv_value;
378 static int hf_peer_state_tlv_vrf_table_name;
379 static int hf_peer_up_tlv_string;
380 static int hf_peer_up_tlv_sys_name;
381 static int hf_peer_up_tlv_sys_descr;
382 static int hf_peer_up_tlv_admin_label;
384 /* BMP Peer Down Notification field */
385 static int hf_peer_down_reason;
386 static int hf_peer_down_data;
388 /* BMP Stat Reports field */
389 static int hf_stats_count;
390 static int hf_stat_type;
391 static int hf_stat_len;
392 static int hf_stat_data;
393 static int hf_stat_data_prefix_rej;
394 static int hf_stat_data_prefix_dup;
395 static int hf_stat_data_withdraw_dup;
396 static int hf_stat_data_cluster_loop;
397 static int hf_stat_data_as_loop;
398 static int hf_stat_data_inv_originator;
399 static int hf_stat_data_as_confed_loop;
400 static int hf_stat_data_routes_adj_rib_in;
401 static int hf_stat_data_routes_loc_rib;
402 static int hf_stat_data_routes_per_adj_rib_in_afi;
403 static int hf_stat_data_routes_per_adj_rib_in_safi;
404 static int hf_stat_data_routes_per_adj_rib_in;
405 static int hf_stat_data_routes_per_loc_rib_afi;
406 static int hf_stat_data_routes_per_loc_rib_safi;
407 static int hf_stat_data_routes_per_loc_rib;
408 static int hf_stat_data_update_treat;
409 static int hf_stat_data_prefixes_treat;
410 static int hf_stat_data_duplicate_update;
411 static int hf_stat_data_routes_pre_adj_rib_out;
412 static int hf_stat_data_routes_post_adj_rib_out;
413 static int hf_stat_data_routes_pre_per_adj_rib_out_afi;
414 static int hf_stat_data_routes_pre_per_adj_rib_out_safi;
415 static int hf_stat_data_routes_pre_per_adj_rib_out;
416 static int hf_stat_data_routes_post_per_adj_rib_out_afi;
417 static int hf_stat_data_routes_post_per_adj_rib_out_safi;
418 static int hf_stat_data_routes_post_per_adj_rib_out;
420 /* BMP Termination field */
421 static int hf_term_types;
422 static int hf_term_type;
423 static int hf_term_len;
424 static int hf_term_info;
425 static int hf_term_reason;
427 /* BMP Route Policy */
428 static int hf_route_policy_flags;
429 static int hf_route_policy_flags_ipv6;
430 static int hf_route_policy_flags_res;
431 static int hf_route_policy_rd;
432 static int hf_route_policy_prefix_length;
433 static int hf_route_policy_prefix_ipv4;
434 static int hf_route_policy_prefix_reserved;
435 static int hf_route_policy_prefix_ipv6;
436 static int hf_route_policy_route_origin;
437 static int hf_route_policy_event_count;
438 static int hf_route_policy_total_event_length;
439 static int hf_route_policy_single_event_length;
440 static int hf_route_policy_event_index;
441 static int hf_route_policy_timestamp_sec;
442 static int hf_route_policy_timestamp_msec;
443 static int hf_route_policy_path_identifier;
444 static int hf_route_policy_afi;
445 static int hf_route_policy_safi;
446 static int hf_route_policy_tlv;
447 static int hf_route_policy_tlv_type;
448 static int hf_route_policy_tlv_length;
449 static int hf_route_policy_tlv_value;
450 static int hf_route_policy_tlv_vrf_table_id;
451 static int hf_route_policy_tlv_vrf_table_name;
452 static int hf_route_policy_tlv_policy_flags;
453 static int hf_route_policy_tlv_policy_flags_m;
454 static int hf_route_policy_tlv_policy_flags_p;
455 static int hf_route_policy_tlv_policy_flags_d;
456 static int hf_route_policy_tlv_policy_flags_res;
457 static int hf_route_policy_tlv_policy_count;
458 static int hf_route_policy_tlv_policy_class;
459 static int hf_route_policy_tlv_policy_peer_ipv4;
460 static int hf_route_policy_tlv_policy_peer_ipv6;
461 static int hf_route_policy_tlv_policy_peer_reserved;
462 static int hf_route_policy_tlv_policy_peer_router_id;
463 static int hf_route_policy_tlv_policy_peer_as;
464 static int hf_route_policy_tlv_policy;
465 static int hf_route_policy_tlv_policy_name_length;
466 static int hf_route_policy_tlv_policy_item_id_length;
467 static int hf_route_policy_tlv_policy_name;
468 static int hf_route_policy_tlv_policy_item_id;
469 static int hf_route_policy_tlv_policy_flag;
470 static int hf_route_policy_tlv_policy_flag_c;
471 static int hf_route_policy_tlv_policy_flag_r;
472 static int hf_route_policy_tlv_policy_flag_res2;
474 static int hf_route_policy_tlv_string;
476 static int hf_bmpv4_tlv;
477 static int hf_bmpv4_tlv_type;
478 static int hf_bmpv4_tlv_length;
479 static int hf_bmpv4_tlv_index;
480 static int hf_bmpv4_tlv_value_bytes;
481 static int hf_bmpv4_tlv_value_string;
482 static int hf_bmpv4_tlv_value_bool;
483 static int hf_bmpv4_tlv_value_index;
484 static int hf_bmpv4_tlv_group_id;
485 static int hf_bmpv4_tlv_path_status_status = -1;
486 static int hf_bmpv4_tlv_path_status_reason = -1;
488 static int hf_bmp_path_status_invalid = -1;
489 static int hf_bmp_path_status_best = -1;
490 static int hf_bmp_path_status_non_selected = -1;
491 static int hf_bmp_path_status_primary = -1;
492 static int hf_bmp_path_status_backup = -1;
493 static int hf_bmp_path_status_non_installed = -1;
494 static int hf_bmp_path_status_best_external = -1;
495 static int hf_bmp_path_status_addpath = -1;
496 static int hf_bmp_path_status_filtered_in = -1;
497 static int hf_bmp_path_status_filtered_out = -1;
498 static int hf_bmp_path_status_invalid_rov = -1;
500 static int * const hf_bmpv4_tlv_path_status[] = {
501 &hf_bmp_path_status_invalid,
502 &hf_bmp_path_status_best,
503 &hf_bmp_path_status_non_selected,
504 &hf_bmp_path_status_primary,
505 &hf_bmp_path_status_backup,
506 &hf_bmp_path_status_non_installed,
507 &hf_bmp_path_status_best_external,
508 &hf_bmp_path_status_addpath,
509 &hf_bmp_path_status_filtered_in,
510 &hf_bmp_path_status_filtered_out,
511 &hf_bmp_path_status_invalid_rov,
512 NULL
515 static int ett_bmp;
516 static int ett_bmp_route_monitoring;
517 static int ett_bmp_stat_report;
518 static int ett_bmp_stat_type;
519 static int ett_bmp_peer_down;
520 static int ett_bmp_peer_up;
521 static int ett_bmp_peer_state_tlv;
522 static int ett_bmp_peer_header;
523 static int ett_bmp_peer_flags;
524 static int ett_bmp_init;
525 static int ett_bmp_init_types;
526 static int ett_bmp_init_type;
527 static int ett_bmp_term;
528 static int ett_bmp_term_type;
529 static int ett_bmp_term_types;
530 static int ett_bmp_route_mirroring;
531 static int ett_bmp_route_policy_flags;
532 static int ett_bmp_route_policy_tlv;
533 static int ett_bmp_route_policy_tlv_policy_flags;
534 static int ett_bmp_route_policy_tlv_policy;
535 static int ett_bmpv4_tlv;
536 static int ett_bmpv4_tlv_value;
537 static int ett_bmpv4_tlv_path_status = -1;
540 static expert_field ei_stat_data_unknown;
541 static expert_field ei_bmpv4_tlv_wrong_cap_size;
542 static expert_field ei_bmpv4_tlv_wrong_cap_value;
543 static expert_field ei_bmpv4_tlv_string_bad_length;
545 static dissector_handle_t bmp_handle;
546 static dissector_handle_t dissector_bgp;
548 /* desegmentation */
549 static bool bmp_desegment = true;
551 typedef struct bmpv4_tlv_info {
552 uint16_t type;
553 uint16_t length;
554 uint16_t idx;
555 bool has_index;
556 } bmpv4_tlv_info;
558 /* Dissect BMPv4 TLV Header
560 * with Index (Route Monitoring Message)
561 * 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
562 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
563 * | Type (2 octets) | Length (2 octets) |
564 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
565 * | Index (2 octets) |
566 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
567 * ~ Value (variable) ~
568 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
570 * without Index
571 * 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
572 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
573 * | Type (2 octets) | Length (2 octets) |
574 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
575 * ~ Value (variable) ~
576 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
578 static bmpv4_tlv_info bmpv4_dissect_tlv_hdr(tvbuff_t *tvb, proto_tree **tree_ref, int *offset_ref, uint8_t bmp_type) {
580 int offset = *offset_ref;
581 proto_tree *tree = *tree_ref;
582 uint32_t value_holder;
583 bmpv4_tlv_info tlv = { 0 };
585 tlv.type = tvb_get_ntohs(tvb, offset);
586 tlv.length = tvb_get_ntohs(tvb, offset + 2);
587 tlv.has_index = bmp_type == BMP_MSG_TYPE_ROUTE_MONITORING;
589 int total_length = 2 /* type field */
590 + 2 /* length field */
591 + (tlv.has_index ? 2 : 0) /* index field, if present */
592 + tlv.length; /* tlv value length */
594 proto_item *ti = proto_tree_add_item(tree, hf_bmpv4_tlv, tvb, offset, total_length, ENC_NA);
595 proto_item_append_text(ti, ": %s", val_to_str(tlv.type, bmpv4_tlv_typevals, "Unknown (0x%02x)"));
597 proto_tree *subtree = proto_item_add_subtree(ti, ett_bmpv4_tlv);
599 proto_tree_add_item(subtree, hf_bmpv4_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN);
600 offset += 2;
602 proto_tree_add_item_ret_uint(subtree, hf_bmpv4_tlv_length, tvb, offset, 2, ENC_BIG_ENDIAN, &value_holder);
603 offset += 2;
605 if (tlv.has_index) {
606 proto_tree_add_item_ret_uint(subtree, hf_bmpv4_tlv_index, tvb, offset, 2, ENC_BIG_ENDIAN, &value_holder);
607 tlv.idx = (uint16_t) value_holder;
608 offset += 2;
611 *offset_ref = offset;
612 *tree_ref = subtree;
614 return tlv;
617 static void bmpv4_dissect_tlvs(proto_tree *tree, tvbuff_t *tvb, int offset, packet_info *pinfo, uint8_t bmp_msg_type) {
618 bmpv4_tlv_info tlv = { 0 };
620 while (tvb_captured_length_remaining(tvb, offset) >= 4) {
621 proto_tree *tlv_tree = tree;
622 tlv = bmpv4_dissect_tlv_hdr(tvb, &tlv_tree, &offset, bmp_msg_type);
624 switch (tlv.type) {
625 case BMPv4_TLV_TYPE_GROUP: {
627 proto_tree_add_item(tlv_tree, hf_bmpv4_tlv_group_id, tvb, offset, 2, ENC_NA);
628 offset += 2;
630 int list_length = tlv.length - 2 /* group id is not in list */;
631 proto_item *ti = proto_tree_add_item(tlv_tree, hf_bmpv4_tlv_value_bytes, tvb, offset, list_length, ENC_NA);
633 int list_count = list_length / BMPv4_TLV_LENGTH_GROUP_ITEM;
634 proto_item_set_text(ti, "Target Count: %d", list_count);
635 proto_item *subtree = proto_item_add_subtree(ti, ett_bmpv4_tlv_value);
637 for (int i = 0; i < list_count; i++) {
638 proto_tree_add_item(subtree, hf_bmpv4_tlv_value_index, tvb, offset, BMPv4_TLV_LENGTH_GROUP_ITEM, ENC_NA);
639 offset += BMPv4_TLV_LENGTH_GROUP_ITEM;
642 break;
644 case BMPv4_TLV_TYPE_VRF_TABLE_NAME: {
646 proto_item *ti = proto_tree_add_item(tlv_tree, hf_bmpv4_tlv_value_string, tvb, offset, tlv.length,
647 ENC_ASCII);
648 offset += tlv.length;
650 if (tlv.length == 0 || tlv.length > BMPv4_TLV_LENGTH_VRF_TABLE_NAME_MAX_LENGTH) {
651 expert_add_info(pinfo, ti, &ei_bmpv4_tlv_string_bad_length);
653 break;
655 case BMPv4_TLV_TYPE_BGP_PATH_STATUS: {
656 bool has_reason = tlv.length > BMPv4_TLV_LENGTH_PATH_STATUS_STATUS_LENGTH;
658 proto_tree_add_bitmask(tlv_tree, tvb, offset, hf_bmpv4_tlv_path_status_status, ett_bmpv4_tlv_path_status, hf_bmpv4_tlv_path_status, ENC_ASCII);
659 offset += BMPv4_TLV_LENGTH_PATH_STATUS_STATUS_LENGTH;
661 if (!has_reason)
662 break;
664 proto_tree_add_item(tlv_tree, hf_bmpv4_tlv_path_status_reason, tvb, offset, BMPv4_TLV_LENGTH_PATH_STATUS_REASON_LENGTH, ENC_ASCII);
665 offset += BMPv4_TLV_LENGTH_PATH_STATUS_REASON_LENGTH;
666 break;
668 case BMPv4_TLV_TYPE_BGP_CAP_ADDPATH:
669 case BMPv4_TLV_TYPE_BGP_CAP_MULTIPLE_LBL: {
671 uint16_t cap_value = tvb_get_uint8(tvb, offset);
672 if (cap_value != 0 && cap_value != 1) {
673 expert_add_info(pinfo, tlv_tree, &ei_bmpv4_tlv_wrong_cap_value);
676 if (tlv.length != BMPv4_TLV_LENGTH_BGP_CAPABILITY) {
677 expert_add_info(pinfo, tlv_tree, &ei_bmpv4_tlv_wrong_cap_size);
680 proto_tree_add_item(tlv_tree, hf_bmpv4_tlv_value_bool, tvb, offset, BMPv4_TLV_LENGTH_BGP_CAPABILITY, ENC_NA);
681 offset += BMPv4_TLV_LENGTH_BGP_CAPABILITY;
683 break;
685 case BMPv4_TLV_TYPE_BGP_MSG: {
687 proto_item *ti = proto_tree_add_item(tlv_tree, hf_bmpv4_tlv_value_bytes, tvb, offset, tlv.length, ENC_NA);
688 proto_tree *subtree = proto_item_add_subtree(ti, ett_bmpv4_tlv_value);
690 call_dissector(dissector_bgp, tvb_new_subset_length(tvb, offset, tlv.length), pinfo, subtree);
692 offset += tlv.length;
693 break;
695 default:
696 break;
702 * Dissect BMP Peer Down Notification
704 * 0 1 2 3 4 5 6 7 8
705 * +-+-+-+-+-+-+-+-+
706 * | Reason | 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
707 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
708 * | Data (present if Reason = 1, 2 or 3) |
709 * ~ ~
710 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
713 static void
714 dissect_bmp_peer_down_notification(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset, int8_t flags _U_, bool is_v4)
716 uint8_t down_reason;
718 down_reason = tvb_get_uint8(tvb, offset);
719 proto_tree_add_item(tree, hf_peer_down_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
720 offset += 1;
722 /* bmp version 3 */
723 switch (down_reason) {
724 case BMP_PEER_DOWN_LOCAL_NO_NOTIFY: {
725 /* FSM event code */
726 proto_tree_add_item(tree, hf_peer_down_data, tvb, offset, 2, ENC_NA);
727 break;
729 case BMP_PEER_DOWN_LOCAL_NOTIFY:
730 case BMP_PEER_DOWN_REMOTE_NOTIFY: {
731 col_clear(pinfo->cinfo, COL_INFO);
732 call_dissector(dissector_bgp, tvb_new_subset_remaining(tvb, offset), pinfo, tree);
733 break;
735 case BMP_PEER_DOWN_LOCAL_SYSTEM_CLOSED: {
736 uint32_t type, length;
737 proto_item *tlv_item;
738 proto_tree *tlv_tree;
739 tlv_item = proto_tree_add_item(tree, hf_peer_state_tlv, tvb, offset, 2 + 2, ENC_NA);
740 tlv_tree = proto_item_add_subtree(tlv_item, ett_bmp_peer_state_tlv);
742 type = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
744 /* unknown tlv type, and we support other types with version 4 so let v4 dissect it */
745 if (try_val_to_str(type, peer_down_tlv_typevals) == NULL && is_v4) {
746 break;
749 proto_tree_add_item(tlv_tree, hf_peer_state_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN);
750 offset += 2;
752 proto_tree_add_item_ret_uint(tlv_tree, hf_peer_state_tlv_length, tvb, offset, 2, ENC_BIG_ENDIAN, &length);
753 offset += 2;
755 proto_item_append_text(tlv_item, ": (t=%d,l=%d) %s", type, length, val_to_str(type, peer_down_tlv_typevals, "Unknown TLV Type (%02d)") );
756 proto_item_set_len(tlv_item, 2 + 2 + length);
758 proto_tree_add_item(tlv_tree, hf_peer_state_tlv_value, tvb, offset, length, ENC_NA);
759 proto_tree_add_item(tlv_tree, hf_peer_state_tlv_vrf_table_name, tvb, offset, length, ENC_ASCII);
760 offset += length;
762 default:
763 break;
766 /* bmp version 4 */
767 if (is_v4) {
768 bmpv4_dissect_tlvs(tree, tvb, offset, pinfo, BMP_MSG_TYPE_PEER_DOWN);
769 return;
774 * Dissect BMP Peer Up Notification
776 * 0 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
777 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
778 * | Local Address (16 bytes) |
779 * ~ ~
780 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
781 * | Local Port | Remote Port |
782 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
783 * | Sent OPEN Message |
784 * ~ ~
785 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
786 * | Received OPEN Message |
787 * ~ ~
788 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
789 * | Information (variable) |
790 * ~ ~
791 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
794 static void
795 dissect_bmp_peer_up_notification(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset, int8_t flags)
797 if (flags & BMP_PEER_FLAG_IPV6) {
798 proto_tree_add_item(tree, hf_peer_up_ipv6_address, tvb, offset, 16, ENC_NA);
799 offset += 16;
800 } else {
801 proto_tree_add_item(tree, hf_bmp_unused, tvb, offset, 12, ENC_NA);
802 offset += 12;
803 proto_tree_add_item(tree, hf_peer_up_ipv4_address, tvb, offset, 4, ENC_BIG_ENDIAN);
804 offset += 4;
807 proto_tree_add_item(tree, hf_peer_up_local_port, tvb, offset, 2, ENC_BIG_ENDIAN);
808 offset += 2;
810 proto_tree_add_item(tree, hf_peer_up_remote_port, tvb, offset, 2, ENC_BIG_ENDIAN);
811 offset += 2;
813 col_clear(pinfo->cinfo, COL_INFO);
814 offset += call_dissector(dissector_bgp, tvb_new_subset_remaining(tvb, offset), pinfo, tree);
815 offset += call_dissector(dissector_bgp, tvb_new_subset_remaining(tvb, offset), pinfo, tree);
817 while (tvb_reported_length_remaining(tvb, offset) > 0) {
818 uint32_t type, length;
819 proto_item *tlv_item;
820 proto_tree *tlv_tree;
821 tlv_item = proto_tree_add_item(tree, hf_peer_state_tlv, tvb, offset, 2 + 2, ENC_NA);
822 tlv_tree = proto_item_add_subtree(tlv_item, ett_bmp_peer_state_tlv);
824 proto_tree_add_item_ret_uint(tlv_tree, hf_peer_state_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN, &type);
825 offset += 2;
827 proto_tree_add_item_ret_uint(tlv_tree, hf_peer_state_tlv_length, tvb, offset, 2, ENC_BIG_ENDIAN, &length);
828 offset += 2;
830 proto_item_append_text(tlv_item, ": (t=%d,l=%d) %s", type, length, val_to_str(type, peer_up_tlv_typevals, "Unknown TLV Type (%02d)") );
831 proto_item_set_len(tlv_item, 2 + 2 + length);
833 proto_tree_add_item(tlv_tree, hf_peer_state_tlv_value, tvb, offset, length, ENC_NA);
834 switch(type){
835 case BMP_PEER_UP_TLV_STRING: {
836 proto_tree_add_item(tlv_tree, hf_peer_up_tlv_string, tvb, offset, length, ENC_ASCII);
837 offset += length;
839 break;
840 case BMP_PEER_UP_TLV_SYS_DESCR: {
841 proto_tree_add_item(tlv_tree, hf_peer_up_tlv_sys_descr, tvb, offset, length, ENC_ASCII);
842 offset += length;
844 break;
845 case BMP_PEER_UP_TLV_SYS_NAME: {
846 proto_tree_add_item(tlv_tree, hf_peer_up_tlv_sys_name, tvb, offset, length, ENC_ASCII);
847 offset += length;
849 break;
850 case BMP_PEER_STATE_TLV_VRF_TABLE_NAME: {
851 proto_tree_add_item(tlv_tree, hf_peer_state_tlv_vrf_table_name, tvb, offset, length, ENC_ASCII);
852 offset += length;
854 break;
855 case BMP_PEER_UP_TLV_ADMIN_LABEL: {
856 proto_tree_add_item(tlv_tree, hf_peer_up_tlv_admin_label, tvb, offset, length, ENC_ASCII);
857 offset += length;
859 break;
860 default:{
861 //TODO: Add expert info about undecoded type ?
862 offset += length;
873 * Dissect BMP Stats Report
875 * 0 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
876 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
877 * | Stats Count |
878 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
881 * 0 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
882 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
883 * | Stat Type | Stat Len |
884 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
885 * | Stat Data |
886 * ~ ~
887 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
890 static void
891 dissect_bmp_stat_report(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset, int8_t flags _U_)
893 uint32_t stat_len, stat_type;
894 uint32_t i;
896 uint32_t stats_count = tvb_get_ntohl(tvb, offset);
898 proto_tree_add_item(tree, hf_stats_count, tvb, offset, 4, ENC_BIG_ENDIAN);
899 offset += 4;
901 for (i = 0; i < stats_count; i++) {
902 proto_item *ti;
903 proto_item *subtree;
905 ti = proto_tree_add_item_ret_uint(tree, hf_stat_type, tvb, offset, 2, ENC_BIG_ENDIAN, &stat_type);
906 subtree = proto_item_add_subtree(ti, ett_bmp_stat_type);
907 offset += 2;
909 proto_tree_add_item_ret_uint(subtree, hf_stat_len, tvb, offset, 2, ENC_BIG_ENDIAN, &stat_len);
910 offset += 2;
912 proto_tree_add_item(subtree, hf_stat_data, tvb, offset, stat_len, ENC_NA);
913 switch(stat_type){
914 case BMP_STAT_PREFIX_REJ:
915 proto_tree_add_item(subtree, hf_stat_data_prefix_rej, tvb, offset, 4, ENC_BIG_ENDIAN);
916 offset += 4;
917 break;
918 case BMP_STAT_PREFIX_DUP:
919 proto_tree_add_item(subtree, hf_stat_data_prefix_dup, tvb, offset, 4, ENC_BIG_ENDIAN);
920 offset += 4;
921 break;
922 case BMP_STAT_WITHDRAW_DUP:
923 proto_tree_add_item(subtree, hf_stat_data_withdraw_dup, tvb, offset, 4, ENC_BIG_ENDIAN);
924 offset += 4;
925 break;
926 case BMP_STAT_CLUSTER_LOOP:
927 proto_tree_add_item(subtree, hf_stat_data_cluster_loop, tvb, offset, 4, ENC_BIG_ENDIAN);
928 offset += 4;
929 break;
930 case BMP_STAT_AS_LOOP:
931 proto_tree_add_item(subtree, hf_stat_data_as_loop, tvb, offset, 4, ENC_BIG_ENDIAN);
932 offset += 4;
933 break;
934 case BMP_STAT_INV_ORIGINATOR:
935 proto_tree_add_item(subtree, hf_stat_data_inv_originator, tvb, offset, 4, ENC_BIG_ENDIAN);
936 offset += 4;
937 break;
938 case BMP_STAT_AS_CONFED_LOOP:
939 proto_tree_add_item(subtree, hf_stat_data_as_confed_loop, tvb, offset, 4, ENC_BIG_ENDIAN);
940 offset += 4;
941 break;
942 case BMP_STAT_ROUTES_ADJ_RIB_IN:
943 proto_tree_add_item(subtree, hf_stat_data_routes_adj_rib_in, tvb, offset, 8, ENC_BIG_ENDIAN);
944 offset += 8;
945 break;
946 case BMP_STAT_ROUTES_LOC_RIB:
947 proto_tree_add_item(subtree, hf_stat_data_routes_loc_rib, tvb, offset, 8, ENC_BIG_ENDIAN);
948 offset += 8;
949 break;
950 case BMP_STAT_ROUTES_PER_ADJ_RIB_IN:
951 proto_tree_add_item(subtree, hf_stat_data_routes_per_adj_rib_in_afi, tvb, offset, 2, ENC_BIG_ENDIAN);
952 offset += 2;
953 proto_tree_add_item(subtree, hf_stat_data_routes_per_adj_rib_in_safi, tvb, offset, 1, ENC_BIG_ENDIAN);
954 offset += 1;
955 proto_tree_add_item(subtree, hf_stat_data_routes_per_adj_rib_in, tvb, offset, 8, ENC_BIG_ENDIAN);
956 offset += 8;
957 break;
958 case BMP_STAT_ROUTES_PER_LOC_RIB:
959 proto_tree_add_item(subtree, hf_stat_data_routes_per_loc_rib_afi, tvb, offset, 2, ENC_BIG_ENDIAN);
960 offset += 2;
961 proto_tree_add_item(subtree, hf_stat_data_routes_per_loc_rib_safi, tvb, offset, 1, ENC_BIG_ENDIAN);
962 offset += 1;
963 proto_tree_add_item(subtree, hf_stat_data_routes_per_loc_rib, tvb, offset, 8, ENC_BIG_ENDIAN);
964 offset += 8;
965 break;
966 case BMP_STAT_UPDATE_TREAT:
967 proto_tree_add_item(subtree, hf_stat_data_update_treat, tvb, offset, 4, ENC_BIG_ENDIAN);
968 offset += 4;
969 break;
970 case BMP_STAT_PREFIXES_TREAT:
971 proto_tree_add_item(subtree, hf_stat_data_prefixes_treat, tvb, offset, 4, ENC_BIG_ENDIAN);
972 offset += 4;
973 break;
974 case BMP_STAT_DUPLICATE_UPDATE:
975 proto_tree_add_item(subtree, hf_stat_data_duplicate_update, tvb, offset, 4, ENC_BIG_ENDIAN);
976 offset += 4;
977 break;
978 case BMP_STAT_ROUTES_PRE_ADJ_RIB_OUT:
979 proto_tree_add_item(subtree, hf_stat_data_routes_pre_adj_rib_out, tvb, offset, 8, ENC_BIG_ENDIAN);
980 offset += 8;
981 break;
982 case BMP_STAT_ROUTES_POST_ADJ_RIB_OUT:
983 proto_tree_add_item(subtree, hf_stat_data_routes_post_adj_rib_out, tvb, offset, 8, ENC_BIG_ENDIAN);
984 offset += 8;
985 break;
986 case BMP_STAT_ROUTES_PRE_PER_ADJ_RIB_OUT:
987 proto_tree_add_item(subtree, hf_stat_data_routes_pre_per_adj_rib_out_afi, tvb, offset, 2, ENC_BIG_ENDIAN);
988 offset += 2;
989 proto_tree_add_item(subtree, hf_stat_data_routes_pre_per_adj_rib_out_safi, tvb, offset, 1, ENC_BIG_ENDIAN);
990 offset += 1;
991 proto_tree_add_item(subtree, hf_stat_data_routes_pre_per_adj_rib_out, tvb, offset, 8, ENC_BIG_ENDIAN);
992 offset += 8;
993 break;
994 case BMP_STAT_ROUTES_POST_PER_ADJ_RIB_OUT:
995 proto_tree_add_item(subtree, hf_stat_data_routes_post_per_adj_rib_out_afi, tvb, offset, 2, ENC_BIG_ENDIAN);
996 offset += 2;
997 proto_tree_add_item(subtree, hf_stat_data_routes_post_per_adj_rib_out_safi, tvb, offset, 1, ENC_BIG_ENDIAN);
998 offset += 1;
999 proto_tree_add_item(subtree, hf_stat_data_routes_post_per_adj_rib_out, tvb, offset, 8, ENC_BIG_ENDIAN);
1000 offset += 8;
1001 break;
1002 default:
1003 expert_add_info(pinfo, ti, &ei_stat_data_unknown);
1004 offset += stat_len;
1005 break;
1011 * Dissect BMP Termination Message
1013 * 0 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
1014 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1015 * | Information Type | Information Length |
1016 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1017 * | Information (variable) |
1018 * ~ ~
1019 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1022 static void
1023 dissect_bmp_termination(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, int offset, uint8_t bmp_type _U_, uint16_t len)
1025 uint16_t term_type;
1026 uint16_t term_len;
1028 proto_item *ti;
1029 proto_item *subtree;
1031 ti = proto_tree_add_item(tree, hf_term_types, tvb, offset, len, ENC_NA);
1032 subtree = proto_item_add_subtree(ti, ett_bmp_term_types);
1034 term_type = tvb_get_ntohs(tvb, offset);
1035 proto_item_append_text(subtree, ", Type %s",
1036 val_to_str(term_type, term_typevals, "Unknown (0x%02x)"));
1038 proto_tree_add_item(subtree, hf_term_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1039 offset += 2;
1041 term_len = tvb_get_ntohs(tvb, offset);
1042 proto_tree_add_item(subtree, hf_term_len, tvb, offset, 2, ENC_BIG_ENDIAN);
1043 offset += 2;
1045 if (term_type == BMP_TERM_TYPE_STRING) {
1046 proto_tree_add_item(subtree, hf_term_info, tvb, offset, term_len, ENC_ASCII);
1047 } else {
1048 proto_tree_add_item(subtree, hf_term_reason, tvb, offset, term_len, ENC_BIG_ENDIAN);
1050 /*offset += term_len;*/
1054 * Dissect BMP Per-Peer Header
1056 * 0 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
1057 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1058 * | Peer Type | Peer Flags |
1059 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1060 * | Peer Distinguisher (present based on peer type) |
1061 * | |
1062 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1063 * | Peer Address (16 bytes) |
1064 * ~ ~
1065 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1066 * | Peer AS |
1067 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1068 * | Peer BGP ID |
1069 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1070 * | Timestamp (seconds) |
1071 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1072 * | Timestamp (microseconds) |
1073 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1076 static void
1077 dissect_bmp_peer_header(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset, uint8_t bmp_msg_type, uint16_t len, uint8_t bmp_version)
1079 uint8_t flags;
1080 uint32_t type;
1081 proto_item *item;
1082 proto_item *ti;
1083 proto_item *peer_hdr_subtree;
1085 static int * const peer_flags[] = {
1086 &hf_peer_flags_ipv6,
1087 &hf_peer_flags_post_policy,
1088 &hf_peer_flags_as_path,
1089 &hf_peer_flags_adj_rib_out,
1090 &hf_peer_flags_res,
1091 NULL
1093 static int * const peer_flags_loc_rib[] = {
1094 &hf_peer_flags_loc_rib,
1095 &hf_peer_flags_loc_rib_res,
1096 NULL
1099 ti = proto_tree_add_item(tree, hf_peer_header, tvb, offset, len, ENC_NA);
1100 peer_hdr_subtree = proto_item_add_subtree(ti, ett_bmp_peer_header);
1102 proto_tree_add_item_ret_uint(peer_hdr_subtree, hf_peer_type, tvb, offset, 1, ENC_BIG_ENDIAN, &type);
1103 offset += 1;
1105 flags = tvb_get_uint8(tvb, offset);
1107 if (type == BMP_PEER_LOC_RIB_INSTANCE) {
1108 proto_tree_add_bitmask(peer_hdr_subtree, tvb, offset, hf_peer_flags, ett_bmp_peer_flags, peer_flags_loc_rib, ENC_NA);
1109 } else {
1110 proto_tree_add_bitmask(peer_hdr_subtree, tvb, offset, hf_peer_flags, ett_bmp_peer_flags, peer_flags, ENC_NA);
1112 offset += 1;
1114 item = proto_tree_add_item(peer_hdr_subtree, hf_peer_distinguisher, tvb, offset, 8, ENC_NA);
1115 proto_item_set_text(item, "Peer Distinguisher: %s", decode_bgp_rd(pinfo->pool, tvb, offset));
1116 offset += 8;
1118 if (flags & BMP_PEER_FLAG_IPV6) {
1119 proto_tree_add_item(peer_hdr_subtree, hf_peer_ipv6_address, tvb, offset, 16, ENC_NA);
1120 offset += 16;
1121 } else {
1122 proto_tree_add_item(peer_hdr_subtree, hf_bmp_unused, tvb, offset, 12, ENC_NA);
1123 offset += 12;
1124 proto_tree_add_item(peer_hdr_subtree, hf_peer_ipv4_address, tvb, offset, 4, ENC_BIG_ENDIAN);
1125 offset += 4;
1128 proto_tree_add_item(peer_hdr_subtree, hf_peer_asn, tvb, offset, 4, ENC_BIG_ENDIAN);
1129 offset += 4;
1131 proto_tree_add_item(peer_hdr_subtree, hf_peer_bgp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
1132 offset += 4;
1134 proto_tree_add_item(peer_hdr_subtree, hf_peer_timestamp_sec, tvb, offset, 4, ENC_BIG_ENDIAN);
1135 offset += 4;
1137 proto_tree_add_item(peer_hdr_subtree, hf_peer_timestamp_msec, tvb, offset, 4, ENC_BIG_ENDIAN);
1138 offset += 4;
1140 bool is_v4 = bmp_version == 4;
1142 switch (bmp_msg_type) {
1143 case BMP_MSG_TYPE_ROUTE_MONITORING: {
1144 if (is_v4) {
1145 bmpv4_dissect_tlvs(tree, tvb, offset, pinfo, bmp_msg_type);
1146 } else {
1147 col_clear(pinfo->cinfo, COL_INFO);
1148 call_dissector(dissector_bgp, tvb_new_subset_remaining(tvb, offset), pinfo, tree);
1150 break;
1152 case BMP_MSG_TYPE_ROUTE_MIRRORING: {
1153 while (tvb_reported_length_remaining(tvb, offset) > 0) {
1154 uint32_t route_mirroring_type, length;
1155 proto_tree_add_item_ret_uint(tree, hf_peer_route_mirroring_type, tvb, offset, 2, ENC_BIG_ENDIAN, &route_mirroring_type);
1156 offset += 2;
1157 proto_tree_add_item_ret_uint(tree, hf_peer_route_mirroring_length, tvb, offset, 2, ENC_BIG_ENDIAN, &length);
1158 offset += 2;
1159 switch (route_mirroring_type) {
1160 case BMP_ROUTE_MIRRORING_TLV_BGP_MESSAGE: /* BGP Message */
1161 col_clear(pinfo->cinfo, COL_INFO);
1162 call_dissector(dissector_bgp, tvb_new_subset_remaining(tvb, offset), pinfo, tree);
1163 offset += length;
1164 break;
1165 case BMP_ROUTE_MIRRORING_TLV_INFORMATION: /* Information */
1166 proto_tree_add_item(tree, hf_peer_route_mirroring_code, tvb, offset, 2, ENC_BIG_ENDIAN);
1167 offset += 2;
1168 break;
1171 break;
1174 case BMP_MSG_TYPE_STAT_REPORT:
1175 dissect_bmp_stat_report(tvb, tree, pinfo, offset, flags);
1176 break;
1177 case BMP_MSG_TYPE_PEER_DOWN: {
1178 dissect_bmp_peer_down_notification(tvb, tree, pinfo, offset, flags, is_v4);
1179 break;
1181 case BMP_MSG_TYPE_PEER_UP:
1182 dissect_bmp_peer_up_notification(tvb, tree, pinfo, offset, flags);
1183 break;
1184 case BMP_MSG_TYPE_INIT:
1185 case BMP_MSG_TYPE_TERM:
1186 default:
1187 DISSECTOR_ASSERT_NOT_REACHED();
1188 break;
1193 * Dissect BMP Initiation Message
1195 * 0 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
1196 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1197 * | Information Type | Information Length |
1198 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1199 * | Information (variable) |
1200 * ~ ~
1201 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1204 static void
1205 dissect_bmp_init(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, int offset, uint8_t bmp_type _U_, uint16_t len)
1207 uint16_t init_type;
1208 uint16_t init_len;
1209 proto_tree *pti;
1210 proto_tree *parent_tree;
1212 pti = proto_tree_add_item(tree, hf_init_types, tvb, offset, len, ENC_NA);
1213 parent_tree = proto_item_add_subtree(pti, ett_bmp_init_types);
1215 while (tvb_reported_length_remaining(tvb, offset) > 0) {
1216 proto_tree *ti;
1217 proto_tree *subtree;
1219 init_type = tvb_get_ntohs(tvb, offset);
1220 proto_item_append_text(pti, ", Type %s",
1221 val_to_str(init_type, init_typevals, "Unknown (0x%02x)"));
1223 ti = proto_tree_add_item(parent_tree, hf_init_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1224 subtree = proto_item_add_subtree(ti, ett_bmp_init_type);
1225 offset += 2;
1227 init_len = tvb_get_ntohs(tvb, offset);
1228 proto_tree_add_item(subtree, hf_init_length, tvb, offset, 2, ENC_BIG_ENDIAN);
1229 offset += 2;
1231 proto_tree_add_item(subtree, hf_init_info, tvb, offset, init_len, ENC_ASCII);
1232 offset += init_len;
1237 +---------------------------------------------------------------+
1238 | Single event length |
1239 +---------------------------------------------------------------+
1240 | Event index |
1241 +---------------------------------------------------------------+
1242 | Timestamp(seconds) |
1243 +---------------------------------------------------------------+
1244 | Timestamp(microseconds) |
1245 +---------------------------------------------------------------+
1246 | Path Identifier |
1247 +---------------------------------------------------------------+
1248 | AFI |
1249 +---------------------------------------------------------------+
1250 | SAFI |
1251 +---------------------------------------------------------------+
1252 | VRF/Table TLV |
1253 +---------------------------------------------------------------+
1254 | Policy TLV |
1255 +---------------------------------------------------------------+
1256 | Pre Policy Attribute TLV |
1257 +---------------------------------------------------------------+
1258 | Post Policy Attribute TLV |
1259 +---------------------------------------------------------------+
1260 | String TLV |
1261 +---------------------------------------------------------------+
1264 static int
1265 dissect_bmp_route_policy_event(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, int offset)
1267 uint32_t single_event_length;
1269 proto_tree_add_item_ret_uint(tree, hf_route_policy_single_event_length, tvb, offset, 2, ENC_NA, &single_event_length);
1270 offset += 2;
1271 single_event_length -=2;
1273 proto_tree_add_item(tree, hf_route_policy_event_index, tvb, offset, 1, ENC_NA);
1274 offset += 1;
1275 single_event_length -=1;
1277 proto_tree_add_item(tree, hf_route_policy_timestamp_sec, tvb, offset, 4, ENC_BIG_ENDIAN);
1278 offset += 4;
1279 single_event_length -=4;
1281 proto_tree_add_item(tree, hf_route_policy_timestamp_msec, tvb, offset, 4, ENC_BIG_ENDIAN);
1282 offset += 4;
1283 single_event_length -=4;
1285 proto_tree_add_item(tree, hf_route_policy_path_identifier, tvb, offset, 4, ENC_BIG_ENDIAN);
1286 offset += 4;
1287 single_event_length -=4;
1289 proto_tree_add_item(tree, hf_route_policy_afi, tvb, offset, 2, ENC_BIG_ENDIAN);
1290 offset += 2;
1291 single_event_length -=2;
1293 proto_tree_add_item(tree, hf_route_policy_safi, tvb, offset, 1, ENC_BIG_ENDIAN);
1294 offset += 1;
1295 single_event_length -=1;
1297 while (single_event_length > 0) {
1298 uint32_t type, length;
1299 proto_item *tlv_item;
1300 proto_tree *tlv_tree;
1301 tlv_item = proto_tree_add_item(tree, hf_route_policy_tlv, tvb, offset, 2+2, ENC_NA);
1302 tlv_tree = proto_item_add_subtree(tlv_item, ett_bmp_route_policy_tlv);
1304 proto_tree_add_item_ret_uint(tlv_tree, hf_route_policy_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN, &type);
1305 offset += 2;
1306 single_event_length -= 2;
1308 proto_tree_add_item_ret_uint(tlv_tree, hf_route_policy_tlv_length, tvb, offset, 2, ENC_BIG_ENDIAN, &length);
1309 offset += 2;
1310 single_event_length -= 2;
1312 proto_item_append_text(tlv_item, ": (t=%d,l=%d) %s", type, length, val_to_str(type, route_policy_tlv_typevals, "Unknown TLV Type (%02d)") );
1313 proto_item_set_len(tlv_item, 2 + 2 + length);
1315 proto_tree_add_item(tlv_tree, hf_route_policy_tlv_value, tvb, offset, length, ENC_NA);
1316 switch(type){
1317 case BMP_ROUTE_POLICY_TLV_VRF: {
1318 proto_tree_add_item(tlv_tree, hf_route_policy_tlv_vrf_table_id, tvb, offset, 4, ENC_BIG_ENDIAN);
1319 proto_tree_add_item(tlv_tree, hf_route_policy_tlv_vrf_table_name, tvb, offset+4, length-4, ENC_ASCII);
1320 offset += length;
1321 single_event_length -=length;
1323 break;
1324 case BMP_ROUTE_POLICY_TLV_POLICY: {
1325 uint8_t flags;
1326 uint32_t policy_count;
1327 static int * const route_policy_tlv_policy_flags[] = {
1328 &hf_route_policy_tlv_policy_flags_m,
1329 &hf_route_policy_tlv_policy_flags_p,
1330 &hf_route_policy_tlv_policy_flags_d,
1331 &hf_route_policy_tlv_policy_flags_res,
1332 NULL
1334 static int * const route_policy_tlv_policy_flag[] = {
1335 &hf_route_policy_tlv_policy_flag_c,
1336 &hf_route_policy_tlv_policy_flag_r,
1337 &hf_route_policy_tlv_policy_flag_res2,
1338 NULL
1341 flags = tvb_get_uint8(tvb, offset);
1342 proto_tree_add_bitmask(tlv_tree, tvb, offset, hf_route_policy_tlv_policy_flags, ett_bmp_route_policy_tlv_policy_flags, route_policy_tlv_policy_flags, ENC_NA);
1343 offset += 1;
1344 proto_tree_add_item_ret_uint(tlv_tree, hf_route_policy_tlv_policy_count, tvb, offset, 1, ENC_BIG_ENDIAN, &policy_count);
1345 offset += 1;
1347 proto_tree_add_item(tlv_tree, hf_route_policy_tlv_policy_class, tvb, offset, 1, ENC_BIG_ENDIAN);
1348 offset += 1;
1350 if(flags & BMP_PEER_FLAG_IPV6){
1351 proto_tree_add_item(tlv_tree, hf_route_policy_tlv_policy_peer_ipv6, tvb, offset, 16, ENC_NA);
1352 offset += 16;
1353 } else {
1354 proto_tree_add_item(tlv_tree, hf_route_policy_tlv_policy_peer_reserved, tvb, offset, 12, ENC_NA);
1355 offset += 12;
1356 proto_tree_add_item(tlv_tree, hf_route_policy_tlv_policy_peer_ipv4, tvb, offset, 4, ENC_NA);
1357 offset += 4;
1360 proto_tree_add_item(tlv_tree, hf_route_policy_tlv_policy_peer_router_id, tvb, offset, 4, ENC_NA);
1361 offset += 4;
1363 proto_tree_add_item(tlv_tree, hf_route_policy_tlv_policy_peer_as, tvb, offset, 4, ENC_NA);
1364 offset += 4;
1366 while(policy_count){
1367 proto_item *policy_item;
1368 proto_tree *policy_tree;
1369 const uint8_t *policy_name, *policy_id;
1370 uint32_t policy_name_length, policy_item_id_length;
1372 policy_item = proto_tree_add_item(tlv_tree, hf_route_policy_tlv_policy, tvb, offset, 2+2, ENC_NA);
1373 policy_tree = proto_item_add_subtree(policy_item, ett_bmp_route_policy_tlv_policy);
1376 proto_tree_add_item_ret_uint(policy_tree, hf_route_policy_tlv_policy_name_length, tvb, offset, 2, ENC_NA, &policy_name_length);
1377 offset += 2;
1379 proto_tree_add_item_ret_uint(policy_tree, hf_route_policy_tlv_policy_item_id_length, tvb, offset, 2, ENC_NA, &policy_item_id_length);
1380 offset += 2;
1382 proto_item_append_text(policy_tree, ": (t=%d,l=%d)", policy_name_length, policy_item_id_length);
1383 proto_item_set_len(policy_tree, 2 + 2 + policy_name_length + policy_item_id_length );
1385 proto_tree_add_item_ret_string(policy_tree, hf_route_policy_tlv_policy_name, tvb, offset, policy_name_length, ENC_ASCII|ENC_NA, pinfo->pool, &policy_name);
1386 proto_item_append_text(policy_tree, " name: %s", policy_name);
1387 offset += policy_name_length;
1389 proto_tree_add_item_ret_string(policy_tree, hf_route_policy_tlv_policy_item_id, tvb, offset, policy_item_id_length, ENC_ASCII|ENC_NA, pinfo->pool, &policy_id);
1390 proto_item_append_text(policy_tree, " id: %s", policy_id);
1391 offset += policy_item_id_length;
1393 proto_tree_add_bitmask(policy_tree, tvb, offset, hf_route_policy_tlv_policy_flag, ett_bmp_route_policy_tlv_policy_flags, route_policy_tlv_policy_flag, ENC_NA);
1394 offset += 1;
1396 policy_count--;
1398 single_event_length -= length;
1400 break;
1401 case BMP_ROUTE_POLICY_TLV_PRE_POLICY: {
1402 dissect_bgp_path_attr(tlv_tree, tvb, length, offset, pinfo);
1403 offset += length;
1404 single_event_length -= length;
1406 break;
1407 case BMP_ROUTE_POLICY_TLV_POST_POLICY: {
1408 dissect_bgp_path_attr(tlv_tree, tvb, length, offset, pinfo);
1409 offset += length;
1410 single_event_length -= length;
1412 break;
1413 case BMP_ROUTE_POLICY_TLV_STRING: {
1414 proto_tree_add_item(tlv_tree, hf_route_policy_tlv_string, tvb, offset, length, ENC_ASCII);
1415 offset += length;
1416 single_event_length -= length;
1418 break;
1419 default:{
1420 //TODO: Add expert info about undecoded type ?
1421 offset += length;
1422 single_event_length -=length;
1429 return offset;
1434 * Dissect BMP Route Policy and Attribute Message
1436 * +---------------------------------------------------------------+
1437 * |V| Reserved |
1438 * +---------------------------------------------------------------+
1439 * | Route Distinguisher |
1440 * +---------------------------------------------------------------+
1441 * | Prefix length |
1442 * +---------------------------------------------------------------+
1443 * | Prefix |
1444 * +---------------------------------------------------------------+
1445 * | Route Origin |
1446 * +---------------------------------------------------------------+
1447 * | Event count |
1448 * +---------------------------------------------------------------+
1449 * | Total event length |
1450 * +---------------------------------------------------------------+
1451 * | 1st Event |
1452 * +---------------------------------------------------------------+
1453 * | 2nd Event |
1454 * +---------------------------------------------------------------+
1455 * ~ ~
1456 * + ...... +
1457 * ~ ~
1458 * +---------------------------------------------------------------+
1459 * | Last Event |
1460 * +---------------------------------------------------------------+
1463 static void
1464 dissect_bmp_route_policy(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset, uint8_t bmp_type _U_, uint16_t len _U_)
1466 uint8_t flags;
1467 uint32_t event_count;
1469 static int * const route_policy_flags[] = {
1470 &hf_route_policy_flags_ipv6,
1471 &hf_route_policy_flags_res,
1472 NULL
1475 flags = tvb_get_uint8(tvb, offset);
1477 proto_tree_add_bitmask(tree, tvb, offset, hf_route_policy_flags, ett_bmp_route_policy_flags, route_policy_flags, ENC_NA);
1478 offset += 1;
1480 proto_tree_add_item(tree, hf_route_policy_rd, tvb, offset, 8, ENC_NA);
1481 offset += 8;
1483 proto_tree_add_item(tree, hf_route_policy_prefix_length, tvb, offset, 1, ENC_NA);
1484 offset += 1;
1486 if(flags & BMP_PEER_FLAG_IPV6){
1487 proto_tree_add_item(tree, hf_route_policy_prefix_ipv6, tvb, offset, 16, ENC_NA);
1488 offset += 16;
1489 } else {
1490 proto_tree_add_item(tree, hf_route_policy_prefix_reserved, tvb, offset, 12, ENC_NA);
1491 offset += 12;
1492 proto_tree_add_item(tree, hf_route_policy_prefix_ipv4, tvb, offset, 4, ENC_NA);
1493 offset += 4;
1496 proto_tree_add_item(tree, hf_route_policy_route_origin, tvb, offset, 4, ENC_NA);
1497 offset += 4;
1499 proto_tree_add_item_ret_uint(tree, hf_route_policy_event_count, tvb, offset, 1, ENC_NA, &event_count);
1500 offset += 1;
1502 proto_tree_add_item(tree, hf_route_policy_total_event_length, tvb, offset, 2, ENC_NA);
1503 offset += 2;
1505 while(event_count){
1506 offset = dissect_bmp_route_policy_event(tvb, tree, pinfo, offset);
1507 event_count--;
1512 * Dissect BMP PDU and Common Header
1514 * 0 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
1515 * +-+-+-+-+-+-+-+-+
1516 * | Version |
1517 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1518 * | Message Length |
1519 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1520 * | Msg. Type |
1521 * +---------------+
1524 static unsigned
1525 get_bmp_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
1527 return tvb_get_ntohl(tvb, offset + 1);
1530 static int
1531 dissect_bmp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1533 int offset = 0;
1534 uint8_t bmp_type;
1535 uint16_t len;
1536 int arg;
1537 proto_item *ti;
1538 proto_item *bmp_tree;
1540 col_set_str(pinfo->cinfo, COL_PROTOCOL, "BMP");
1541 col_clear(pinfo->cinfo, COL_INFO);
1543 bmp_type = tvb_get_uint8(tvb, 5);
1545 col_add_fstr(pinfo->cinfo, COL_INFO, "Type: %s",
1546 val_to_str(bmp_type, bmp_typevals, "Unknown (0x%02x)"));
1548 ti = proto_tree_add_item(tree, proto_bmp, tvb, 0, -1, ENC_NA);
1549 proto_item_append_text(ti, ", Type %s",
1550 val_to_str(bmp_type, bmp_typevals, "Unknown (0x%02x)"));
1552 switch (bmp_type) {
1553 case BMP_MSG_TYPE_ROUTE_MONITORING:
1554 arg = ett_bmp_route_monitoring;
1555 break;
1556 case BMP_MSG_TYPE_STAT_REPORT:
1557 arg = ett_bmp_stat_report;
1558 break;
1559 case BMP_MSG_TYPE_PEER_DOWN:
1560 arg = ett_bmp_peer_down;
1561 break;
1562 case BMP_MSG_TYPE_PEER_UP:
1563 arg = ett_bmp_peer_up;
1564 break;
1565 case BMP_MSG_TYPE_INIT:
1566 arg = ett_bmp_init;
1567 break;
1568 case BMP_MSG_TYPE_TERM:
1569 arg = ett_bmp_term;
1570 break;
1571 case BMP_MSG_TYPE_ROUTE_MIRRORING:
1572 arg = ett_bmp_route_mirroring;
1573 break;
1574 default:
1575 arg = ett_bmp;
1576 break;
1579 bmp_tree = proto_item_add_subtree(ti, arg);
1581 uint32_t bmp_version_tmp = 0;
1582 proto_tree_add_item_ret_uint(bmp_tree, hf_bmp_version, tvb, offset, 1, ENC_BIG_ENDIAN, &bmp_version_tmp);
1583 uint8_t bmp_version = (uint8_t) bmp_version_tmp;
1585 offset += 1;
1586 proto_tree_add_item(bmp_tree, hf_bmp_length, tvb, offset, 4, ENC_BIG_ENDIAN);
1587 offset += 4;
1588 proto_tree_add_item(bmp_tree, hf_bmp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1589 offset += 1;
1591 len = tvb_get_ntohs(tvb, offset);
1593 switch (bmp_type) {
1594 case BMP_MSG_TYPE_INIT:
1595 dissect_bmp_init(tvb, bmp_tree, pinfo, offset, bmp_type, len);
1596 break;
1597 case BMP_MSG_TYPE_ROUTE_MONITORING:
1598 case BMP_MSG_TYPE_STAT_REPORT:
1599 case BMP_MSG_TYPE_PEER_DOWN:
1600 case BMP_MSG_TYPE_PEER_UP:
1601 case BMP_MSG_TYPE_ROUTE_MIRRORING:
1602 dissect_bmp_peer_header(tvb, bmp_tree, pinfo, offset, bmp_type, len, bmp_version);
1603 break;
1604 case BMP_MSG_TYPE_TERM:
1605 dissect_bmp_termination(tvb, bmp_tree, pinfo, offset, bmp_type, len);
1606 break;
1607 case BMP_MSG_TYPE_ROUTE_POLICY:
1608 dissect_bmp_route_policy(tvb, bmp_tree, pinfo, offset, bmp_type, len);
1609 break;
1610 default:
1611 break;
1614 return tvb_captured_length(tvb);
1617 /* Main dissecting routine */
1618 static int
1619 dissect_bmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1621 tcp_dissect_pdus(tvb, pinfo, tree, bmp_desegment, FRAME_HEADER_LEN, get_bmp_pdu_len, dissect_bmp_pdu, data);
1622 return tvb_captured_length(tvb);
1626 void
1627 proto_register_bmp(void)
1629 expert_module_t *expert_bmp;
1631 static hf_register_info hf[] = {
1632 /* BMP Common Header */
1633 { &hf_bmp_version,
1634 { "Version", "bmp.version", FT_UINT8, BASE_DEC,
1635 NULL, 0x0, NULL, HFILL }},
1636 { &hf_bmp_length,
1637 { "Length", "bmp.length", FT_UINT32, BASE_DEC,
1638 NULL, 0x0, NULL, HFILL }},
1639 { &hf_bmp_type,
1640 { "Type", "bmp.type", FT_UINT8, BASE_DEC,
1641 VALS(bmp_typevals), 0x0, "BMP message type", HFILL }},
1643 /* Unused/Reserved Bytes */
1644 { &hf_bmp_unused,
1645 { "Unused", "bmp.unused", FT_BYTES, BASE_NONE,
1646 NULL, 0x0, NULL, HFILL }},
1648 /* Initiation Header */
1649 { &hf_init_types,
1650 { "Information Types", "bmp.init.types", FT_NONE, BASE_NONE,
1651 NULL, 0x0, NULL, HFILL }},
1652 { &hf_init_type,
1653 { "Type", "bmp.init.type", FT_UINT16, BASE_DEC,
1654 VALS(init_typevals), 0x0, "Initiation type", HFILL }},
1655 { &hf_init_length,
1656 { "Length", "bmp.init.length", FT_UINT16, BASE_DEC,
1657 NULL, 0x0, NULL, HFILL }},
1658 { &hf_init_info,
1659 { "Information", "bmp.init.info", FT_STRING, BASE_NONE,
1660 NULL, 0x0, NULL, HFILL }},
1662 /* Per Peer Header */
1663 { &hf_peer_header,
1664 { "Per Peer Header", "bmp.peer.header", FT_NONE, BASE_NONE,
1665 NULL, 0x0, NULL, HFILL }},
1666 { &hf_peer_type,
1667 { "Type", "bmp.peer.type", FT_UINT8, BASE_DEC,
1668 VALS(peer_typevals), 0x0, NULL, HFILL }},
1669 { &hf_peer_flags,
1670 { "Flags", "bmp.peer.flags", FT_UINT8, BASE_HEX,
1671 NULL, BMP_PEER_FLAG_MASK, NULL, HFILL }},
1672 { &hf_peer_flags_ipv6,
1673 { "IPv6", "bmp.peer.flags.ipv6", FT_BOOLEAN, 8,
1674 TFS(&tfs_set_notset), BMP_PEER_FLAG_IPV6, NULL, HFILL }},
1675 { &hf_peer_flags_post_policy,
1676 { "Post-policy", "bmp.peer.flags.post_policy", FT_BOOLEAN, 8,
1677 TFS(&tfs_set_notset), BMP_PEER_FLAG_POST_POLICY, NULL, HFILL }},
1678 { &hf_peer_flags_as_path,
1679 { "AS PATH", "bmp.peer.flags.as_path", FT_BOOLEAN, 8,
1680 TFS(&tfs_set_notset), BMP_PEER_FLAG_AS_PATH, NULL, HFILL }},
1681 { &hf_peer_flags_adj_rib_out,
1682 { "Adj-RIB-Out", "bmp.peer.flags.adj_rib_out", FT_BOOLEAN, 8,
1683 TFS(&tfs_set_notset), BMP_PEER_FLAG_ADJ_RIB_OUT, NULL, HFILL }},
1684 { &hf_peer_flags_res,
1685 { "Reserved", "bmp.peer.flags.reserved", FT_BOOLEAN, 8,
1686 TFS(&tfs_set_notset), BMP_PEER_FLAG_RES, NULL, HFILL }},
1687 { &hf_peer_flags_loc_rib,
1688 { "Loc-RIB", "bmp.peer.flags.loc_rib", FT_BOOLEAN, 8,
1689 TFS(&tfs_set_notset), BMP_PEER_FLAG_LOC_RIB, NULL, HFILL }},
1690 { &hf_peer_flags_loc_rib_res,
1691 { "Reserved", "bmp.peer.flags.loc_rib.res", FT_BOOLEAN, 8,
1692 TFS(&tfs_set_notset), BMP_PEER_FLAG_LOC_RIB_RES, NULL, HFILL }},
1693 { &hf_peer_distinguisher,
1694 { "Peer Distinguisher", "bmp.peer.distinguisher", FT_BYTES, BASE_NONE,
1695 NULL, 0x0, NULL, HFILL }},
1696 { &hf_peer_ipv4_address,
1697 { "Address", "bmp.peer.ip.addr", FT_IPv4, BASE_NONE,
1698 NULL, 0x0, NULL, HFILL }},
1699 { &hf_peer_ipv6_address,
1700 { "Address", "bmp.peer.ipv6.addr", FT_IPv6, BASE_NONE,
1701 NULL, 0x0, NULL, HFILL }},
1702 { &hf_peer_asn,
1703 { "ASN", "bmp.peer.asn", FT_UINT32, BASE_DEC,
1704 NULL, 0x0, NULL, HFILL }},
1705 { &hf_peer_bgp_id,
1706 { "BGP ID", "bmp.peer.id", FT_IPv4, BASE_NONE,
1707 NULL, 0x0, NULL, HFILL }},
1708 { &hf_peer_timestamp_sec,
1709 { "Timestamp (sec)", "bmp.peer.timestamp.sec", FT_UINT32, BASE_DEC,
1710 NULL, 0x0, NULL, HFILL }},
1711 { &hf_peer_timestamp_msec,
1712 { "Timestamp (msec)", "bmp.peer.timestamp.msec", FT_UINT32, BASE_DEC,
1713 NULL, 0x0, NULL, HFILL }},
1714 /* Route Mirroring */
1715 { &hf_peer_route_mirroring_type,
1716 { "Route Mirroring Type", "bmp.peer.route_mirroring.type", FT_UINT16, BASE_DEC,
1717 VALS(route_mirroring_typevals), 0x0, NULL, HFILL }},
1718 { &hf_peer_route_mirroring_length,
1719 { "Length", "bmp.peer.route_mirroring.length", FT_UINT16, BASE_DEC,
1720 NULL, 0x0, NULL, HFILL }},
1721 { &hf_peer_route_mirroring_code,
1722 { "Code", "bmp.peer.route_mirroring.code", FT_UINT16, BASE_DEC,
1723 VALS(route_mirroring_information_typevals), 0x0, NULL, HFILL }},
1725 { &hf_peer_up_ipv4_address,
1726 { "Local Address", "bmp.peer.up.ip.addr", FT_IPv4, BASE_NONE,
1727 NULL, 0x0, NULL, HFILL }},
1728 { &hf_peer_up_ipv6_address,
1729 { "Local Address", "bmp.peer.up.ipv6.addr", FT_IPv6, BASE_NONE,
1730 NULL, 0x0, NULL, HFILL }},
1731 { &hf_peer_up_local_port,
1732 { "Local Port", "bmp.peer.up.port.local", FT_UINT16, BASE_DEC,
1733 NULL, 0x0, NULL, HFILL }},
1734 { &hf_peer_up_remote_port,
1735 { "Remote Port", "bmp.peer.up.port.remote", FT_UINT16, BASE_DEC,
1736 NULL, 0x0, NULL, HFILL }},
1738 /* Peer Up TLV */
1739 { &hf_peer_state_tlv,
1740 { "Peer UP/Down TLV", "bmp.peer_state.tlv", FT_NONE, BASE_NONE,
1741 NULL, 0x0, NULL, HFILL }},
1742 { &hf_peer_state_tlv_type,
1743 { "Type", "bmp.peer_state.tlv.type", FT_UINT16, BASE_DEC,
1744 VALS(peer_up_tlv_typevals), 0x0, NULL, HFILL }},
1745 { &hf_peer_state_tlv_length,
1746 { "Length", "bmp.peer_state.tlv.length", FT_UINT16, BASE_DEC,
1747 NULL, 0x0, NULL, HFILL }},
1748 { &hf_peer_state_tlv_value,
1749 { "Value", "bmp.peer_state.tlv.value", FT_BYTES, BASE_NONE,
1750 NULL, 0x0, NULL, HFILL }},
1751 { &hf_peer_up_tlv_string,
1752 { "String", "bmp.peer_up.tlv.sys_string", FT_STRING, BASE_NONE,
1753 NULL, 0x0, NULL, HFILL }},
1754 { &hf_peer_up_tlv_sys_descr,
1755 { "SysDescr", "bmp.peer_up.tlv.sys_descr", FT_STRING, BASE_NONE,
1756 NULL, 0x0, NULL, HFILL }},
1757 { &hf_peer_up_tlv_sys_name,
1758 { "SysName", "bmp.peer_up.tlv.sys_name", FT_STRING, BASE_NONE,
1759 NULL, 0x0, NULL, HFILL }},
1760 { &hf_peer_state_tlv_vrf_table_name,
1761 { "VRF/Table name", "bmp.peer_state.tlv.vrf_table_name", FT_STRING, BASE_NONE,
1762 NULL, 0x0, NULL, HFILL }},
1763 { &hf_peer_up_tlv_admin_label,
1764 { "Admin Label", "bmp.peer_up.tlv.admin_label", FT_STRING, BASE_NONE,
1765 NULL, 0x0, NULL, HFILL }},
1767 /* Peer Down Notification */
1768 { &hf_peer_down_reason,
1769 { "Reason", "bmp.peer.down.reason", FT_UINT8, BASE_DEC,
1770 VALS(down_reason_typevals), 0x0, NULL, HFILL }},
1771 { &hf_peer_down_data,
1772 { "Data", "bmp.peer.down.data", FT_NONE, BASE_NONE,
1773 NULL, 0x0, NULL, HFILL }},
1775 /* Stats Report */
1776 { &hf_stats_count,
1777 { "Stats Count", "bmp.stats.count", FT_UINT32, BASE_DEC,
1778 NULL, 0x0, NULL, HFILL }},
1779 { &hf_stat_type,
1780 { "Type", "bmp.stats.type", FT_UINT16, BASE_DEC,
1781 VALS(stat_typevals), 0x0, NULL, HFILL }},
1782 { &hf_stat_len,
1783 { "Length", "bmp.stats.length", FT_UINT16, BASE_DEC,
1784 NULL, 0x0, NULL, HFILL }},
1785 { &hf_stat_data,
1786 { "Data", "bmp.stats.data", FT_BYTES, BASE_NONE,
1787 NULL, 0x0, NULL, HFILL }},
1788 { &hf_stat_data_prefix_rej,
1789 { "Number of prefixes rejected by inbound policy", "bmp.stats.data.prefix_rej", FT_UINT32, BASE_DEC,
1790 NULL, 0x0, NULL, HFILL }},
1791 { &hf_stat_data_prefix_dup,
1792 { "Number of (known) duplicate prefix advertisements", "bmp.stats.data.prefix_dup", FT_UINT32, BASE_DEC,
1793 NULL, 0x0, NULL, HFILL }},
1794 { &hf_stat_data_withdraw_dup,
1795 { "Number of (known) duplicate withdraws", "bmp.stats.data.withdraw_dup", FT_UINT32, BASE_DEC,
1796 NULL, 0x0, NULL, HFILL }},
1797 { &hf_stat_data_cluster_loop,
1798 { "Number of updates invalidated due to CLUSTER_LIST loop", "bmp.stats.data.cluster_loop", FT_UINT32, BASE_DEC,
1799 NULL, 0x0, NULL, HFILL }},
1800 { &hf_stat_data_as_loop,
1801 { "Number of updates invalidated due to AS_PATH loop", "bmp.stats.data.as_loop", FT_UINT32, BASE_DEC,
1802 NULL, 0x0, NULL, HFILL }},
1803 { &hf_stat_data_inv_originator,
1804 { "Number of updates invalidated due to ORIGINATOR_ID", "bmp.stats.data.inv_originator", FT_UINT32, BASE_DEC,
1805 NULL, 0x0, NULL, HFILL }},
1806 { &hf_stat_data_as_confed_loop,
1807 { "Number of updates invalidated due to a loop found in AS_CONFED_SEQUENCE or AS_CONFED_SET", "bmp.stats.data.as_confed_loop", FT_UINT32, BASE_DEC,
1808 NULL, 0x0, NULL, HFILL }},
1809 { &hf_stat_data_routes_adj_rib_in,
1810 { "Number of routes in Adj-RIBs-In", "bmp.stats.data.routes_adj_rib_in", FT_UINT64, BASE_DEC,
1811 NULL, 0x0, NULL, HFILL }},
1812 { &hf_stat_data_routes_loc_rib,
1813 { "Number of routes in Loc-RIB", "bmp.stats.data.routes_loc_rib", FT_UINT64, BASE_DEC,
1814 NULL, 0x0, NULL, HFILL }},
1815 { &hf_stat_data_routes_per_adj_rib_in_afi,
1816 { "AFI", "bmp.stats.data.routes_per_adj_rib_in.afi", FT_UINT16, BASE_DEC,
1817 NULL, 0x0, NULL, HFILL }},
1818 { &hf_stat_data_routes_per_adj_rib_in_safi,
1819 { "SAFI", "bmp.stats.data.routes_per_adj_rib_in.safi", FT_UINT8, BASE_DEC,
1820 NULL, 0x0, NULL, HFILL }},
1821 { &hf_stat_data_routes_per_adj_rib_in,
1822 { "Number of routes in per-AFI/SAFI Adj-RIB-In", "bmp.stats.data.routes_per_adj_rib_in", FT_UINT64, BASE_DEC,
1823 NULL, 0x0, NULL, HFILL }},
1824 { &hf_stat_data_routes_per_loc_rib_afi,
1825 { "AFI", "bmp.stats.data.routes_per_loc_rib.afi", FT_UINT16, BASE_DEC,
1826 NULL, 0x0, NULL, HFILL }},
1827 { &hf_stat_data_routes_per_loc_rib_safi,
1828 { "SAFI", "bmp.stats.data.routes_per_loc_rib.safi", FT_UINT8, BASE_DEC,
1829 NULL, 0x0, NULL, HFILL }},
1830 { &hf_stat_data_routes_per_loc_rib,
1831 { "Number of routes in per-AFI/SAFI Adj-RIB-In", "bmp.stats.data.routes_per_loc_rib", FT_UINT64, BASE_DEC,
1832 NULL, 0x0, NULL, HFILL }},
1833 { &hf_stat_data_update_treat,
1834 { "Number of updates subjected to treat-as-withdraw", "bmp.stats.data.update_treat", FT_UINT32, BASE_DEC,
1835 NULL, 0x0, NULL, HFILL }},
1836 { &hf_stat_data_prefixes_treat,
1837 { "Number of prefixes subjected to treat-as-withdraw", "bmp.stats.data.prefixes_treat", FT_UINT32, BASE_DEC,
1838 NULL, 0x0, NULL, HFILL }},
1839 { &hf_stat_data_duplicate_update,
1840 { "Number of duplicate update messages received", "bmp.stats.data.duplicate_update", FT_UINT32, BASE_DEC,
1841 NULL, 0x0, NULL, HFILL }},
1842 { &hf_stat_data_routes_pre_adj_rib_out,
1843 { "Number of routes in pre-policy Adj-RIBs-Out", "bmp.stats.data.routes_pre_adj_rib_out", FT_UINT64, BASE_DEC,
1844 NULL, 0x0, NULL, HFILL }},
1845 { &hf_stat_data_routes_post_adj_rib_out,
1846 { "Number of routes in post-policy Adj-RIBs-Out", "bmp.stats.data.routes_post_adj_rib_out", FT_UINT64, BASE_DEC,
1847 NULL, 0x0, NULL, HFILL }},
1848 { &hf_stat_data_routes_pre_per_adj_rib_out_afi,
1849 { "AFI", "bmp.stats.data.routes_pre_per_adj_rib_out.afi", FT_UINT16, BASE_DEC,
1850 NULL, 0x0, NULL, HFILL }},
1851 { &hf_stat_data_routes_pre_per_adj_rib_out_safi,
1852 { "SAFI", "bmp.stats.data.routes_pre_per_adj_rib_out.safi", FT_UINT8, BASE_DEC,
1853 NULL, 0x0, NULL, HFILL }},
1854 { &hf_stat_data_routes_pre_per_adj_rib_out,
1855 { "Number of routes in per-AFI/SAFI pre-policy Adj-RIB-Out", "bmp.stats.data.routes_pre_per_adj_rib_out", FT_UINT64, BASE_DEC,
1856 NULL, 0x0, NULL, HFILL }},
1857 { &hf_stat_data_routes_post_per_adj_rib_out_afi,
1858 { "AFI", "bmp.stats.data.routes_post_per_adj_rib_out.afi", FT_UINT16, BASE_DEC,
1859 NULL, 0x0, NULL, HFILL }},
1860 { &hf_stat_data_routes_post_per_adj_rib_out_safi,
1861 { "SAFI", "bmp.stats.data.routes_post_per_adj_rib_out.safi", FT_UINT8, BASE_DEC,
1862 NULL, 0x0, NULL, HFILL }},
1863 { &hf_stat_data_routes_post_per_adj_rib_out,
1864 { "Number of routes in per-AFI/SAFI post-policy Adj-RIB-Out", "bmp.stats.data.routes_post_per_adj_rib_out", FT_UINT64, BASE_DEC,
1865 NULL, 0x0, NULL, HFILL }},
1866 /* Termination Message */
1867 { &hf_term_types,
1868 { "Termination Types", "bmp.term.types", FT_NONE, BASE_NONE,
1869 NULL, 0x0, NULL, HFILL }},
1870 { &hf_term_type,
1871 { "Type", "bmp.term.type", FT_UINT16, BASE_DEC,
1872 VALS(term_typevals), 0x0, NULL, HFILL }},
1873 { &hf_term_len,
1874 { "Length", "bmp.term.length", FT_UINT16, BASE_DEC,
1875 NULL, 0x0, NULL, HFILL }},
1876 { &hf_term_info,
1877 { "Information", "bmp.term.info", FT_STRING, BASE_NONE,
1878 NULL, 0x0, NULL, HFILL }},
1879 { &hf_term_reason,
1880 { "Reason", "bmp.term.reason", FT_UINT16, BASE_DEC,
1881 VALS(term_reason_typevals), 0x0, NULL, HFILL }},
1883 /* Route Policy */
1884 { &hf_route_policy_flags,
1885 { "Flags", "bmp.route_policy.flags", FT_UINT8, BASE_HEX,
1886 NULL, 0x0, NULL, HFILL }},
1887 { &hf_route_policy_flags_ipv6,
1888 { "IPv6", "bmp.route_policy.flags.ipv6", FT_BOOLEAN, 8,
1889 TFS(&tfs_set_notset), BMP_PEER_FLAG_IPV6, NULL, HFILL }},
1890 { &hf_route_policy_flags_res,
1891 { "Reserved", "bmp.route_policy.flags.res", FT_UINT8, BASE_HEX,
1892 NULL, 0x7F, NULL, HFILL }},
1893 { &hf_route_policy_rd,
1894 { "Route Distinguisher", "bmp.route_policy.type", FT_UINT64, BASE_HEX_DEC,
1895 NULL, 0x0, NULL, HFILL }},
1896 { &hf_route_policy_prefix_length,
1897 { "Prefix Length", "bmp.route_policy.prefix_length", FT_UINT8, BASE_DEC,
1898 NULL, 0x0, NULL, HFILL }},
1899 { &hf_route_policy_prefix_ipv4,
1900 { "Prefix (IPv4)", "bmp.route_policy.prefix_ipv4", FT_IPv4, BASE_NONE,
1901 NULL, 0x0, NULL, HFILL }},
1902 { &hf_route_policy_prefix_reserved,
1903 { "Prefix (Reserved)", "bmp.route_policy.prefix_reserved", FT_BYTES, BASE_NONE,
1904 NULL, 0x0, NULL, HFILL }},
1905 { &hf_route_policy_prefix_ipv6,
1906 { "Prefix (IPv6)", "bmp.route_policy.prefix_ipv6", FT_IPv6, BASE_NONE,
1907 NULL, 0x0, NULL, HFILL }},
1908 { &hf_route_policy_route_origin,
1909 { "Route origin", "bmp.route_policy.route_origin", FT_UINT32, BASE_DEC,
1910 NULL, 0x0, NULL, HFILL }},
1911 { &hf_route_policy_event_count,
1912 { "Event count", "bmp.route_policy.event_count", FT_UINT8, BASE_DEC,
1913 NULL, 0x0, NULL, HFILL }},
1914 { &hf_route_policy_total_event_length,
1915 { "Total Event Length", "bmp.route_policy.total_event_length", FT_UINT16, BASE_DEC,
1916 NULL, 0x0, NULL, HFILL }},
1917 { &hf_route_policy_single_event_length,
1918 { "Single event length", "bmp.route_policy.single_event_length", FT_UINT16, BASE_DEC,
1919 NULL, 0x0, NULL, HFILL }},
1920 { &hf_route_policy_event_index,
1921 { "Event count", "bmp.route_policy.event_index", FT_UINT8, BASE_DEC,
1922 NULL, 0x0, NULL, HFILL }},
1923 { &hf_route_policy_timestamp_sec,
1924 { "Timestamp (sec)", "bmp.route_policy.timestamp.sec", FT_UINT32, BASE_DEC,
1925 NULL, 0x0, NULL, HFILL }},
1926 { &hf_route_policy_timestamp_msec,
1927 { "Timestamp (msec)", "bmp.route_policy.timestamp.msec", FT_UINT32, BASE_DEC,
1928 NULL, 0x0, NULL, HFILL }},
1929 { &hf_route_policy_path_identifier,
1930 { "Path Identifier", "bmp.route_policy.path_identifier", FT_UINT32, BASE_DEC,
1931 NULL, 0x0, NULL, HFILL }},
1932 { &hf_route_policy_afi,
1933 { "AFI", "bmp.route_policy.afi", FT_UINT16, BASE_DEC,
1934 NULL, 0x0, NULL, HFILL }},
1935 { &hf_route_policy_safi,
1936 { "SAFI", "bmp.route_policy.safi", FT_UINT8, BASE_DEC,
1937 NULL, 0x0, NULL, HFILL }},
1938 { &hf_route_policy_tlv,
1939 { "TLV", "bmp.route_policy.tlv", FT_NONE, BASE_NONE,
1940 NULL, 0x0, NULL, HFILL }},
1941 { &hf_route_policy_tlv_type,
1942 { "Type", "bmp.route_policy.tlv.type", FT_UINT16, BASE_DEC,
1943 VALS(route_policy_tlv_typevals), 0x0, NULL, HFILL }},
1944 { &hf_route_policy_tlv_length,
1945 { "Length", "bmp.route_policy.tlv.length", FT_UINT16, BASE_DEC,
1946 NULL, 0x0, NULL, HFILL }},
1947 { &hf_route_policy_tlv_value,
1948 { "Value", "bmp.route_policy.tlv.value", FT_BYTES, BASE_NONE,
1949 NULL, 0x0, NULL, HFILL }},
1950 { &hf_route_policy_tlv_vrf_table_id,
1951 { "Table id", "bmp.route_policy.tlv.vrf.table_id", FT_UINT32, BASE_DEC,
1952 NULL, 0x0, NULL, HFILL }},
1953 { &hf_route_policy_tlv_vrf_table_name,
1954 { "Table name", "bmp.route_policy.tlv.vrf.table_name", FT_STRING, BASE_NONE,
1955 NULL, 0x0, NULL, HFILL }},
1956 { &hf_route_policy_tlv_policy_flags,
1957 { "Flags", "bmp.route_policy.tlv.policy.flags", FT_UINT8, BASE_HEX,
1958 NULL, 0x0, NULL, HFILL }},
1959 { &hf_route_policy_tlv_policy_flags_m,
1960 { "M(atch)", "bmp.route_policy.tlv.policy.flags.m", FT_BOOLEAN, 8,
1961 NULL, 0x80, NULL, HFILL }},
1962 { &hf_route_policy_tlv_policy_flags_p,
1963 { "P(ermit)", "bmp.route_policy.tlv.policy.flags.p", FT_BOOLEAN, 8,
1964 NULL, 0x40, NULL, HFILL }},
1965 { &hf_route_policy_tlv_policy_flags_d,
1966 { "D(ifference)", "bmp.route_policy.tlv.policy.flags.d", FT_BOOLEAN, 8,
1967 NULL, 0x20, NULL, HFILL }},
1968 { &hf_route_policy_tlv_policy_flags_res,
1969 { "Reserved", "bmp.route_policy.tlv.policy.flags.res", FT_UINT8, BASE_HEX,
1970 NULL, 0x1F, NULL, HFILL }},
1971 { &hf_route_policy_tlv_policy_count,
1972 { "Policy Count", "bmp.route_policy.tlv.policy.count", FT_UINT8, BASE_DEC,
1973 NULL, 0x0, NULL, HFILL }},
1974 { &hf_route_policy_tlv_policy_class,
1975 { "Policy Class", "bmp.route_policy.tlv.policy.class", FT_UINT8, BASE_HEX,
1976 VALS(route_policy_tlv_policy_class_typevals), 0x0, NULL, HFILL }},
1977 { &hf_route_policy_tlv_policy_peer_ipv4,
1978 { "Peer (IPv4)", "bmp.route_policy.tlv.policy.peer_ipv4", FT_IPv4, BASE_NONE,
1979 NULL, 0x0, NULL, HFILL }},
1980 { &hf_route_policy_tlv_policy_peer_reserved,
1981 { "Peer (Reserved)", "bmp.route_policy.tlv.policy.peer_reserved", FT_BYTES, BASE_NONE,
1982 NULL, 0x0, NULL, HFILL }},
1983 { &hf_route_policy_tlv_policy_peer_ipv6,
1984 { "Peer (IPv6)", "bmp.route_policy.tlv.policy.peer_ipv6", FT_IPv6, BASE_NONE,
1985 NULL, 0x0, NULL, HFILL }},
1986 { &hf_route_policy_tlv_policy_peer_router_id,
1987 { "Route Id", "bmp.route_policy.tlv.policy.peer.router_id", FT_IPv4, BASE_NONE,
1988 NULL, 0x0, NULL, HFILL }},
1989 { &hf_route_policy_tlv_policy_peer_as,
1990 { "Peer AS", "bmp.route_policy.tlv.policy.peer.as", FT_UINT32, BASE_DEC,
1991 NULL, 0x0, NULL, HFILL }},
1992 { &hf_route_policy_tlv_policy,
1993 { "Policy", "bmp.route_policy.tlv.policy", FT_NONE, BASE_NONE,
1994 NULL, 0x0, NULL, HFILL }},
1995 { &hf_route_policy_tlv_policy_name_length,
1996 { "Policy Name Length", "bmp.route_policy.tlv.policy.name.length", FT_UINT16, BASE_DEC,
1997 NULL, 0x0, NULL, HFILL }},
1998 { &hf_route_policy_tlv_policy_item_id_length,
1999 { "Policy ID Length", "bmp.route_policy.tlv.policy.item_id.length", FT_UINT16, BASE_DEC,
2000 NULL, 0x0, NULL, HFILL }},
2001 { &hf_route_policy_tlv_policy_name,
2002 { "Policy Name", "bmp.route_policy.tlv.policy.name", FT_STRING, BASE_NONE,
2003 NULL, 0x0, NULL, HFILL }},
2004 { &hf_route_policy_tlv_policy_item_id,
2005 { "Policy ID", "bmp.route_policy.tlv.policy.item_id", FT_STRING, BASE_NONE,
2006 NULL, 0x0, NULL, HFILL }},
2007 { &hf_route_policy_tlv_policy_flag,
2008 { "Flag", "bmp.route_policy.tlv.policy.flag", FT_UINT8, BASE_HEX,
2009 NULL, 0x0, NULL, HFILL }},
2010 { &hf_route_policy_tlv_policy_flag_c,
2011 { "C(haining)", "bmp.route_policy.tlv.policy.flag.c", FT_BOOLEAN, 8,
2012 NULL, 0x80, NULL, HFILL }},
2013 { &hf_route_policy_tlv_policy_flag_r,
2014 { "R(ecursion)", "bmp.route_policy.tlv.policy.flag.r", FT_BOOLEAN, 8,
2015 NULL, 0x40, NULL, HFILL }},
2016 { &hf_route_policy_tlv_policy_flag_res2,
2017 { "Reserved", "bmp.route_policy.tlv.policy.flag.res2", FT_UINT8, BASE_HEX,
2018 NULL, 0x3F, NULL, HFILL }},
2019 { &hf_route_policy_tlv_string,
2020 { "String", "bmp.route_policy.tlv.string", FT_STRING, BASE_NONE,
2021 NULL, 0x0, NULL, HFILL }},
2023 /* BMPv4 TLVs */
2024 { &hf_bmpv4_tlv,
2025 { "BMPv4 TLV", "bmp.tlv", FT_NONE, BASE_NONE,
2026 NULL, 0x0, NULL, HFILL }},
2027 { &hf_bmpv4_tlv_type,
2028 { "Type", "bmp.tlv.type", FT_UINT16, BASE_DEC,
2029 VALS(bmpv4_tlv_typevals), 0x0, NULL, HFILL }},
2030 { &hf_bmpv4_tlv_length,
2031 { "Length", "bmp.tlv.length", FT_UINT16, BASE_DEC,
2032 NULL, 0x0, NULL, HFILL }},
2033 { &hf_bmpv4_tlv_index,
2034 { "Index", "bmp.tlv.index", FT_UINT16, BASE_DEC,
2035 NULL, 0x0, NULL, HFILL }},
2036 { &hf_bmpv4_tlv_value_bytes,
2037 { "Value", "bmp.tlv.value.bytes", FT_BYTES, SEP_SPACE,
2038 NULL, 0x0, NULL, HFILL }},
2039 { &hf_bmpv4_tlv_value_string,
2040 { "Value", "bmp.tlv.value.string", FT_STRING, BASE_NONE,
2041 NULL, 0x0, NULL, HFILL }},
2042 { &hf_bmpv4_tlv_value_bool,
2043 { "Value", "bmp.tlv.value.bool", FT_BOOLEAN, BASE_NONE,
2044 NULL, 0x0, NULL, HFILL }},
2045 { &hf_bmpv4_tlv_value_index,
2046 { "Index", "bmp.tlv.value.index", FT_UINT16, BASE_DEC,
2047 NULL, 0x0, NULL, HFILL }},
2048 { &hf_bmpv4_tlv_group_id,
2049 { "Group ID", "bmp.tlv.group_id", FT_UINT16, BASE_DEC,
2050 NULL, 0x0, NULL, HFILL }},
2051 { &hf_bmpv4_tlv_path_status_status,
2052 { "Status", "bmp.tlv.value.path_status.status", FT_UINT32, BASE_HEX,
2053 NULL, BMP_PATH_STATUS_MASK, NULL, HFILL }},
2054 { &hf_bmpv4_tlv_path_status_reason,
2055 { "Reason", "bmp.tlv.value.path_status.reason", FT_UINT16, BASE_HEX,
2056 VALS(bmpv4_tlv_path_status_reason_typevals), 0x0, NULL, HFILL }},
2057 { &hf_bmp_path_status_invalid,
2058 { "invalid", "bmp.tlv.value.path_status.invalid", FT_BOOLEAN, 32,
2059 TFS(&tfs_set_notset), BMP_PATH_STATUS_INVALID, NULL, HFILL}},
2060 { &hf_bmp_path_status_best,
2061 { "best", "bmp.tlv.value.path_status.best", FT_BOOLEAN, 32,
2062 TFS(&tfs_set_notset), BMP_PATH_STATUS_BEST, NULL, HFILL}},
2063 { &hf_bmp_path_status_non_selected,
2064 { "non_selected", "bmp.tlv.value.path_status.non_selected", FT_BOOLEAN, 32,
2065 TFS(&tfs_set_notset), BMP_PATH_STATUS_NON_SELECTED, NULL, HFILL}},
2066 { &hf_bmp_path_status_primary,
2067 { "primary", "bmp.tlv.value.path_status.primary", FT_BOOLEAN, 32,
2068 TFS(&tfs_set_notset), BMP_PATH_STATUS_PRIMARY, NULL, HFILL}},
2069 { &hf_bmp_path_status_backup,
2070 { "backup", "bmp.tlv.value.path_status.backup", FT_BOOLEAN, 32,
2071 TFS(&tfs_set_notset), BMP_PATH_STATUS_BACKUP, NULL, HFILL}},
2072 { &hf_bmp_path_status_non_installed,
2073 { "non_installed", "bmp.tlv.value.path_status.non_installed", FT_BOOLEAN, 32,
2074 TFS(&tfs_set_notset), BMP_PATH_STATUS_NON_INSTALLED, NULL, HFILL}},
2075 { &hf_bmp_path_status_best_external,
2076 { "best_external", "bmp.tlv.value.path_status.best_external", FT_BOOLEAN, 32,
2077 TFS(&tfs_set_notset), BMP_PATH_STATUS_BEST_EXTERNAL, NULL, HFILL}},
2078 { &hf_bmp_path_status_addpath,
2079 { "addpath", "bmp.tlv.value.path_status.addpath", FT_BOOLEAN, 32,
2080 TFS(&tfs_set_notset), BMP_PATH_STATUS_ADDPATH, NULL, HFILL}},
2081 { &hf_bmp_path_status_filtered_in,
2082 { "filtered_in", "bmp.tlv.value.path_status.filtered_in", FT_BOOLEAN, 32,
2083 TFS(&tfs_set_notset), BMP_PATH_STATUS_FILTERED_IN, NULL, HFILL}},
2084 { &hf_bmp_path_status_filtered_out,
2085 { "filtered_out", "bmp.tlv.value.path_status.filtered_out", FT_BOOLEAN, 32,
2086 TFS(&tfs_set_notset), BMP_PATH_STATUS_FILTERED_OUT, NULL, HFILL}},
2087 { &hf_bmp_path_status_invalid_rov,
2088 { "invalid_rov", "bmp.tlv.value.path_status.invalid_rov", FT_BOOLEAN, 32,
2089 TFS(&tfs_set_notset), BMP_PATH_STATUS_INVALID_ROV, NULL, HFILL}},
2092 /* Setup protocol subtree array */
2093 static int *ett[] = {
2094 &ett_bmp,
2095 &ett_bmp_route_monitoring,
2096 &ett_bmp_stat_report,
2097 &ett_bmp_stat_type,
2098 &ett_bmp_peer_down,
2099 &ett_bmp_peer_up,
2100 &ett_bmp_peer_state_tlv,
2101 &ett_bmp_peer_header,
2102 &ett_bmp_peer_flags,
2103 &ett_bmp_init,
2104 &ett_bmp_init_type,
2105 &ett_bmp_init_types,
2106 &ett_bmp_term,
2107 &ett_bmp_term_type,
2108 &ett_bmp_term_types,
2109 &ett_bmp_route_mirroring,
2110 &ett_bmp_route_policy_flags,
2111 &ett_bmp_route_policy_tlv,
2112 &ett_bmp_route_policy_tlv_policy_flags,
2113 &ett_bmp_route_policy_tlv_policy,
2114 &ett_bmpv4_tlv,
2115 &ett_bmpv4_tlv_value,
2116 &ett_bmpv4_tlv_path_status,
2119 static ei_register_info ei[] = {
2120 { &ei_stat_data_unknown,
2121 { "bmp.stats.data.unknown", PI_UNDECODED, PI_NOTE,
2122 "Unknown stats type payload", EXPFILL }
2124 { &ei_bmpv4_tlv_wrong_cap_size,
2125 { "bmp.tlv.capability.bad_size", PI_MALFORMED, PI_ERROR,
2126 "Wrong capability size (should be 1)", EXPFILL }
2128 { &ei_bmpv4_tlv_wrong_cap_value,
2129 { "bmp.tlv.capability.bad_value", PI_MALFORMED, PI_ERROR,
2130 "Wrong capability value (should be 0 or 1)", EXPFILL }
2132 { &ei_bmpv4_tlv_string_bad_length,
2133 { "bmp.tlv.string.bad_length", PI_MALFORMED, PI_NOTE,
2134 "Bad string length (should be in range [1; 255])", EXPFILL }
2138 module_t *bmp_module;
2140 proto_bmp = proto_register_protocol("BGP Monitoring Protocol", "BMP", "bmp");
2142 bmp_handle = register_dissector("bmp", dissect_bmp, proto_bmp);
2144 proto_register_field_array(proto_bmp, hf, array_length(hf));
2145 proto_register_subtree_array(ett, array_length(ett));
2147 expert_bmp = expert_register_protocol(proto_bmp);
2148 expert_register_field_array(expert_bmp, ei, array_length(ei));
2150 bmp_module = prefs_register_protocol(proto_bmp, NULL);
2151 prefs_register_bool_preference(bmp_module, "desegment",
2152 "Reassemble BMP messages spanning multiple TCP segments",
2153 "Whether the BMP dissector should reassemble messages spanning multiple TCP segments."
2154 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
2155 &bmp_desegment);
2159 void
2160 proto_reg_handoff_bmp(void)
2162 dissector_add_for_decode_as_with_preference("tcp.port", bmp_handle);
2163 dissector_bgp = find_dissector_add_dependency("bgp.pdu", proto_bmp);
2166 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2168 * Local variables:
2169 * c-basic-offset: 4
2170 * tab-width: 8
2171 * indent-tabs-mode: nil
2172 * End:
2174 * ex: set shiftwidth=4 tabstop=8 expandtab:
2175 * :indentSize=4:tabSize=8:noTabs=true: