summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-bmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-bmp.c')
-rw-r--r--epan/dissectors/packet-bmp.c759
1 files changed, 515 insertions, 244 deletions
diff --git a/epan/dissectors/packet-bmp.c b/epan/dissectors/packet-bmp.c
index 11e11a07..0647397b 100644
--- a/epan/dissectors/packet-bmp.c
+++ b/epan/dissectors/packet-bmp.c
@@ -14,6 +14,7 @@
* RFC8671 Support for Adj-RIB-Out in the BGP Monitoring Protocol (BMP)
* RFC9069 Support for Local RIB in BGP Monitoring Protocol (BMP)
* draft-xu-grow-bmp-route-policy-attr-trace-04 BGP Route Policy and Attribute Trace Using BMP
+ * draft-ietf-grow-bmp-tlv-13 BMP v4: TLV support for BMP Route Monitoring and Peer Down Messages
*/
#include "config.h"
@@ -21,6 +22,7 @@
#include <epan/packet.h>
#include <epan/expert.h>
#include <epan/prefs.h>
+#include <epan/tfs.h>
#include "packet-tcp.h"
#include "packet-bgp.h"
@@ -86,9 +88,9 @@ void proto_reg_handoff_bmp(void);
#define BMP_STAT_ROUTES_POST_PER_ADJ_RIB_OUT 0x11 /* Number of routes in per-AFI/SAFI post-policy Adj RIB-Out */
/* BMP Peer Down Reason Codes */
-#define BMP_PEER_DOWN_LOCAL_NOTIFY 0x1 /* Local system closed the session with notification */
-#define BMP_PEER_DOWN_LOCAL_NO_NOTIFY 0x2 /* Local system closed the session with FSM code */
-#define BMP_PEER_DOWN_REMOTE_NOTIFY 0x3 /* Remote system closed the session with notification */
+#define BMP_PEER_DOWN_LOCAL_NOTIFY 0x1 /* Local system closed the session, NOTIFICATION PDU follows */
+#define BMP_PEER_DOWN_LOCAL_NO_NOTIFY 0x2 /* Local system closed the session, FSM Event follows */
+#define BMP_PEER_DOWN_REMOTE_NOTIFY 0x3 /* Remote system closed the session, NOTIFICATION PDU follows */
#define BMP_PEER_DOWN_REMOTE_NO_NOTIFY 0x4 /* Remote system closed the session without notification */
#define BMP_PEER_DOWN_INFO_NO_LONGER 0x5 /* Information for this peer will no longer be sent to the monitoring station for configuration reasons */
#define BMP_PEER_DOWN_LOCAL_SYSTEM_CLOSED 0x6 /* Local system closed, TLV data Follows */ //RFC9069
@@ -115,13 +117,26 @@ void proto_reg_handoff_bmp(void);
#define BMP_PEER_UP_TLV_STRING 0x00
#define BMP_PEER_UP_TLV_SYS_DESCR 0x01
#define BMP_PEER_UP_TLV_SYS_NAME 0x02
-#define BMP_PEER_UP_TLV_VRF_TABLE_NAME 0x03
+/* this one is called peer state because both peer up and down use it */
+#define BMP_PEER_STATE_TLV_VRF_TABLE_NAME 0x03
#define BMP_PEER_UP_TLV_ADMIN_LABEL 0x04
/* BMP Route Mirroring TLV */
#define BMP_ROUTE_MIRRORING_TLV_BGP_MESSAGE 0x00
#define BMP_ROUTE_MIRRORING_TLV_INFORMATION 0x01
+/* BMP draft-ietf-grow-bmp-tlv TLV */
+#define BMPv4_TLV_TYPE_VRF_TABLE_NAME 0x03
+#define BMPv4_TLV_TYPE_BGP_MSG 0x04
+#define BMPv4_TLV_TYPE_GROUP 0x05
+#define BMPv4_TLV_TYPE_BGP_CAP_ADDPATH 0x06
+#define BMPv4_TLV_TYPE_BGP_CAP_MULTIPLE_LBL 0x07
+
+/* BMP draft-item-grow-bmp-tlv TLV Lengths */
+#define BMPv4_TLV_LENGTH_BGP_CAPABILITY 0x01
+#define BMPv4_TLV_LENGTH_GROUP_ITEM 0x02
+#define BMPv4_TLV_LENGTH_VRF_TABLE_NAME_MAX_LENGTH 0xFF
+
static const value_string bmp_typevals[] = {
{ BMP_MSG_TYPE_ROUTE_MONITORING, "Route Monitoring" },
{ BMP_MSG_TYPE_STAT_REPORT, "Statistics Report" },
@@ -156,7 +171,7 @@ static const value_string down_reason_typevals[] = {
{ BMP_PEER_DOWN_LOCAL_NO_NOTIFY, "Local System, No Notification" },
{ BMP_PEER_DOWN_REMOTE_NOTIFY, "Remote System, Notification" },
{ BMP_PEER_DOWN_REMOTE_NO_NOTIFY, "Remote System, No Notification" },
- { BMP_PEER_DOWN_INFO_NO_LONGER, "Peer no longer be sent INformation (Configuration reasons)" },
+ { BMP_PEER_DOWN_INFO_NO_LONGER, "Peer no longer be sent Information (Configuration reasons)" },
{ BMP_PEER_DOWN_LOCAL_SYSTEM_CLOSED, "Local system closed, TLV data Follows" },
{ 0, NULL }
};
@@ -220,12 +235,26 @@ static const value_string route_policy_tlv_policy_class_typevals[] = {
{ 0, NULL }
};
+static const value_string bmpv4_tlv_typevals[] = {
+ { BMPv4_TLV_TYPE_BGP_MSG, "BGP Message" },
+ { BMPv4_TLV_TYPE_GROUP, "Group" },
+ { BMPv4_TLV_TYPE_VRF_TABLE_NAME, "VRF/Table Name" },
+ { BMPv4_TLV_TYPE_BGP_CAP_ADDPATH, "BGP Add-Path Capability" },
+ { BMPv4_TLV_TYPE_BGP_CAP_MULTIPLE_LBL, "BGP Multi-Label Capability" },
+ { 0, NULL }
+};
+
static const value_string peer_up_tlv_typevals[] = {
- { BMP_PEER_UP_TLV_STRING, "String" },
- { BMP_PEER_UP_TLV_SYS_DESCR, "sysDescr" },
- { BMP_PEER_UP_TLV_SYS_NAME, "sysName" },
- { BMP_PEER_UP_TLV_VRF_TABLE_NAME, "VRF/Table" },
- { BMP_PEER_UP_TLV_ADMIN_LABEL, "Admin Label" },
+ { BMP_PEER_UP_TLV_STRING, "String" },
+ { BMP_PEER_UP_TLV_SYS_DESCR, "sysDescr" },
+ { BMP_PEER_UP_TLV_SYS_NAME, "sysName" },
+ { BMP_PEER_STATE_TLV_VRF_TABLE_NAME, "VRF/Table" },
+ { BMP_PEER_UP_TLV_ADMIN_LABEL, "Admin Label" },
+ { 0, NULL }
+};
+
+static const value_string peer_down_tlv_typevals[] = {
+ { BMP_PEER_STATE_TLV_VRF_TABLE_NAME, "VRF/Table" },
{ 0, NULL }
};
@@ -242,182 +271,332 @@ static const value_string route_mirroring_information_typevals[] = {
};
-static int proto_bmp = -1;
+static int proto_bmp;
/* BMP Common Header field */
-static int hf_bmp_version = -1;
-static int hf_bmp_length = -1;
-static int hf_bmp_type = -1;
+static int hf_bmp_version;
+static int hf_bmp_length;
+static int hf_bmp_type;
/* BMP Unused Bytes field */
-static int hf_bmp_unused = -1;
+static int hf_bmp_unused;
/* BMP Initiation Header field */
-static int hf_init_types = -1;
-static int hf_init_type = -1;
-static int hf_init_length = -1;
-static int hf_init_info = -1;
+static int hf_init_types;
+static int hf_init_type;
+static int hf_init_length;
+static int hf_init_info;
/* BMP Per Peer Header field */
-static int hf_peer_header = -1;
-static int hf_peer_type = -1;
-static int hf_peer_flags = -1;
-static int hf_peer_flags_ipv6 = -1;
-static int hf_peer_flags_post_policy = -1;
-static int hf_peer_flags_as_path = -1;
-static int hf_peer_flags_adj_rib_out = -1;
-static int hf_peer_flags_res = -1;
-static int hf_peer_flags_loc_rib = -1;
-static int hf_peer_flags_loc_rib_res = -1;
-static int hf_peer_distinguisher = -1;
-static int hf_peer_ipv4_address = -1;
-static int hf_peer_ipv6_address = -1;
-static int hf_peer_asn = -1;
-static int hf_peer_bgp_id = -1;
-static int hf_peer_timestamp_sec = -1;
-static int hf_peer_timestamp_msec = -1;
-
-static int hf_peer_route_mirroring_type = -1;
-static int hf_peer_route_mirroring_length = -1;
-static int hf_peer_route_mirroring_code = -1;
+static int hf_peer_header;
+static int hf_peer_type;
+static int hf_peer_flags;
+static int hf_peer_flags_ipv6;
+static int hf_peer_flags_post_policy;
+static int hf_peer_flags_as_path;
+static int hf_peer_flags_adj_rib_out;
+static int hf_peer_flags_res;
+static int hf_peer_flags_loc_rib;
+static int hf_peer_flags_loc_rib_res;
+static int hf_peer_distinguisher;
+static int hf_peer_ipv4_address;
+static int hf_peer_ipv6_address;
+static int hf_peer_asn;
+static int hf_peer_bgp_id;
+static int hf_peer_timestamp_sec;
+static int hf_peer_timestamp_msec;
+
+static int hf_peer_route_mirroring_type;
+static int hf_peer_route_mirroring_length;
+static int hf_peer_route_mirroring_code;
/* BMP Peer Up Notification field */
-static int hf_peer_up_ipv4_address = -1;
-static int hf_peer_up_ipv6_address = -1;
-static int hf_peer_up_local_port = -1;
-static int hf_peer_up_remote_port = -1;
-
-static int hf_peer_up_tlv = -1;
-static int hf_peer_up_tlv_type = -1;
-static int hf_peer_up_tlv_length = -1;
-static int hf_peer_up_tlv_value = -1;
-static int hf_peer_up_tlv_string = -1;
-static int hf_peer_up_tlv_sys_name = -1;
-static int hf_peer_up_tlv_sys_descr = -1;
-static int hf_peer_up_tlv_vrf_table_name = -1;
-static int hf_peer_up_tlv_admin_label = -1;
+static int hf_peer_up_ipv4_address;
+static int hf_peer_up_ipv6_address;
+static int hf_peer_up_local_port;
+static int hf_peer_up_remote_port;
+
+static int hf_peer_state_tlv;
+static int hf_peer_state_tlv_type;
+static int hf_peer_state_tlv_length;
+static int hf_peer_state_tlv_value;
+static int hf_peer_state_tlv_vrf_table_name;
+static int hf_peer_up_tlv_string;
+static int hf_peer_up_tlv_sys_name;
+static int hf_peer_up_tlv_sys_descr;
+static int hf_peer_up_tlv_admin_label;
/* BMP Peer Down Notification field */
-static int hf_peer_down_reason = -1;
-static int hf_peer_down_data = -1;
+static int hf_peer_down_reason;
+static int hf_peer_down_data;
/* BMP Stat Reports field */
-static int hf_stats_count = -1;
-static int hf_stat_type = -1;
-static int hf_stat_len = -1;
-static int hf_stat_data = -1;
-static int hf_stat_data_prefix_rej = -1;
-static int hf_stat_data_prefix_dup = -1;
-static int hf_stat_data_withdraw_dup = -1;
-static int hf_stat_data_cluster_loop = -1;
-static int hf_stat_data_as_loop = -1;
-static int hf_stat_data_inv_originator = -1;
-static int hf_stat_data_as_confed_loop = -1;
-static int hf_stat_data_routes_adj_rib_in = -1;
-static int hf_stat_data_routes_loc_rib = -1;
-static int hf_stat_data_routes_per_adj_rib_in_afi = -1;
-static int hf_stat_data_routes_per_adj_rib_in_safi = -1;
-static int hf_stat_data_routes_per_adj_rib_in = -1;
-static int hf_stat_data_routes_per_loc_rib_afi = -1;
-static int hf_stat_data_routes_per_loc_rib_safi = -1;
-static int hf_stat_data_routes_per_loc_rib = -1;
-static int hf_stat_data_update_treat = -1;
-static int hf_stat_data_prefixes_treat = -1;
-static int hf_stat_data_duplicate_update = -1;
-static int hf_stat_data_routes_pre_adj_rib_out = -1;
-static int hf_stat_data_routes_post_adj_rib_out = -1;
-static int hf_stat_data_routes_pre_per_adj_rib_out_afi = -1;
-static int hf_stat_data_routes_pre_per_adj_rib_out_safi = -1;
-static int hf_stat_data_routes_pre_per_adj_rib_out = -1;
-static int hf_stat_data_routes_post_per_adj_rib_out_afi = -1;
-static int hf_stat_data_routes_post_per_adj_rib_out_safi = -1;
-static int hf_stat_data_routes_post_per_adj_rib_out = -1;
+static int hf_stats_count;
+static int hf_stat_type;
+static int hf_stat_len;
+static int hf_stat_data;
+static int hf_stat_data_prefix_rej;
+static int hf_stat_data_prefix_dup;
+static int hf_stat_data_withdraw_dup;
+static int hf_stat_data_cluster_loop;
+static int hf_stat_data_as_loop;
+static int hf_stat_data_inv_originator;
+static int hf_stat_data_as_confed_loop;
+static int hf_stat_data_routes_adj_rib_in;
+static int hf_stat_data_routes_loc_rib;
+static int hf_stat_data_routes_per_adj_rib_in_afi;
+static int hf_stat_data_routes_per_adj_rib_in_safi;
+static int hf_stat_data_routes_per_adj_rib_in;
+static int hf_stat_data_routes_per_loc_rib_afi;
+static int hf_stat_data_routes_per_loc_rib_safi;
+static int hf_stat_data_routes_per_loc_rib;
+static int hf_stat_data_update_treat;
+static int hf_stat_data_prefixes_treat;
+static int hf_stat_data_duplicate_update;
+static int hf_stat_data_routes_pre_adj_rib_out;
+static int hf_stat_data_routes_post_adj_rib_out;
+static int hf_stat_data_routes_pre_per_adj_rib_out_afi;
+static int hf_stat_data_routes_pre_per_adj_rib_out_safi;
+static int hf_stat_data_routes_pre_per_adj_rib_out;
+static int hf_stat_data_routes_post_per_adj_rib_out_afi;
+static int hf_stat_data_routes_post_per_adj_rib_out_safi;
+static int hf_stat_data_routes_post_per_adj_rib_out;
/* BMP Termination field */
-static int hf_term_types = -1;
-static int hf_term_type = -1;
-static int hf_term_len = -1;
-static int hf_term_info = -1;
-static int hf_term_reason = -1;
+static int hf_term_types;
+static int hf_term_type;
+static int hf_term_len;
+static int hf_term_info;
+static int hf_term_reason;
/* BMP Route Policy */
-static int hf_route_policy_flags = -1;
-static int hf_route_policy_flags_ipv6 = -1;
-static int hf_route_policy_flags_res = -1;
-static int hf_route_policy_rd = -1;
-static int hf_route_policy_prefix_length = -1;
-static int hf_route_policy_prefix_ipv4 = -1;
-static int hf_route_policy_prefix_reserved = -1;
-static int hf_route_policy_prefix_ipv6 = -1;
-static int hf_route_policy_route_origin = -1;
-static int hf_route_policy_event_count = -1;
-static int hf_route_policy_total_event_length = -1;
-static int hf_route_policy_single_event_length = -1;
-static int hf_route_policy_event_index = -1;
-static int hf_route_policy_timestamp_sec = -1;
-static int hf_route_policy_timestamp_msec = -1;
-static int hf_route_policy_path_identifier = -1;
-static int hf_route_policy_afi = -1;
-static int hf_route_policy_safi = -1;
-static int hf_route_policy_tlv = -1;
-static int hf_route_policy_tlv_type = -1;
-static int hf_route_policy_tlv_length = -1;
-static int hf_route_policy_tlv_value = -1;
-static int hf_route_policy_tlv_vrf_table_id = -1;
-static int hf_route_policy_tlv_vrf_table_name = -1;
-static int hf_route_policy_tlv_policy_flags = -1;
-static int hf_route_policy_tlv_policy_flags_m = -1;
-static int hf_route_policy_tlv_policy_flags_p = -1;
-static int hf_route_policy_tlv_policy_flags_d = -1;
-static int hf_route_policy_tlv_policy_flags_res = -1;
-static int hf_route_policy_tlv_policy_count = -1;
-static int hf_route_policy_tlv_policy_class = -1;
-static int hf_route_policy_tlv_policy_peer_ipv4 = -1;
-static int hf_route_policy_tlv_policy_peer_ipv6 = -1;
-static int hf_route_policy_tlv_policy_peer_reserved = -1;
-static int hf_route_policy_tlv_policy_peer_router_id = -1;
-static int hf_route_policy_tlv_policy_peer_as = -1;
-static int hf_route_policy_tlv_policy = -1;
-static int hf_route_policy_tlv_policy_name_length = -1;
-static int hf_route_policy_tlv_policy_item_id_length = -1;
-static int hf_route_policy_tlv_policy_name = -1;
-static int hf_route_policy_tlv_policy_item_id = -1;
-static int hf_route_policy_tlv_policy_flag = -1;
-static int hf_route_policy_tlv_policy_flag_c = -1;
-static int hf_route_policy_tlv_policy_flag_r = -1;
-static int hf_route_policy_tlv_policy_flag_res2 = -1;
-
-static int hf_route_policy_tlv_string = -1;
-
-static gint ett_bmp = -1;
-static gint ett_bmp_route_monitoring = -1;
-static gint ett_bmp_stat_report = -1;
-static gint ett_bmp_stat_type = -1;
-static gint ett_bmp_peer_down = -1;
-static gint ett_bmp_peer_up = -1;
-static gint ett_bmp_peer_up_tlv = -1;
-static gint ett_bmp_peer_header = -1;
-static gint ett_bmp_peer_flags = -1;
-static gint ett_bmp_init = -1;
-static gint ett_bmp_init_types = -1;
-static gint ett_bmp_init_type = -1;
-static gint ett_bmp_term = -1;
-static gint ett_bmp_term_type = -1;
-static gint ett_bmp_term_types = -1;
-static gint ett_bmp_route_mirroring = -1;
-static gint ett_bmp_route_policy_flags = -1;
-static gint ett_bmp_route_policy_tlv = -1;
-static gint ett_bmp_route_policy_tlv_policy_flags = -1;
-static gint ett_bmp_route_policy_tlv_policy = -1;
-
-static expert_field ei_stat_data_unknown = EI_INIT;
+static int hf_route_policy_flags;
+static int hf_route_policy_flags_ipv6;
+static int hf_route_policy_flags_res;
+static int hf_route_policy_rd;
+static int hf_route_policy_prefix_length;
+static int hf_route_policy_prefix_ipv4;
+static int hf_route_policy_prefix_reserved;
+static int hf_route_policy_prefix_ipv6;
+static int hf_route_policy_route_origin;
+static int hf_route_policy_event_count;
+static int hf_route_policy_total_event_length;
+static int hf_route_policy_single_event_length;
+static int hf_route_policy_event_index;
+static int hf_route_policy_timestamp_sec;
+static int hf_route_policy_timestamp_msec;
+static int hf_route_policy_path_identifier;
+static int hf_route_policy_afi;
+static int hf_route_policy_safi;
+static int hf_route_policy_tlv;
+static int hf_route_policy_tlv_type;
+static int hf_route_policy_tlv_length;
+static int hf_route_policy_tlv_value;
+static int hf_route_policy_tlv_vrf_table_id;
+static int hf_route_policy_tlv_vrf_table_name;
+static int hf_route_policy_tlv_policy_flags;
+static int hf_route_policy_tlv_policy_flags_m;
+static int hf_route_policy_tlv_policy_flags_p;
+static int hf_route_policy_tlv_policy_flags_d;
+static int hf_route_policy_tlv_policy_flags_res;
+static int hf_route_policy_tlv_policy_count;
+static int hf_route_policy_tlv_policy_class;
+static int hf_route_policy_tlv_policy_peer_ipv4;
+static int hf_route_policy_tlv_policy_peer_ipv6;
+static int hf_route_policy_tlv_policy_peer_reserved;
+static int hf_route_policy_tlv_policy_peer_router_id;
+static int hf_route_policy_tlv_policy_peer_as;
+static int hf_route_policy_tlv_policy;
+static int hf_route_policy_tlv_policy_name_length;
+static int hf_route_policy_tlv_policy_item_id_length;
+static int hf_route_policy_tlv_policy_name;
+static int hf_route_policy_tlv_policy_item_id;
+static int hf_route_policy_tlv_policy_flag;
+static int hf_route_policy_tlv_policy_flag_c;
+static int hf_route_policy_tlv_policy_flag_r;
+static int hf_route_policy_tlv_policy_flag_res2;
+
+static int hf_route_policy_tlv_string;
+
+static int hf_bmpv4_tlv;
+static int hf_bmpv4_tlv_type;
+static int hf_bmpv4_tlv_length;
+static int hf_bmpv4_tlv_index;
+static int hf_bmpv4_tlv_value_bytes;
+static int hf_bmpv4_tlv_value_string;
+static int hf_bmpv4_tlv_value_bool;
+static int hf_bmpv4_tlv_value_index;
+static int hf_bmpv4_tlv_group_id;
+
+static int ett_bmp;
+static int ett_bmp_route_monitoring;
+static int ett_bmp_stat_report;
+static int ett_bmp_stat_type;
+static int ett_bmp_peer_down;
+static int ett_bmp_peer_up;
+static int ett_bmp_peer_state_tlv;
+static int ett_bmp_peer_header;
+static int ett_bmp_peer_flags;
+static int ett_bmp_init;
+static int ett_bmp_init_types;
+static int ett_bmp_init_type;
+static int ett_bmp_term;
+static int ett_bmp_term_type;
+static int ett_bmp_term_types;
+static int ett_bmp_route_mirroring;
+static int ett_bmp_route_policy_flags;
+static int ett_bmp_route_policy_tlv;
+static int ett_bmp_route_policy_tlv_policy_flags;
+static int ett_bmp_route_policy_tlv_policy;
+static int ett_bmpv4_tlv;
+static int ett_bmpv4_tlv_value;
+
+static expert_field ei_stat_data_unknown;
+static expert_field ei_bmpv4_tlv_wrong_cap_size;
+static expert_field ei_bmpv4_tlv_wrong_cap_value;
+static expert_field ei_bmpv4_tlv_string_bad_length;
static dissector_handle_t bmp_handle;
static dissector_handle_t dissector_bgp;
/* desegmentation */
-static gboolean bmp_desegment = TRUE;
+static bool bmp_desegment = true;
+
+typedef struct bmpv4_tlv_info {
+ uint16_t type;
+ uint16_t length;
+ uint16_t idx;
+ bool has_index;
+} bmpv4_tlv_info;
+
+/* Dissect BMPv4 TLV Header
+ *
+ * with Index (Route Monitoring Message)
+ * 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Type (2 octets) | Length (2 octets) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Index (2 octets) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Value (variable) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * without Index
+ * 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Type (2 octets) | Length (2 octets) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Value (variable) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+static bmpv4_tlv_info bmpv4_dissect_tlv_hdr(tvbuff_t *tvb, proto_tree **tree_ref, int *offset_ref, uint8_t bmp_type) {
+
+ int offset = *offset_ref;
+ proto_tree *tree = *tree_ref;
+ uint32_t value_holder;
+ bmpv4_tlv_info tlv = { 0 };
+
+ tlv.type = tvb_get_ntohs(tvb, offset);
+ tlv.length = tvb_get_ntohs(tvb, offset + 2);
+ tlv.has_index = bmp_type == BMP_MSG_TYPE_ROUTE_MONITORING;
+ int total_length = 2 /* type field */
+ + 2 /* length field */
+ + (tlv.has_index ? 2 : 0) /* index field, if present */
+ + tlv.length; /* tlv value length */
+
+ proto_item *ti = proto_tree_add_item(tree, hf_bmpv4_tlv, tvb, offset, total_length, ENC_NA);
+ proto_item_append_text(ti, ": %s", val_to_str(tlv.type, bmpv4_tlv_typevals, "Unknown (0x%02x)"));
+
+ proto_tree *subtree = proto_item_add_subtree(ti, ett_bmpv4_tlv);
+
+ proto_tree_add_item(subtree, hf_bmpv4_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+
+ proto_tree_add_item_ret_uint(subtree, hf_bmpv4_tlv_length, tvb, offset, 2, ENC_BIG_ENDIAN, &value_holder);
+ offset += 2;
+
+ if (tlv.has_index) {
+ proto_tree_add_item_ret_uint(subtree, hf_bmpv4_tlv_index, tvb, offset, 2, ENC_BIG_ENDIAN, &value_holder);
+ tlv.idx = (uint16_t) value_holder;
+ offset += 2;
+ }
+
+ *offset_ref = offset;
+ *tree_ref = subtree;
+
+ return tlv;
+}
+
+static void bmpv4_dissect_tlvs(proto_tree *tree, tvbuff_t *tvb, int offset, packet_info *pinfo, uint8_t bmp_msg_type) {
+ bmpv4_tlv_info tlv = { 0 };
+
+ while (tvb_captured_length_remaining(tvb, offset) >= 4) {
+ proto_tree *tlv_tree = tree;
+ tlv = bmpv4_dissect_tlv_hdr(tvb, &tlv_tree, &offset, bmp_msg_type);
+
+ switch (tlv.type) {
+ case BMPv4_TLV_TYPE_GROUP: {
+
+ proto_tree_add_item(tlv_tree, hf_bmpv4_tlv_group_id, tvb, offset, 2, ENC_NA);
+ offset += 2;
+
+ int list_length = tlv.length - 2 /* group id is not in list */;
+ proto_item *ti = proto_tree_add_item(tlv_tree, hf_bmpv4_tlv_value_bytes, tvb, offset, list_length, ENC_NA);
+
+ int list_count = list_length / BMPv4_TLV_LENGTH_GROUP_ITEM;
+ proto_item_set_text(ti, "Target Count: %d", list_count);
+ proto_item *subtree = proto_item_add_subtree(ti, ett_bmpv4_tlv_value);
+
+ for (int i = 0; i < list_count; i++) {
+ proto_tree_add_item(subtree, hf_bmpv4_tlv_value_index, tvb, offset, BMPv4_TLV_LENGTH_GROUP_ITEM, ENC_NA);
+ offset += BMPv4_TLV_LENGTH_GROUP_ITEM;
+ }
+
+ break;
+ }
+ case BMPv4_TLV_TYPE_VRF_TABLE_NAME: {
+
+ proto_item *ti = proto_tree_add_item(tlv_tree, hf_bmpv4_tlv_value_string, tvb, offset, tlv.length, ENC_ASCII);
+ offset += tlv.length;
+
+ if (tlv.length == 0 || tlv.length > BMPv4_TLV_LENGTH_VRF_TABLE_NAME_MAX_LENGTH) {
+ expert_add_info(pinfo, ti, &ei_bmpv4_tlv_string_bad_length);
+ }
+ break;
+ }
+ case BMPv4_TLV_TYPE_BGP_CAP_ADDPATH:
+ case BMPv4_TLV_TYPE_BGP_CAP_MULTIPLE_LBL: {
+
+ uint16_t cap_value = tvb_get_uint8(tvb, offset);
+ if (cap_value != 0 && cap_value != 1) {
+ expert_add_info(pinfo, tlv_tree, &ei_bmpv4_tlv_wrong_cap_value);
+ }
+
+ if (tlv.length != BMPv4_TLV_LENGTH_BGP_CAPABILITY) {
+ expert_add_info(pinfo, tlv_tree, &ei_bmpv4_tlv_wrong_cap_size);
+ }
+
+ proto_tree_add_item(tlv_tree, hf_bmpv4_tlv_value_bool, tvb, offset, BMPv4_TLV_LENGTH_BGP_CAPABILITY, ENC_NA);
+ offset += BMPv4_TLV_LENGTH_BGP_CAPABILITY;
+
+ break;
+ }
+ case BMPv4_TLV_TYPE_BGP_MSG: {
+
+ proto_item *ti = proto_tree_add_item(tlv_tree, hf_bmpv4_tlv_value_bytes, tvb, offset, tlv.length, ENC_NA);
+ proto_tree *subtree = proto_item_add_subtree(ti, ett_bmpv4_tlv_value);
+
+ call_dissector(dissector_bgp, tvb_new_subset_length(tvb, offset, tlv.length), pinfo, subtree);
+
+ offset += tlv.length;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
/*
* Dissect BMP Peer Down Notification
@@ -432,21 +611,62 @@ static gboolean bmp_desegment = TRUE;
*
*/
static void
-dissect_bmp_peer_down_notification(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset, gint8 flags _U_)
+dissect_bmp_peer_down_notification(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset, int8_t flags _U_, bool is_v4)
{
- guint8 down_reason;
+ uint8_t down_reason;
- down_reason = tvb_get_guint8(tvb, offset);
+ down_reason = tvb_get_uint8(tvb, offset);
proto_tree_add_item(tree, hf_peer_down_reason, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
- if (down_reason != BMP_PEER_DOWN_REMOTE_NO_NOTIFY) {
- if (down_reason == BMP_PEER_DOWN_LOCAL_NO_NOTIFY) {
+ /* bmp version 3 */
+ switch (down_reason) {
+ case BMP_PEER_DOWN_LOCAL_NO_NOTIFY: {
+ /* FSM event code */
proto_tree_add_item(tree, hf_peer_down_data, tvb, offset, 2, ENC_NA);
- } else {
+ break;
+ }
+ case BMP_PEER_DOWN_LOCAL_NOTIFY:
+ case BMP_PEER_DOWN_REMOTE_NOTIFY: {
col_clear(pinfo->cinfo, COL_INFO);
call_dissector(dissector_bgp, tvb_new_subset_remaining(tvb, offset), pinfo, tree);
+ break;
+ }
+ case BMP_PEER_DOWN_LOCAL_SYSTEM_CLOSED: {
+ uint32_t type, length;
+ proto_item *tlv_item;
+ proto_tree *tlv_tree;
+ tlv_item = proto_tree_add_item(tree, hf_peer_state_tlv, tvb, offset, 2 + 2, ENC_NA);
+ tlv_tree = proto_item_add_subtree(tlv_item, ett_bmp_peer_state_tlv);
+
+ type = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
+
+ /* unknown tlv type, and we support other types with version 4 so let v4 dissect it */
+ if (try_val_to_str(type, peer_down_tlv_typevals) == NULL && is_v4) {
+ break;
+ }
+
+ proto_tree_add_item(tlv_tree, hf_peer_state_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+
+ proto_tree_add_item_ret_uint(tlv_tree, hf_peer_state_tlv_length, tvb, offset, 2, ENC_BIG_ENDIAN, &length);
+ offset += 2;
+
+ 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)") );
+ proto_item_set_len(tlv_item, 2 + 2 + length);
+
+ proto_tree_add_item(tlv_tree, hf_peer_state_tlv_value, tvb, offset, length, ENC_NA);
+ proto_tree_add_item(tlv_tree, hf_peer_state_tlv_vrf_table_name, tvb, offset, length, ENC_ASCII);
+ offset += length;
}
+ default:
+ break;
+ }
+
+ /* bmp version 4 */
+ if (is_v4) {
+ bmpv4_dissect_tlvs(tree, tvb, offset, pinfo, BMP_MSG_TYPE_PEER_DOWN);
+ return;
}
}
@@ -472,7 +692,7 @@ dissect_bmp_peer_down_notification(tvbuff_t *tvb, proto_tree *tree, packet_info
*
*/
static void
-dissect_bmp_peer_up_notification(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset, gint8 flags)
+dissect_bmp_peer_up_notification(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset, int8_t flags)
{
if (flags & BMP_PEER_FLAG_IPV6) {
proto_tree_add_item(tree, hf_peer_up_ipv6_address, tvb, offset, 16, ENC_NA);
@@ -495,22 +715,22 @@ dissect_bmp_peer_up_notification(tvbuff_t *tvb, proto_tree *tree, packet_info *p
offset += call_dissector(dissector_bgp, tvb_new_subset_remaining(tvb, offset), pinfo, tree);
while (tvb_reported_length_remaining(tvb, offset) > 0) {
- guint32 type, length;
+ uint32_t type, length;
proto_item *tlv_item;
proto_tree *tlv_tree;
- tlv_item = proto_tree_add_item(tree, hf_peer_up_tlv, tvb, offset, 2+2, ENC_NA);
- tlv_tree = proto_item_add_subtree(tlv_item, ett_bmp_peer_up_tlv);
+ tlv_item = proto_tree_add_item(tree, hf_peer_state_tlv, tvb, offset, 2 + 2, ENC_NA);
+ tlv_tree = proto_item_add_subtree(tlv_item, ett_bmp_peer_state_tlv);
- proto_tree_add_item_ret_uint(tlv_tree, hf_peer_up_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN, &type);
+ proto_tree_add_item_ret_uint(tlv_tree, hf_peer_state_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN, &type);
offset += 2;
- proto_tree_add_item_ret_uint(tlv_tree, hf_peer_up_tlv_length, tvb, offset, 2, ENC_BIG_ENDIAN, &length);
+ proto_tree_add_item_ret_uint(tlv_tree, hf_peer_state_tlv_length, tvb, offset, 2, ENC_BIG_ENDIAN, &length);
offset += 2;
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)") );
proto_item_set_len(tlv_item, 2 + 2 + length);
- proto_tree_add_item(tlv_tree, hf_peer_up_tlv_value, tvb, offset, length, ENC_NA);
+ proto_tree_add_item(tlv_tree, hf_peer_state_tlv_value, tvb, offset, length, ENC_NA);
switch(type){
case BMP_PEER_UP_TLV_STRING: {
proto_tree_add_item(tlv_tree, hf_peer_up_tlv_string, tvb, offset, length, ENC_ASCII);
@@ -527,8 +747,8 @@ dissect_bmp_peer_up_notification(tvbuff_t *tvb, proto_tree *tree, packet_info *p
offset += length;
}
break;
- case BMP_PEER_UP_TLV_VRF_TABLE_NAME: {
- proto_tree_add_item(tlv_tree, hf_peer_up_tlv_vrf_table_name, tvb, offset, length, ENC_ASCII);
+ case BMP_PEER_STATE_TLV_VRF_TABLE_NAME: {
+ proto_tree_add_item(tlv_tree, hf_peer_state_tlv_vrf_table_name, tvb, offset, length, ENC_ASCII);
offset += length;
}
break;
@@ -568,12 +788,12 @@ dissect_bmp_peer_up_notification(tvbuff_t *tvb, proto_tree *tree, packet_info *p
*
*/
static void
-dissect_bmp_stat_report(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset, gint8 flags _U_)
+dissect_bmp_stat_report(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset, int8_t flags _U_)
{
- guint32 stat_len, stat_type;
- guint32 i;
+ uint32_t stat_len, stat_type;
+ uint32_t i;
- guint32 stats_count = tvb_get_ntohl(tvb, offset);
+ uint32_t stats_count = tvb_get_ntohl(tvb, offset);
proto_tree_add_item(tree, hf_stats_count, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
@@ -700,10 +920,10 @@ dissect_bmp_stat_report(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int
*
*/
static void
-dissect_bmp_termination(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, int offset, guint8 bmp_type _U_, guint16 len)
+dissect_bmp_termination(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, int offset, uint8_t bmp_type _U_, uint16_t len)
{
- guint16 term_type;
- guint16 term_len;
+ uint16_t term_type;
+ uint16_t term_len;
proto_item *ti;
proto_item *subtree;
@@ -730,7 +950,6 @@ dissect_bmp_termination(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_,
/*offset += term_len;*/
}
-
/*
* Dissect BMP Per-Peer Header
*
@@ -755,13 +974,13 @@ dissect_bmp_termination(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_,
*
*/
static void
-dissect_bmp_peer_header(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset, guint8 bmp_type, guint16 len)
+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)
{
- guint8 flags;
- guint32 type;
+ uint8_t flags;
+ uint32_t type;
proto_item *item;
proto_item *ti;
- proto_item *subtree;
+ proto_item *peer_hdr_subtree;
static int * const peer_flags[] = {
&hf_peer_flags_ipv6,
@@ -778,54 +997,61 @@ dissect_bmp_peer_header(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int
};
ti = proto_tree_add_item(tree, hf_peer_header, tvb, offset, len, ENC_NA);
- subtree = proto_item_add_subtree(ti, ett_bmp_peer_header);
+ peer_hdr_subtree = proto_item_add_subtree(ti, ett_bmp_peer_header);
- proto_tree_add_item_ret_uint(subtree, hf_peer_type, tvb, offset, 1, ENC_BIG_ENDIAN, &type);
+ proto_tree_add_item_ret_uint(peer_hdr_subtree, hf_peer_type, tvb, offset, 1, ENC_BIG_ENDIAN, &type);
offset += 1;
- flags = tvb_get_guint8(tvb, offset);
+ flags = tvb_get_uint8(tvb, offset);
if (type == BMP_PEER_LOC_RIB_INSTANCE) {
- proto_tree_add_bitmask(subtree, tvb, offset, hf_peer_flags, ett_bmp_peer_flags, peer_flags_loc_rib, ENC_NA);
+ proto_tree_add_bitmask(peer_hdr_subtree, tvb, offset, hf_peer_flags, ett_bmp_peer_flags, peer_flags_loc_rib, ENC_NA);
} else {
- proto_tree_add_bitmask(subtree, tvb, offset, hf_peer_flags, ett_bmp_peer_flags, peer_flags, ENC_NA);
+ proto_tree_add_bitmask(peer_hdr_subtree, tvb, offset, hf_peer_flags, ett_bmp_peer_flags, peer_flags, ENC_NA);
}
offset += 1;
- item = proto_tree_add_item(subtree, hf_peer_distinguisher, tvb, offset, 8, ENC_NA);
+ item = proto_tree_add_item(peer_hdr_subtree, hf_peer_distinguisher, tvb, offset, 8, ENC_NA);
proto_item_set_text(item, "Peer Distinguisher: %s", decode_bgp_rd(pinfo->pool, tvb, offset));
offset += 8;
if (flags & BMP_PEER_FLAG_IPV6) {
- proto_tree_add_item(subtree, hf_peer_ipv6_address, tvb, offset, 16, ENC_NA);
+ proto_tree_add_item(peer_hdr_subtree, hf_peer_ipv6_address, tvb, offset, 16, ENC_NA);
offset += 16;
} else {
- proto_tree_add_item(subtree, hf_bmp_unused, tvb, offset, 12, ENC_NA);
+ proto_tree_add_item(peer_hdr_subtree, hf_bmp_unused, tvb, offset, 12, ENC_NA);
offset += 12;
- proto_tree_add_item(subtree, hf_peer_ipv4_address, tvb, offset, 4, ENC_BIG_ENDIAN);
+ proto_tree_add_item(peer_hdr_subtree, hf_peer_ipv4_address, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
}
- proto_tree_add_item(subtree, hf_peer_asn, tvb, offset, 4, ENC_BIG_ENDIAN);
+ proto_tree_add_item(peer_hdr_subtree, hf_peer_asn, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
- proto_tree_add_item(subtree, hf_peer_bgp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+ proto_tree_add_item(peer_hdr_subtree, hf_peer_bgp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
- proto_tree_add_item(subtree, hf_peer_timestamp_sec, tvb, offset, 4, ENC_BIG_ENDIAN);
+ proto_tree_add_item(peer_hdr_subtree, hf_peer_timestamp_sec, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
- proto_tree_add_item(subtree, hf_peer_timestamp_msec, tvb, offset, 4, ENC_BIG_ENDIAN);
+ proto_tree_add_item(peer_hdr_subtree, hf_peer_timestamp_msec, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
- switch (bmp_type) {
- case BMP_MSG_TYPE_ROUTE_MONITORING:
+ bool is_v4 = bmp_version == 4;
+
+ switch (bmp_msg_type) {
+ case BMP_MSG_TYPE_ROUTE_MONITORING: {
+ if (is_v4) {
+ bmpv4_dissect_tlvs(tree, tvb, offset, pinfo, bmp_msg_type);
+ } else {
col_clear(pinfo->cinfo, COL_INFO);
call_dissector(dissector_bgp, tvb_new_subset_remaining(tvb, offset), pinfo, tree);
- break;
+ }
+ break;
+ }
case BMP_MSG_TYPE_ROUTE_MIRRORING: {
while (tvb_reported_length_remaining(tvb, offset) > 0) {
- guint32 route_mirroring_type, length;
+ uint32_t route_mirroring_type, length;
proto_tree_add_item_ret_uint(tree, hf_peer_route_mirroring_type, tvb, offset, 2, ENC_BIG_ENDIAN, &route_mirroring_type);
offset += 2;
proto_tree_add_item_ret_uint(tree, hf_peer_route_mirroring_length, tvb, offset, 2, ENC_BIG_ENDIAN, &length);
@@ -848,9 +1074,10 @@ dissect_bmp_peer_header(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int
case BMP_MSG_TYPE_STAT_REPORT:
dissect_bmp_stat_report(tvb, tree, pinfo, offset, flags);
break;
- case BMP_MSG_TYPE_PEER_DOWN:
- dissect_bmp_peer_down_notification(tvb, tree, pinfo, offset, flags);
- break;
+ case BMP_MSG_TYPE_PEER_DOWN: {
+ dissect_bmp_peer_down_notification(tvb, tree, pinfo, offset, flags, is_v4);
+ break;
+ }
case BMP_MSG_TYPE_PEER_UP:
dissect_bmp_peer_up_notification(tvb, tree, pinfo, offset, flags);
break;
@@ -862,8 +1089,6 @@ dissect_bmp_peer_header(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int
}
}
-
-
/*
* Dissect BMP Initiation Message
*
@@ -877,10 +1102,10 @@ dissect_bmp_peer_header(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int
*
*/
static void
-dissect_bmp_init(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, int offset, guint8 bmp_type _U_, guint16 len)
+dissect_bmp_init(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, int offset, uint8_t bmp_type _U_, uint16_t len)
{
- guint16 init_type;
- guint16 init_len;
+ uint16_t init_type;
+ uint16_t init_len;
proto_tree *pti;
proto_tree *parent_tree;
@@ -939,7 +1164,7 @@ dissect_bmp_init(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, int of
static int
dissect_bmp_route_policy_event(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, int offset)
{
- guint32 single_event_length;
+ uint32_t single_event_length;
proto_tree_add_item_ret_uint(tree, hf_route_policy_single_event_length, tvb, offset, 2, ENC_NA, &single_event_length);
offset += 2;
@@ -970,7 +1195,7 @@ dissect_bmp_route_policy_event(tvbuff_t *tvb, proto_tree *tree, packet_info *pin
single_event_length -=1;
while (single_event_length > 0) {
- guint32 type, length;
+ uint32_t type, length;
proto_item *tlv_item;
proto_tree *tlv_tree;
tlv_item = proto_tree_add_item(tree, hf_route_policy_tlv, tvb, offset, 2+2, ENC_NA);
@@ -997,8 +1222,8 @@ dissect_bmp_route_policy_event(tvbuff_t *tvb, proto_tree *tree, packet_info *pin
}
break;
case BMP_ROUTE_POLICY_TLV_POLICY: {
- guint8 flags;
- guint32 policy_count;
+ uint8_t flags;
+ uint32_t policy_count;
static int * const route_policy_tlv_policy_flags[] = {
&hf_route_policy_tlv_policy_flags_m,
&hf_route_policy_tlv_policy_flags_p,
@@ -1013,7 +1238,7 @@ dissect_bmp_route_policy_event(tvbuff_t *tvb, proto_tree *tree, packet_info *pin
NULL
};
- flags = tvb_get_guint8(tvb, offset);
+ flags = tvb_get_uint8(tvb, offset);
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);
offset += 1;
proto_tree_add_item_ret_uint(tlv_tree, hf_route_policy_tlv_policy_count, tvb, offset, 1, ENC_BIG_ENDIAN, &policy_count);
@@ -1041,8 +1266,8 @@ dissect_bmp_route_policy_event(tvbuff_t *tvb, proto_tree *tree, packet_info *pin
while(policy_count){
proto_item *policy_item;
proto_tree *policy_tree;
- const guint8 *policy_name, *policy_id;
- guint32 policy_name_length, policy_item_id_length;
+ const uint8_t *policy_name, *policy_id;
+ uint32_t policy_name_length, policy_item_id_length;
policy_item = proto_tree_add_item(tlv_tree, hf_route_policy_tlv_policy, tvb, offset, 2+2, ENC_NA);
policy_tree = proto_item_add_subtree(policy_item, ett_bmp_route_policy_tlv_policy);
@@ -1136,10 +1361,10 @@ dissect_bmp_route_policy_event(tvbuff_t *tvb, proto_tree *tree, packet_info *pin
*
*/
static void
-dissect_bmp_route_policy(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset, guint8 bmp_type _U_, guint16 len _U_)
+dissect_bmp_route_policy(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, int offset, uint8_t bmp_type _U_, uint16_t len _U_)
{
- guint8 flags;
- guint32 event_count;
+ uint8_t flags;
+ uint32_t event_count;
static int * const route_policy_flags[] = {
&hf_route_policy_flags_ipv6,
@@ -1147,7 +1372,7 @@ dissect_bmp_route_policy(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, in
NULL
};
- flags = tvb_get_guint8(tvb, offset);
+ flags = tvb_get_uint8(tvb, offset);
proto_tree_add_bitmask(tree, tvb, offset, hf_route_policy_flags, ett_bmp_route_policy_flags, route_policy_flags, ENC_NA);
offset += 1;
@@ -1196,7 +1421,7 @@ dissect_bmp_route_policy(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, in
* +---------------+
*
*/
-static guint
+static unsigned
get_bmp_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
{
return tvb_get_ntohl(tvb, offset + 1);
@@ -1206,16 +1431,16 @@ static int
dissect_bmp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
int offset = 0;
- guint8 bmp_type;
- guint16 len;
- gint arg;
+ uint8_t bmp_type;
+ uint16_t len;
+ int arg;
proto_item *ti;
proto_item *bmp_tree;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "BMP");
col_clear(pinfo->cinfo, COL_INFO);
- bmp_type = tvb_get_guint8(tvb, 5);
+ bmp_type = tvb_get_uint8(tvb, 5);
col_add_fstr(pinfo->cinfo, COL_INFO, "Type: %s",
val_to_str(bmp_type, bmp_typevals, "Unknown (0x%02x)"));
@@ -1253,7 +1478,10 @@ dissect_bmp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data
bmp_tree = proto_item_add_subtree(ti, arg);
- proto_tree_add_item(bmp_tree, hf_bmp_version, tvb, offset, 1, ENC_BIG_ENDIAN);
+ uint32_t bmp_version_tmp = 0;
+ proto_tree_add_item_ret_uint(bmp_tree, hf_bmp_version, tvb, offset, 1, ENC_BIG_ENDIAN, &bmp_version_tmp);
+ uint8_t bmp_version = (uint8_t) bmp_version_tmp;
+
offset += 1;
proto_tree_add_item(bmp_tree, hf_bmp_length, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
@@ -1271,7 +1499,7 @@ dissect_bmp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data
case BMP_MSG_TYPE_PEER_DOWN:
case BMP_MSG_TYPE_PEER_UP:
case BMP_MSG_TYPE_ROUTE_MIRRORING:
- dissect_bmp_peer_header(tvb, bmp_tree, pinfo, offset, bmp_type, len);
+ dissect_bmp_peer_header(tvb, bmp_tree, pinfo, offset, bmp_type, len, bmp_version);
break;
case BMP_MSG_TYPE_TERM:
dissect_bmp_termination(tvb, bmp_tree, pinfo, offset, bmp_type, len);
@@ -1408,17 +1636,17 @@ proto_register_bmp(void)
NULL, 0x0, NULL, HFILL }},
/* Peer Up TLV */
- { &hf_peer_up_tlv,
- { "Peer UP TLV", "bmp.peer_up.tlv", FT_NONE, BASE_NONE,
+ { &hf_peer_state_tlv,
+ { "Peer UP/Down TLV", "bmp.peer_state.tlv", FT_NONE, BASE_NONE,
NULL, 0x0, NULL, HFILL }},
- { &hf_peer_up_tlv_type,
- { "Type", "bmp.peer_up.tlv.type", FT_UINT16, BASE_DEC,
+ { &hf_peer_state_tlv_type,
+ { "Type", "bmp.peer_state.tlv.type", FT_UINT16, BASE_DEC,
VALS(peer_up_tlv_typevals), 0x0, NULL, HFILL }},
- { &hf_peer_up_tlv_length,
- { "Length", "bmp.peer_up.tlv.length", FT_UINT16, BASE_DEC,
+ { &hf_peer_state_tlv_length,
+ { "Length", "bmp.peer_state.tlv.length", FT_UINT16, BASE_DEC,
NULL, 0x0, NULL, HFILL }},
- { &hf_peer_up_tlv_value,
- { "Value", "bmp.peer_up.tlv.value", FT_BYTES, BASE_NONE,
+ { &hf_peer_state_tlv_value,
+ { "Value", "bmp.peer_state.tlv.value", FT_BYTES, BASE_NONE,
NULL, 0x0, NULL, HFILL }},
{ &hf_peer_up_tlv_string,
{ "String", "bmp.peer_up.tlv.sys_string", FT_STRING, BASE_NONE,
@@ -1429,8 +1657,8 @@ proto_register_bmp(void)
{ &hf_peer_up_tlv_sys_name,
{ "SysName", "bmp.peer_up.tlv.sys_name", FT_STRING, BASE_NONE,
NULL, 0x0, NULL, HFILL }},
- { &hf_peer_up_tlv_vrf_table_name,
- { "VRF/Table name", "bmp.peer_up.tlv.vrf_table_name", FT_STRING, BASE_NONE,
+ { &hf_peer_state_tlv_vrf_table_name,
+ { "VRF/Table name", "bmp.peer_state.tlv.vrf_table_name", FT_STRING, BASE_NONE,
NULL, 0x0, NULL, HFILL }},
{ &hf_peer_up_tlv_admin_label,
{ "Admin Label", "bmp.peer_up.tlv.admin_label", FT_STRING, BASE_NONE,
@@ -1691,17 +1919,46 @@ proto_register_bmp(void)
{ &hf_route_policy_tlv_string,
{ "String", "bmp.route_policy.tlv.string", FT_STRING, BASE_NONE,
NULL, 0x0, NULL, HFILL }},
+
+ /* BMPv4 TLVs */
+ { &hf_bmpv4_tlv,
+ { "BMPv4 TLV", "bmp.tlv", FT_NONE, BASE_NONE,
+ NULL, 0x0, NULL, HFILL }},
+ { &hf_bmpv4_tlv_type,
+ { "Type", "bmp.tlv.type", FT_UINT16, BASE_DEC,
+ NULL, 0x0, NULL, HFILL }},
+ { &hf_bmpv4_tlv_length,
+ { "Length", "bmp.tlv.length", FT_UINT16, BASE_DEC,
+ NULL, 0x0, NULL, HFILL }},
+ { &hf_bmpv4_tlv_index,
+ { "Index", "bmp.tlv.index", FT_UINT16, BASE_DEC,
+ NULL, 0x0, NULL, HFILL }},
+ { &hf_bmpv4_tlv_value_bytes,
+ { "Value", "bmp.tlv.value.bytes", FT_BYTES, SEP_SPACE,
+ NULL, 0x0, NULL, HFILL }},
+ { &hf_bmpv4_tlv_value_string,
+ { "Value", "bmp.tlv.value.string", FT_STRING, BASE_NONE,
+ NULL, 0x0, NULL, HFILL }},
+ { &hf_bmpv4_tlv_value_bool,
+ { "Value", "bmp.tlv.value.bool", FT_BOOLEAN, BASE_NONE,
+ NULL, 0x0, NULL, HFILL }},
+ { &hf_bmpv4_tlv_value_index,
+ { "Index", "bmp.tlv.value.index", FT_UINT16, BASE_DEC,
+ NULL, 0x0, NULL, HFILL }},
+ { &hf_bmpv4_tlv_group_id,
+ { "Group ID", "bmp.tlv.group_id", FT_UINT16, BASE_DEC,
+ NULL, 0x0, NULL, HFILL }},
};
/* Setup protocol subtree array */
- static gint *ett[] = {
+ static int *ett[] = {
&ett_bmp,
&ett_bmp_route_monitoring,
&ett_bmp_stat_report,
&ett_bmp_stat_type,
&ett_bmp_peer_down,
&ett_bmp_peer_up,
- &ett_bmp_peer_up_tlv,
+ &ett_bmp_peer_state_tlv,
&ett_bmp_peer_header,
&ett_bmp_peer_flags,
&ett_bmp_init,
@@ -1715,6 +1972,8 @@ proto_register_bmp(void)
&ett_bmp_route_policy_tlv,
&ett_bmp_route_policy_tlv_policy_flags,
&ett_bmp_route_policy_tlv_policy,
+ &ett_bmpv4_tlv,
+ &ett_bmpv4_tlv_value,
};
static ei_register_info ei[] = {
@@ -1722,6 +1981,18 @@ proto_register_bmp(void)
{ "bmp.stats.data.unknown", PI_UNDECODED, PI_NOTE,
"Unknown stats type payload", EXPFILL }
},
+ { &ei_bmpv4_tlv_wrong_cap_size,
+ { "bmp.tlv.capability.bad_size", PI_MALFORMED, PI_ERROR,
+ "Wrong capability size (should be 1)", EXPFILL }
+ },
+ { &ei_bmpv4_tlv_wrong_cap_value,
+ { "bmp.tlv.capability.bad_value", PI_MALFORMED, PI_ERROR,
+ "Wrong capability value (should be 0 or 1)", EXPFILL }
+ },
+ { &ei_bmpv4_tlv_string_bad_length,
+ { "bmp.tlv.string.bad_length", PI_MALFORMED, PI_NOTE,
+ "Bad string length (should be in range [1; 255])", EXPFILL }
+ },
};
module_t *bmp_module;