2 * Routines for BGP packet dissection.
3 * Copyright 1999, Jun-ichiro itojun Hagino <itojun@itojun.org>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * RFC1771 A Border Gateway Protocol 4 (BGP-4)
27 * RFC1965 Autonomous System Confederations for BGP
28 * RFC1997 BGP Communities Attribute
29 * RFC2547 BGP/MPLS VPNs
30 * RFC2796 BGP Route Reflection An alternative to full mesh IBGP
31 * RFC2842 Capabilities Advertisement with BGP-4
32 * RFC2858 Multiprotocol Extensions for BGP-4
33 * RFC2918 Route Refresh Capability for BGP-4
34 * RFC3107 Carrying Label Information in BGP-4
35 * RFC4486 Subcodes for BGP Cease Notification Message
36 * RFC4724 Graceful Restart Mechanism for BGP
37 * RFC5512 BGP Encapsulation SAFI and the BGP Tunnel Encapsulation Attribute
38 * RFC5640 Load-Balancing for Mesh Softwires
39 * RFC6608 Subcodes for BGP Finite State Machine Error
40 * RFC5575 Dissemination of flow specification rules
41 * draft-ietf-idr-as4bytes-06
42 * draft-ietf-idr-dynamic-cap-03
43 * draft-ietf-idr-bgp-enhanced-route-refresh-02
44 * draft-ietf-idr-bgp-ext-communities-05
45 * draft-knoll-idr-qos-attribute-03
46 * draft-nalawade-kapoor-tunnel-safi-05
47 * draft-ietf-idr-add-paths-04 Additional-Path for BGP-4
48 * http://www.iana.org/assignments/bgp-parameters/ (last updated 2012-04-26)
51 * Destination Preference Attribute for BGP (work in progress)
52 * RFC1863 A BGP/IDRP Route Server alternative to a full mesh routing
61 #include <epan/packet.h>
62 #include <epan/exceptions.h>
63 #include <epan/addr_and_mask.h>
64 #include <epan/show_exception.h>
66 #include <epan/prefs.h>
67 #include <epan/wmem/wmem.h>
68 #include <epan/expert.h>
69 #include <epan/etypes.h>
70 #include <packet-ip.h>
72 void proto_register_bgp(void);
73 void proto_reg_handoff_bgp(void);
75 /* #define MAX_STR_LEN 256 */
77 /* some handy things to know */
78 #define BGP_MAX_PACKET_SIZE 4096
79 #define BGP_MARKER_SIZE 16 /* size of BGP marker */
80 #define BGP_HEADER_SIZE 19 /* size of BGP header, including marker */
81 #define BGP_MIN_OPEN_MSG_SIZE 29
82 #define BGP_MIN_UPDATE_MSG_SIZE 23
83 #define BGP_MIN_NOTIFICATION_MSG_SIZE 21
84 #define BGP_MIN_KEEPALVE_MSG_SIZE BGP_HEADER_SIZE
85 #define BGP_TCP_PORT 179
86 #define BGP_ROUTE_DISTINGUISHER_SIZE 8
88 /* BGP message types */
91 #define BGP_NOTIFICATION 3
92 #define BGP_KEEPALIVE 4
93 #define BGP_ROUTE_REFRESH 5
94 #define BGP_CAPABILITY 6
95 #define BGP_ROUTE_REFRESH_CISCO 0x80
97 #define BGP_SIZE_OF_PATH_ATTRIBUTE 2
100 /* attribute flags, from RFC1771 */
101 #define BGP_ATTR_FLAG_OPTIONAL 0x80
102 #define BGP_ATTR_FLAG_TRANSITIVE 0x40
103 #define BGP_ATTR_FLAG_PARTIAL 0x20
104 #define BGP_ATTR_FLAG_EXTENDED_LENGTH 0x10
108 #define BGP_SSA_TRANSITIVE 0x8000
109 #define BGP_SSA_TYPE 0x7FFF
112 #define BGP_SSA_L2TPv3 1
113 #define BGP_SSA_mGRE 2
114 #define BGP_SSA_IPSec 3
115 #define BGP_SSA_MPLS 4
116 #define BGP_SSA_L2TPv3_IN_IPSec 5
117 #define BGP_SSA_mGRE_IN_IPSec 6
119 /* AS_PATH segment types */
120 #define AS_SET 1 /* RFC1771 */
121 #define AS_SEQUENCE 2 /* RFC1771 */
122 #define AS_CONFED_SET 4 /* RFC1965 has the wrong values, corrected in */
123 #define AS_CONFED_SEQUENCE 3 /* draft-ietf-idr-bgp-confed-rfc1965bis-01.txt */
125 /* OPEN message Optional Parameter types */
126 #define BGP_OPTION_AUTHENTICATION 1 /* RFC1771 */
127 #define BGP_OPTION_CAPABILITY 2 /* RFC2842 */
129 /* BGP capability code */
130 #define BGP_CAPABILITY_RESERVED 0 /* RFC2434 */
131 #define BGP_CAPABILITY_MULTIPROTOCOL 1 /* RFC2858 */
132 #define BGP_CAPABILITY_ROUTE_REFRESH 2 /* RFC2918 */
133 #define BGP_CAPABILITY_COOPERATIVE_ROUTE_FILTERING 3 /* draft-ietf-idr-route-filter-04.txt */
134 #define BGP_CAPABILITY_GRACEFUL_RESTART 0x40 /* draft-ietf-idr-restart-05 */
135 #define BGP_CAPABILITY_4_OCTET_AS_NUMBER 0x41 /* draft-ietf-idr-as4bytes-06 */
136 #define BGP_CAPABILITY_DYNAMIC_CAPABILITY 0x42 /* draft-ietf-idr-dynamic-cap-03 */
137 #define BGP_CAPABILITY_ADDITIONAL_PATHS 0x45 /* draft-ietf-idr-add-paths */
138 #define BGP_CAPABILITY_ENHANCED_ROUTE_REFRESH 0x46 /* draft-ietf-idr-bgp-enhanced-route-refresh-02 */
139 #define BGP_CAPABILITY_ORF_CISCO 0x82 /* Cisco */
140 #define BGP_CAPABILITY_ROUTE_REFRESH_CISCO 0x80 /* Cisco */
142 #define BGP_ORF_PREFIX_CISCO 0x80 /* Cisco */
143 #define BGP_ORF_COMM_CISCO 0x81 /* Cisco */
144 #define BGP_ORF_EXTCOMM_CISCO 0x82 /* Cisco */
145 #define BGP_ORF_ASPATH_CISCO 0x83 /* Cisco */
147 #define BGP_ORF_COMM 0x02 /* draft-ietf-idr-route-filter-06.txt */
148 #define BGP_ORF_EXTCOMM 0x03 /* draft-ietf-idr-route-filter-06.txt */
149 #define BGP_ORF_ASPATH 0x04 /* draft-ietf-idr-aspath-orf-02.txt */
150 /* draft-ietf-idr-route-filter-06.txt */
151 #define BGP_ORF_ACTION 0xc0
152 #define BGP_ORF_ADD 0x00
153 #define BGP_ORF_REMOVE 0x01
154 #define BGP_ORF_REMOVEALL 0x02
156 #define BGP_ORF_MATCH 0x20
157 #define BGP_ORF_PERMIT 0x00
158 #define BGP_ORF_DENY 0x01
160 /* well-known communities, from RFC1997 */
161 #define BGP_COMM_NO_EXPORT 0xFFFFFF01
162 #define BGP_COMM_NO_ADVERTISE 0xFFFFFF02
163 #define BGP_COMM_NO_EXPORT_SUBCONFED 0xFFFFFF03
164 #define FOURHEX0 0x00000000
165 #define FOURHEXF 0xFFFF0000
167 /* attribute types */
168 #define BGPTYPE_ORIGIN 1 /* RFC1771 */
169 #define BGPTYPE_AS_PATH 2 /* RFC1771 */
170 #define BGPTYPE_NEXT_HOP 3 /* RFC1771 */
171 #define BGPTYPE_MULTI_EXIT_DISC 4 /* RFC1771 */
172 #define BGPTYPE_LOCAL_PREF 5 /* RFC1771 */
173 #define BGPTYPE_ATOMIC_AGGREGATE 6 /* RFC1771 */
174 #define BGPTYPE_AGGREGATOR 7 /* RFC1771 */
175 #define BGPTYPE_COMMUNITIES 8 /* RFC1997 */
176 #define BGPTYPE_ORIGINATOR_ID 9 /* RFC2796 */
177 #define BGPTYPE_CLUSTER_LIST 10 /* RFC2796 */
178 #define BGPTYPE_DPA 11 /* work in progress */
179 #define BGPTYPE_ADVERTISER 12 /* RFC1863 */
180 #define BGPTYPE_RCID_PATH 13 /* RFC1863 */
181 #define BGPTYPE_MP_REACH_NLRI 14 /* RFC2858 */
182 #define BGPTYPE_MP_UNREACH_NLRI 15 /* RFC2858 */
183 #define BGPTYPE_EXTENDED_COMMUNITY 16 /* Draft Ramachandra */
184 #define BGPTYPE_NEW_AS_PATH 17 /* draft-ietf-idr-as4bytes */
185 #define BGPTYPE_NEW_AGGREGATOR 18 /* draft-ietf-idr-as4bytes */
186 #define BGPTYPE_SAFI_SPECIFIC_ATTR 19 /* draft-kapoor-nalawade-idr-bgp-ssa-00.txt */
187 #define BGPTYPE_TUNNEL_ENCAPS_ATTR 23 /* RFC5512 */
189 /* NLRI type as define in BGP flow spec RFC */
190 #define BGPNLRI_FSPEC_DST_PFIX 1 /* RFC 5575 */
191 #define BGPNLRI_FSPEC_SRC_PFIX 2 /* RFC 5575 */
192 #define BGPNLRI_FSPEC_IP_PROTO 3 /* RFC 5575 */
193 #define BGPNLRI_FSPEC_PORT 4 /* RFC 5575 */
194 #define BGPNLRI_FSPEC_DST_PORT 5 /* RFC 5575 */
195 #define BGPNLRI_FSPEC_SRC_PORT 6 /* RFC 5575 */
196 #define BGPNLRI_FSPEC_ICMP_TP 7 /* RFC 5575 */
197 #define BGPNLRI_FSPEC_ICMP_CD 8 /* RFC 5575 */
198 #define BGPNLRI_FSPEC_TCP_FLAGS 9 /* RFC 5575 */
199 #define BGPNLRI_FSPEC_PCK_LEN 10 /* RFC 5575 */
200 #define BGPNLRI_FSPEC_DSCP 11 /* RFC 5575 */
201 #define BGPNLRI_FSPEC_FRAGMENT 12 /* RFC 5575 */
203 /* BGP flow spec NLRI operator bitmask */
204 #define BGPNLRI_FSPEC_END_OF_LST 0x80
205 #define BGPNLRI_FSPEC_AND_BIT 0x40
206 #define BGPNLRI_FSPEC_VAL_LEN 0x30
207 #define BGPNLRI_FSPEC_UNUSED_BIT4 0x08
208 #define BGPNLRI_FSPEC_UNUSED_BIT5 0x04
209 #define BGPNLRI_FSPEC_LESS_THAN 0x04
210 #define BGPNLRI_FSPEC_GREATER_THAN 0x02
211 #define BGPNLRI_FSPEC_EQUAL 0x01
212 #define BGPNLRI_FSPEC_TCPF_NOTBIT 0x02
213 #define BGPNLRI_FSPEC_TCPF_MATCHBIT 0x01
214 #define BGPNLRI_FSPEC_DSCP_BITMASK 0xFC
216 /* BGP flow spec specific filter value: TCP flags, Packet fragment ... */
217 #define BGPNLRI_FSPEC_TH_FIN 0x01
218 #define BGPNLRI_FSPEC_TH_SYN 0x02
219 #define BGPNLRI_FSPEC_TH_RST 0x04
220 #define BGPNLRI_FSPEC_TH_PUSH 0x08
221 #define BGPNLRI_FSPEC_TH_ACK 0x10
222 #define BGPNLRI_FSPEC_TH_URG 0x20
223 #define BGPNLRI_FSPEC_TH_ECN 0x40
224 #define BGPNLRI_FSPEC_TH_CWR 0x80
226 #define BGPNLRI_FSPEC_FG_DF 0x01
227 #define BGPNLRI_FSPEC_FG_ISF 0x02
228 #define BGPNLRI_FSPEC_FG_FF 0x04
229 #define BGPNLRI_FSPEC_FG_LF 0x08
231 /* Extended community type */
232 /* according to IANA's number assignment at: http://www.iana.org/assignments/bgp-extended-communities */
233 #define BGP_EXT_COM_QOS_MARK_T 0x04 /* QoS Marking transitive attribute of regular type (8bit) */
234 #define BGP_EXT_COM_QOS_MARK_NT 0x44 /* QoS Marking non-transitive attribute of regular type (8bit) */
235 /* Format Type(1byte):Flags(1byte):QoS Set(1byte):Tec. Type(1byte): */
236 /* Marking O(2bytes):Marking A(1byte):Proc.Cnt(1byte) */
237 #define BGP_EXT_COM_COS_CAP_T 0x05 /* CoS Capability - Format Type(1byte):Flags(1byte):remaining '0..0' */
239 /* draft-ietf-idr-bgp-ext-communities */
240 #define BGP_EXT_COM_RT_0 0x0002 /* Route Target,Format AS(2bytes):AN(4bytes) */
241 #define BGP_EXT_COM_RT_1 0x0102 /* Route Target,Format IP address:AN(2bytes) */
242 #define BGP_EXT_COM_RT_2 0x0202 /* Route Target,Format AS(4bytes):AN(2bytes) */
243 #define BGP_EXT_COM_RO_0 0x0003 /* Route Origin,Format AS(2bytes):AN(4bytes) */
244 #define BGP_EXT_COM_RO_1 0x0103 /* Route Origin,Format IP address:AN(2bytes) */
245 #define BGP_EXT_COM_RO_2 0x0203 /* Route Origin,Format AS(2bytes):AN(4bytes) */
246 #define BGP_EXT_COM_LINKBAND ((BGP_ATTR_FLAG_TRANSITIVE << 8) | 0x0004)
247 /* Link Bandwidth,Format AS(2bytes):
248 * Bandwidth(4bytes) */
249 /* -2 version of the draft */
250 #define BGP_EXT_COM_VPN_ORIGIN 0x0005 /* OSPF Domin ID / VPN of Origin */
251 /* draft-rosen-vpns-ospf-bgp-mpls */
252 #define BGP_EXT_COM_OSPF_RTYPE 0x8000 /* OSPF Route Type,Format Area(4B):RouteType(1B):Options(1B) */
253 #define BGP_EXT_COM_OSPF_RID 0x8001 /* OSPF Router ID,Format RouterID(4B):Unused(2B) */
254 #define BGP_EXT_COM_L2INFO 0x800a /* draft-kompella-ppvpn-l2vpn */
255 #define BGP_EXT_COM_FLOW_RATE 0x8006 /* RFC 5575 flow spec ext com rate limit */
256 #define BGP_EXT_COM_FLOW_ACT 0x8007 /* RFC 5575 flow Spec ext com traffic action */
257 #define BGP_EXT_COM_FLOW_RDIR 0x8008 /* RFC 5575 flow spec ext com redirect action */
258 #define BGP_EXT_COM_FLOW_MARK 0x8009 /* RFC 5575 flow spec ext com mark action */
259 #define BGP_EXT_COM_FLOW_NH 0x0800 /* draft-simpson-redirect-02 */
261 /* extended community option flow flec action bit S and T */
262 #define BGP_EXT_COM_FSPEC_ACT_S 0x02
263 #define BGP_EXT_COM_FSPEC_ACT_T 0x01
265 /* extended community l2vpn flags */
267 #define BGP_EXT_COM_L2_FLAG_D 0x80
268 #define BGP_EXT_COM_L2_FLAG_Z1 0x40
269 #define BGP_EXT_COM_L2_FLAG_F 0x20
270 #define BGP_EXT_COM_L2_FLAG_Z345 0x1c
271 #define BGP_EXT_COM_L2_FLAG_C 0x02
272 #define BGP_EXT_COM_L2_FLAG_S 0x01
274 /* Extended community QoS Marking technology type */
275 #define QOS_TECH_TYPE_DSCP 0x00 /* DiffServ enabled IP (DSCP encoding) */
276 #define QOS_TECH_TYPE_802_1q 0x01 /* Ethernet using 802.1q priority tag */
277 #define QOS_TECH_TYPE_E_LSP 0x02 /* MPLS using E-LSP */
278 #define QOS_TECH_TYPE_VC 0x03 /* Virtual Channel (VC) encoding using separate channels for */
279 /* QoS forwarding / one channel per class (e.g. ATM VCs, FR */
280 /* VCs, MPLS L-LSPs) */
281 #define QOS_TECH_TYPE_GMPLS_TIME 0x04 /* GMPLS - time slot encoding */
282 #define QOS_TECH_TYPE_GMPLS_LAMBDA 0x05 /* GMPLS - lambda encoding */
283 #define QOS_TECH_TYPE_GMPLS_FIBRE 0x06 /* GMPLS - fibre encoding */
285 /* OSPF codes for BGP_EXT_COM_OSPF_RTYPE draft-rosen-vpns-ospf-bgp-mpls */
286 #define BGP_OSPF_RTYPE_RTR 1 /* OSPF Router LSA */
287 #define BGP_OSPF_RTYPE_NET 2 /* OSPF Network LSA */
288 #define BGP_OSPF_RTYPE_SUM 3 /* OSPF Summary LSA */
289 #define BGP_OSPF_RTYPE_EXT 5 /* OSPF External LSA, note that ASBR doesn't apply to MPLS-VPN */
290 #define BGP_OSPF_RTYPE_NSSA 7 /* OSPF NSSA External*/
291 #define BGP_OSPF_RTYPE_SHAM 129 /* OSPF-MPLS-VPN Sham link */
292 #define BGP_OSPF_RTYPE_METRIC_TYPE 0x1 /* LSB of RTYPE Options Field */
294 /* Extended community & Route dinstinguisher formats */
295 #define FORMAT_AS2_LOC 0x00 /* Format AS(2bytes):AN(4bytes) */
296 #define FORMAT_IP_LOC 0x01 /* Format IP address:AN(2bytes) */
297 #define FORMAT_AS4_LOC 0x02 /* Format AS(4bytes):AN(2bytes) */
299 /* RFC 2858 subsequent address family numbers */
300 #define SAFNUM_UNICAST 1
301 #define SAFNUM_MULCAST 2
302 #define SAFNUM_UNIMULC 3
303 #define SAFNUM_MPLS_LABEL 4 /* rfc3107 */
304 #define SAFNUM_MCAST_VPN 5 /* draft-ietf-l3vpn-2547bis-mcast-bgp-08.txt */
305 #define SAFNUM_ENCAPSULATION 7 /* rfc5512 */
306 #define SAFNUM_TUNNEL 64 /* draft-nalawade-kapoor-tunnel-safi-02.txt */
307 #define SAFNUM_VPLS 65
308 #define SAFNUM_MDT 66 /* rfc6037 */
309 #define SAFNUM_LAB_VPNUNICAST 128 /* Draft-rosen-rfc2547bis-03 */
310 #define SAFNUM_LAB_VPNMULCAST 129
311 #define SAFNUM_LAB_VPNUNIMULC 130
312 #define SAFNUM_ROUTE_TARGET 132 /* RFC 4684 Constrained Route Distribution for BGP/MPLS IP VPN */
313 #define SAFNUM_FSPEC_RULE 133 /* RFC 5575 BGP flow spec SAFI */
314 #define SAFNUM_FSPEC_VPN_RULE 134 /* RFC 5575 BGP flow spec SAFI VPN */
317 /* BGP Additional Paths Capability */
318 #define BGP_ADDPATH_RECEIVE 0x01
319 #define BGP_ADDPATH_SEND 0x02
321 /* mcast-vpn route types draft-ietf-l3vpn-2547bis-mcast-bgp-08.txt */
322 #define MCAST_VPN_RTYPE_INTRA_AS_IPMSI_AD 1
323 #define MCAST_VPN_RTYPE_INTER_AS_IPMSI_AD 2
324 #define MCAST_VPN_RTYPE_SPMSI_AD 3
325 #define MCAST_VPN_RTYPE_LEAF_AD 4
326 #define MCAST_VPN_RTYPE_SOURCE_ACTIVE_AD 5
327 #define MCAST_VPN_RTYPE_SHARED_TREE_JOIN 6
328 #define MCAST_VPN_RTYPE_SOURCE_TREE_JOIN 7
330 /* RFC 5512 Tunnel Types */
331 #define TUNNEL_TYPE_L2TP_OVER_IP 1
332 #define TUNNEL_TYPE_GRE 2
333 #define TUNNEL_TYPE_IP_IN_IP 7
335 /* RFC 5512/5640 Sub-TLV Types */
336 #define TUNNEL_SUBTLV_ENCAPSULATION 1
337 #define TUNNEL_SUBTLV_PROTO_TYPE 2
338 #define TUNNEL_SUBTLV_COLOR 4
339 #define TUNNEL_SUBTLV_LOAD_BALANCE 5
342 #define offsetof(type, member) ((size_t)(&((type *)0)->member))
346 static const value_string bgptypevals
[] = {
347 { BGP_OPEN
, "OPEN Message" },
348 { BGP_UPDATE
, "UPDATE Message" },
349 { BGP_NOTIFICATION
, "NOTIFICATION Message" },
350 { BGP_KEEPALIVE
, "KEEPALIVE Message" },
351 { BGP_ROUTE_REFRESH
, "ROUTE-REFRESH Message" },
352 { BGP_CAPABILITY
, "CAPABILITY Message" },
353 { BGP_ROUTE_REFRESH_CISCO
, "Cisco ROUTE-REFRESH Message" },
357 #define BGP_MAJOR_ERROR_MSG_HDR 1
358 #define BGP_MAJOR_ERROR_OPEN_MSG 2
359 #define BGP_MAJOR_ERROR_UPDATE_MSG 3
360 #define BGP_MAJOR_ERROR_HT_EXPIRED 4
361 #define BGP_MAJOR_ERROR_STATE_MACHINE 5
362 #define BGP_MAJOR_ERROR_CEASE 6
363 #define BGP_MAJOR_ERROR_CAP_MSG 7
365 static const value_string bgpnotify_major
[] = {
366 { BGP_MAJOR_ERROR_MSG_HDR
, "Message Header Error" },
367 { BGP_MAJOR_ERROR_OPEN_MSG
, "OPEN Message Error" },
368 { BGP_MAJOR_ERROR_UPDATE_MSG
, "UPDATE Message Error" },
369 { BGP_MAJOR_ERROR_HT_EXPIRED
, "Hold Timer Expired" },
370 { BGP_MAJOR_ERROR_STATE_MACHINE
, "Finite State Machine Error" },
371 { BGP_MAJOR_ERROR_CEASE
, "Cease" },
372 { BGP_MAJOR_ERROR_CAP_MSG
, "CAPABILITY Message Error" },
376 static const value_string bgpnotify_minor_msg_hdr
[] = {
377 { 1, "Connection Not Synchronized" },
378 { 2, "Bad Message Length" },
379 { 3, "Bad Message Type" },
383 static const value_string bgpnotify_minor_open_msg
[] = {
384 { 1, "Unsupported Version Number" },
385 { 2, "Bad Peer AS" },
386 { 3, "Bad BGP Identifier" },
387 { 4, "Unsupported Optional Parameter" },
388 { 5, "Authentication Failure [Deprecated]" },
389 { 6, "Unacceptable Hold Time" },
390 { 7, "Unsupported Capability" },
394 static const value_string bgpnotify_minor_update_msg
[] = {
395 { 1, "Malformed Attribute List" },
396 { 2, "Unrecognized Well-known Attribute" },
397 { 3, "Missing Well-known Attribute" },
398 { 4, "Attribute Flags Error" },
399 { 5, "Attribute Length Error" },
400 { 6, "Invalid ORIGIN Attribute" },
401 { 7, "AS Routing Loop [Deprecated]" },
402 { 8, "Invalid NEXT_HOP Attribute" },
403 { 9, "Optional Attribute Error" },
404 { 10, "Invalid Network Field" },
405 { 11, "Malformed AS_PATH" },
408 /* RFC6608 Subcodes for BGP Finite State Machine Error */
409 static const value_string bgpnotify_minor_state_machine
[] = {
410 { 1, "Receive Unexpected Message in OpenSent State" },
411 { 2, "Receive Unexpected Message in OpenConfirm State" },
412 { 3, "Receive Unexpected Message in Established State" },
416 /* RFC4486 Subcodes for BGP Cease Notification Message */
417 static const value_string bgpnotify_minor_cease
[] = {
418 { 1, "Maximum Number of Prefixes Reached"},
419 { 2, "Administratively Shutdown"},
420 { 3, "Peer De-configured"},
421 { 4, "Administratively Reset"},
422 { 5, "Connection Rejected"},
423 { 6, "Other Configuration Change"},
424 { 7, "Connection Collision Resolution"},
425 { 8, "Out of Resources"},
429 static const value_string bgpnotify_minor_cap_msg
[] = {
430 { 1, "Invalid Action Value" },
431 { 2, "Invalid Capability Length" },
432 { 3, "Malformed Capability Value" },
433 { 4, "Unsupported Capability Code" },
437 static const value_string bgpattr_origin
[] = {
444 static const value_string bgp_open_opt_vals
[] = {
445 { BGP_OPTION_AUTHENTICATION
, "Authentication" },
446 { BGP_OPTION_CAPABILITY
, "Capability" },
450 static const value_string as_segment_type
[] = {
452 { 2, "AS_SEQUENCE" },
453 /* RFC1965 has the wrong values, corrected in */
454 /* draft-ietf-idr-bgp-confed-rfc1965bis-01.txt */
455 { 4, "AS_CONFED_SET" },
456 { 3, "AS_CONFED_SEQUENCE" },
460 static const value_string bgpattr_type
[] = {
461 { BGPTYPE_ORIGIN
, "ORIGIN" },
462 { BGPTYPE_AS_PATH
, "AS_PATH" },
463 { BGPTYPE_NEXT_HOP
, "NEXT_HOP" },
464 { BGPTYPE_MULTI_EXIT_DISC
, "MULTI_EXIT_DISC" },
465 { BGPTYPE_LOCAL_PREF
, "LOCAL_PREF" },
466 { BGPTYPE_ATOMIC_AGGREGATE
, "ATOMIC_AGGREGATE" },
467 { BGPTYPE_AGGREGATOR
, "AGGREGATOR" },
468 { BGPTYPE_COMMUNITIES
, "COMMUNITIES" },
469 { BGPTYPE_ORIGINATOR_ID
, "ORIGINATOR_ID" },
470 { BGPTYPE_CLUSTER_LIST
, "CLUSTER_LIST" },
471 { BGPTYPE_MP_REACH_NLRI
, "MP_REACH_NLRI" },
472 { BGPTYPE_MP_UNREACH_NLRI
, "MP_UNREACH_NLRI" },
473 { BGPTYPE_EXTENDED_COMMUNITY
, "EXTENDED_COMMUNITIES" },
474 { BGPTYPE_NEW_AS_PATH
, "NEW_AS_PATH" },
475 { BGPTYPE_NEW_AGGREGATOR
, "NEW_AGGREGATOR" },
476 { BGPTYPE_SAFI_SPECIFIC_ATTR
, "SAFI_SPECIFIC_ATTRIBUTE" },
477 { BGPTYPE_TUNNEL_ENCAPS_ATTR
, "TUNNEL_ENCAPSULATION_ATTRIBUTE" },
481 static const value_string tunnel_type
[] = {
482 { TUNNEL_TYPE_L2TP_OVER_IP
, "L2TP_OVER_IP" },
483 { TUNNEL_TYPE_GRE
, "GRE" },
484 { TUNNEL_TYPE_IP_IN_IP
, "IP_IN_IP" },
488 static const value_string subtlv_type
[] = {
489 { TUNNEL_SUBTLV_ENCAPSULATION
, "ENCAPSULATION" },
490 { TUNNEL_SUBTLV_PROTO_TYPE
, "PROTOCOL_TYPE" },
491 { TUNNEL_SUBTLV_COLOR
, "COLOR" },
492 { TUNNEL_SUBTLV_LOAD_BALANCE
, "LOAD_BALANCE" },
496 static const value_string bgpext_com8_type
[] = {
497 { BGP_EXT_COM_QOS_MARK_T
, "QoS Marking - transitive" },
498 { BGP_EXT_COM_QOS_MARK_NT
, "QoS Marking - non-transitive" },
499 { BGP_EXT_COM_COS_CAP_T
, "CoS Capability - transitive" },
503 static const value_string bgpext_com_type
[] = {
504 { BGP_EXT_COM_RT_0
, "two-octet AS specific Route Target" },
505 { BGP_EXT_COM_RT_1
, "IPv4 address specific Route Target" },
506 { BGP_EXT_COM_RT_2
, "four-octet AS specific Route Target" },
507 { BGP_EXT_COM_RO_0
, "two-octet AS specific Route Origin" },
508 { BGP_EXT_COM_RO_1
, "IPv4 address specific Route Origin" },
509 { BGP_EXT_COM_RO_2
, "four-octet AS specific Route Origin" },
510 { BGP_EXT_COM_LINKBAND
, "Link Bandwidth" },
511 { BGP_EXT_COM_VPN_ORIGIN
, "OSPF Domain" },
512 { BGP_EXT_COM_OSPF_RTYPE
, "OSPF Route Type" },
513 { BGP_EXT_COM_OSPF_RID
, "OSPF Router ID" },
514 { BGP_EXT_COM_L2INFO
, "Layer 2 Information" },
515 { BGP_EXT_COM_FLOW_ACT
, "Flow spec traffic action" },
516 { BGP_EXT_COM_FLOW_MARK
, "FLow spec traffic marling" },
517 { BGP_EXT_COM_FLOW_RATE
, "Flow spec traffic rate" },
518 { BGP_EXT_COM_FLOW_RDIR
, "Flow spec traffic redirect" },
522 static const value_string flow_spec_op_len_val
[] = {
523 { 0, "1 byte: 1 <<" },
524 { 1, "2 bytes: 1 <<" },
525 { 2, "4 bytes: 1 <<" },
526 { 3, "8 bytes: 1 <<" },
530 static const value_string qos_tech_type
[] = {
531 { QOS_TECH_TYPE_DSCP
, "DiffServ enabled IP (DSCP encoding)" },
532 { QOS_TECH_TYPE_802_1q
, "Ethernet using 802.1q priority tag" },
533 { QOS_TECH_TYPE_E_LSP
, "MPLS using E-LSP" },
534 { QOS_TECH_TYPE_VC
, "Virtual Channel (VC) encoding" },
535 { QOS_TECH_TYPE_GMPLS_TIME
, "GMPLS - time slot encoding" },
536 { QOS_TECH_TYPE_GMPLS_LAMBDA
, "GMPLS - lambda encoding" },
537 { QOS_TECH_TYPE_GMPLS_FIBRE
, "GMPLS - fibre encoding" },
541 static const value_string bgp_ssa_type
[] = {
542 { BGP_SSA_L2TPv3
, "L2TPv3 Tunnel" },
543 { BGP_SSA_mGRE
, "mGRE Tunnel" },
544 { BGP_SSA_IPSec
, "IPSec Tunnel" },
545 { BGP_SSA_MPLS
, "MPLS Tunnel" },
546 { BGP_SSA_L2TPv3_IN_IPSec
, "L2TPv3 in IPSec Tunnel" },
547 { BGP_SSA_mGRE_IN_IPSec
, "mGRE in IPSec Tunnel" },
551 static const value_string bgp_l2vpn_encaps
[] = {
554 { 2, "ATM AAL5 SDU VCC transport"},
555 { 3, "ATM transparent cell transport"},
556 { 4, "Ethernet (VLAN) Tagged mode"},
557 { 5, "Ethernet raw mode"},
560 { 8, "SONET/SDH CES"},
561 { 9, "ATM n-to-one VCC cell transport"},
562 { 10, "ATM n-to-one VPC cell transport"},
563 { 11, "IP layer 2 transport"},
564 { 15, "Frame relay port mode"},
565 { 17, "Structure agnostic E1 over packet"},
566 { 18, "Structure agnostic T1 over packet"},
568 { 20, "Structure agnostic T3 over packet"},
569 { 21, "Nx64kbit/s Basic Service using Structure-aware"},
570 { 25, "Frame Relay DLCI"},
571 { 40, "Structure agnostic E3 over packet"},
572 { 41, "Octet-aligned playload for structure-agnostic DS1 circuits"},
573 { 42, "E1 Nx64kbit/s with CAS using Structure-aware"},
574 { 43, "DS1 (ESF) Nx64kbit/s with CAS using Structure-aware"},
575 { 44, "DS1 (SF) Nx64kbit/s with CAS using Structure-aware"},
576 { 64, "IP-interworking"},
580 static const value_string bgpext_ospf_rtype
[] = {
581 { BGP_OSPF_RTYPE_RTR
, "Router" },
582 { BGP_OSPF_RTYPE_NET
, "Network" },
583 { BGP_OSPF_RTYPE_SUM
, "Summary" },
584 { BGP_OSPF_RTYPE_EXT
, "External" },
585 { BGP_OSPF_RTYPE_NSSA
,"NSSA External" },
586 { BGP_OSPF_RTYPE_SHAM
,"MPLS-VPN Sham" },
590 /* Subsequent address family identifier, RFC2858 */
591 static const value_string bgpattr_nlri_safi
[] = {
593 { SAFNUM_UNICAST
, "Unicast" },
594 { SAFNUM_MULCAST
, "Multicast" },
595 { SAFNUM_UNIMULC
, "Unicast+Multicast" },
596 { SAFNUM_MPLS_LABEL
, "Labeled Unicast"},
597 { SAFNUM_MCAST_VPN
, "MCAST-VPN"},
598 { SAFNUM_ENCAPSULATION
, "Encapsulation"},
599 { SAFNUM_TUNNEL
, "Tunnel"},
600 { SAFNUM_VPLS
, "VPLS"},
601 { SAFNUM_LAB_VPNUNICAST
, "Labeled VPN Unicast" }, /* draft-rosen-rfc2547bis-03 */
602 { SAFNUM_LAB_VPNMULCAST
, "Labeled VPN Multicast" },
603 { SAFNUM_LAB_VPNUNIMULC
, "Labeled VPN Unicast+Multicast" },
604 { SAFNUM_ROUTE_TARGET
, "Route Target Filter" },
605 { SAFNUM_FSPEC_RULE
, "Flow Spec Filter" },
606 { SAFNUM_FSPEC_VPN_RULE
, "Flow Spec Filter VPN" },
610 /* ORF Type, draft-ietf-idr-route-filter-04.txt */
611 static const value_string orf_type_vals
[] = {
612 { 2, "Communities ORF-Type" },
613 { 3, "Extended Communities ORF-Type" },
614 { 128, "Cisco PrefixList ORF-Type" },
615 { 129, "Cisco CommunityList ORF-Type" },
616 { 130, "Cisco Extended CommunityList ORF-Type" },
617 { 131, "Cisco AsPathList ORF-Type" },
621 /* ORF Send/Receive, draft-ietf-idr-route-filter-04.txt */
622 static const value_string orf_send_recv_vals
[] = {
629 /* ORF Send/Receive, draft-ietf-idr-route-filter-04.txt */
630 static const value_string orf_when_vals
[] = {
636 static const value_string orf_entry_action_vals
[] = {
637 { BGP_ORF_ADD
, "Add" },
638 { BGP_ORF_REMOVE
, "Remove" },
639 { BGP_ORF_REMOVEALL
, "RemoveAll" },
643 static const value_string orf_entry_match_vals
[] = {
644 { BGP_ORF_PERMIT
, "Permit" },
645 { BGP_ORF_DENY
, "Deny" },
649 static const value_string capability_vals
[] = {
650 { BGP_CAPABILITY_RESERVED
, "Reserved capability" },
651 { BGP_CAPABILITY_MULTIPROTOCOL
, "Multiprotocol extensions capability" },
652 { BGP_CAPABILITY_ROUTE_REFRESH
, "Route refresh capability" },
653 { BGP_CAPABILITY_COOPERATIVE_ROUTE_FILTERING
, "Cooperative route filtering capability" },
654 { BGP_CAPABILITY_GRACEFUL_RESTART
, "Graceful Restart capability" },
655 { BGP_CAPABILITY_4_OCTET_AS_NUMBER
, "Support for 4-octet AS number capability" },
656 { BGP_CAPABILITY_DYNAMIC_CAPABILITY
, "Support for Dynamic capability" },
657 { BGP_CAPABILITY_ADDITIONAL_PATHS
, "Support for Additional Paths" },
658 { BGP_CAPABILITY_ROUTE_REFRESH_CISCO
, "Route refresh capability" },
659 { BGP_CAPABILITY_ORF_CISCO
, "Cooperative route filtering capability" },
660 { BGP_CAPABILITY_ENHANCED_ROUTE_REFRESH
, "Enhanced route refresh capability" },
664 /* Capability Message action code */
665 static const value_string bgpcap_action
[] = {
666 { 0, "advertising a capability" },
667 { 1, "removing a capability" },
671 static const value_string mcast_vpn_route_type
[] = {
672 { MCAST_VPN_RTYPE_INTRA_AS_IPMSI_AD
, "Intra-AS I-PMSI A-D route" },
673 { MCAST_VPN_RTYPE_INTER_AS_IPMSI_AD
, "Inter-AS I-PMSI A-D route" },
674 { MCAST_VPN_RTYPE_SPMSI_AD
, "S-PMSI A-D route" },
675 { MCAST_VPN_RTYPE_LEAF_AD
, "Leaf A-D route" },
676 { MCAST_VPN_RTYPE_SOURCE_ACTIVE_AD
, "Source Active A-D route" },
677 { MCAST_VPN_RTYPE_SHARED_TREE_JOIN
, "Shared Tree Join route" },
678 { MCAST_VPN_RTYPE_SOURCE_TREE_JOIN
, "Source Tree Join route" },
682 /* NLRI type value_string as define in BGP flow spec RFC */
684 static const value_string flowspec_nlri_opvaluepair_type
[] = {
685 { BGPNLRI_FSPEC_DST_PFIX
, "Destination prefix filter" },
686 { BGPNLRI_FSPEC_SRC_PFIX
, "Source prefix filter" },
687 { BGPNLRI_FSPEC_IP_PROTO
, "IP protocol filter" },
688 { BGPNLRI_FSPEC_PORT
, "Port filter" },
689 { BGPNLRI_FSPEC_DST_PORT
, "Destination port filter" },
690 { BGPNLRI_FSPEC_SRC_PORT
, "Source port filter" },
691 { BGPNLRI_FSPEC_ICMP_TP
, "ICMP type filter" },
692 { BGPNLRI_FSPEC_ICMP_CD
, "ICMP code filter" },
693 { BGPNLRI_FSPEC_TCP_FLAGS
,"TCP flags filter" },
694 { BGPNLRI_FSPEC_PCK_LEN
, "Packet Length filter" },
695 { BGPNLRI_FSPEC_DSCP
, "DSCP marking filter" },
696 { BGPNLRI_FSPEC_FRAGMENT
, "IP fragment filter" },
699 #define BGPNLRI_FSPEC_FRAGMENT 12 /* RFC 5575 */
702 /* Subtype Route Refresh, draft-ietf-idr-bgp-enhanced-route-refresh-02 */
703 static const value_string route_refresh_subtype_vals
[] = {
704 { 0, "Normal route refresh request [RFC2918] with/without ORF [RFC5291]" },
705 { 1, "Demarcation of the beginning of a route refresh" },
706 { 2, "Demarcation of the ending of a route refresh" },
710 static const true_false_string tfs_optional_wellknown
= { "Optional", "Well-known" };
711 static const true_false_string tfs_transitive_non_transitive
= { "Transitive", "Non-transitive" };
712 static const true_false_string tfs_partial_complete
= { "Partial", "Complete" };
713 static const true_false_string tfs_extended_regular_length
= { "Extended length", "Regular length" };
715 /* Maximal size of an IP address string */
716 #define MAX_SIZE_OF_IP_ADDR_STRING 16
718 static int proto_bgp
= -1;
720 /* BGP header field initialisation */
722 /* global BGP header filed */
724 static int hf_bgp_marker
= -1;
725 static int hf_bgp_length
= -1;
726 static int hf_bgp_type
= -1;
728 /* BGP open message header filed */
730 static int hf_bgp_open_version
= -1;
731 static int hf_bgp_open_myas
= -1;
732 static int hf_bgp_open_holdtime
= -1;
733 static int hf_bgp_open_identifier
= -1;
734 static int hf_bgp_open_opt_len
= -1;
735 static int hf_bgp_open_opt_params
= -1;
736 static int hf_bgp_open_opt_param
= -1;
737 static int hf_bgp_open_opt_param_type
= -1;
738 static int hf_bgp_open_opt_param_len
= -1;
739 static int hf_bgp_open_opt_param_auth
= -1;
740 static int hf_bgp_open_opt_param_unknown
= -1;
742 /* BGP notify header field */
744 static int hf_bgp_notify_major_error
= -1;
745 static int hf_bgp_notify_minor_msg_hdr
= -1;
746 static int hf_bgp_notify_minor_open_msg
= -1;
747 static int hf_bgp_notify_minor_update_msg
= -1;
748 static int hf_bgp_notify_minor_ht_expired
= -1;
749 static int hf_bgp_notify_minor_state_machine
= -1;
750 static int hf_bgp_notify_minor_cease
= -1;
751 static int hf_bgp_notify_minor_cap_msg
= -1;
752 static int hf_bgp_notify_minor_unknown
= -1;
753 static int hf_bgp_notify_data
= -1;
755 /* BGP route refresh header field */
757 static int hf_bgp_route_refresh_afi
= -1;
758 static int hf_bgp_route_refresh_subtype
= -1;
759 static int hf_bgp_route_refresh_safi
= -1;
760 static int hf_bgp_route_refresh_orf
= -1;
761 static int hf_bgp_route_refresh_orf_flag
= -1;
762 static int hf_bgp_route_refresh_orf_type
= -1;
763 static int hf_bgp_route_refresh_orf_length
= -1;
764 static int hf_bgp_route_refresh_orf_entry_prefixlist
= -1;
765 static int hf_bgp_route_refresh_orf_entry_action
= -1;
766 static int hf_bgp_route_refresh_orf_entry_match
= -1;
767 static int hf_bgp_route_refresh_orf_entry_sequence
= -1;
768 static int hf_bgp_route_refresh_orf_entry_prefixmask_lower
= -1;
769 static int hf_bgp_route_refresh_orf_entry_prefixmask_upper
= -1;
771 /* BGP capabilities header field */
773 static int hf_bgp_cap
= -1;
774 static int hf_bgp_cap_type
= -1;
775 static int hf_bgp_cap_length
= -1;
776 static int hf_bgp_cap_action
= -1;
777 static int hf_bgp_cap_unknown
= -1;
778 static int hf_bgp_cap_reserved
= -1;
779 static int hf_bgp_cap_mp_afi
= -1;
780 static int hf_bgp_cap_mp_safi
= -1;
781 static int hf_bgp_cap_gr_timers
= -1;
782 static int hf_bgp_cap_gr_timers_restart_flag
= -1;
783 static int hf_bgp_cap_gr_timers_restart_time
= -1;
784 static int hf_bgp_cap_gr_afi
= -1;
785 static int hf_bgp_cap_gr_safi
= -1;
786 static int hf_bgp_cap_gr_flag
= -1;
787 static int hf_bgp_cap_gr_flag_pfs
= -1;
788 static int hf_bgp_cap_4as
= -1;
789 static int hf_bgp_cap_dc
= -1;
790 static int hf_bgp_cap_ap_afi
= -1;
791 static int hf_bgp_cap_ap_safi
= -1;
792 static int hf_bgp_cap_ap_sendreceive
= -1;
793 static int hf_bgp_cap_orf_afi
= -1;
794 static int hf_bgp_cap_orf_safi
= -1;
795 static int hf_bgp_cap_orf_number
= -1;
796 static int hf_bgp_cap_orf_type
= -1;
797 static int hf_bgp_cap_orf_sendreceive
= -1;
799 /* BGP update global header field */
800 static int hf_bgp_update_withdrawn_routes_length
= -1;
801 static int hf_bgp_update_withdrawn_routes
= -1;
803 static int hf_bgp_update_community_as
= -1;
806 /* BGP update path attribute header field */
807 static int hf_bgp_update_total_path_attribute_length
= -1;
808 static int hf_bgp_update_path_attributes
= -1;
810 static int hf_bgp_update_path_attribute
= -1;
811 static int hf_bgp_update_path_attribute_flags
= -1;
812 static int hf_bgp_update_path_attribute_flags_optional
= -1;
813 static int hf_bgp_update_path_attribute_flags_transitive
= -1;
814 static int hf_bgp_update_path_attribute_flags_partial
= -1;
815 static int hf_bgp_update_path_attribute_flags_extended_length
= -1;
816 static int hf_bgp_update_path_attribute_type_code
= -1;
817 static int hf_bgp_update_path_attribute_length
= -1;
818 static int hf_bgp_update_path_attribute_next_hop
= -1;
819 static int hf_bgp_update_path_attribute_as_path
= -1;
820 static int hf_bgp_update_path_attribute_community_value
= -1;
821 static int hf_bgp_update_path_attribute_origin
= -1;
822 static int hf_bgp_update_path_attribute_cluster_list
= -1;
823 static int hf_bgp_update_path_attribute_originator_id
= -1;
824 static int hf_bgp_update_path_attribute_local_pref
= -1;
825 static int hf_bgp_update_path_attribute_multi_exit_disc
= -1;
826 static int hf_bgp_update_path_attribute_aggregator_as
= -1;
827 static int hf_bgp_update_path_attribute_aggregator_origin
= -1;
829 /* BGP update tunnel encaps attribute RFC 5512 */
831 static int hf_bgp_update_encaps_tunnel_tlv_len
= -1;
832 static int hf_bgp_update_encaps_tunnel_tlv_type
= -1;
833 static int hf_bgp_update_encaps_tunnel_subtlv_len
= -1;
834 static int hf_bgp_update_encaps_tunnel_subtlv_type
= -1;
837 /* BGP update path attribute SSA SAFI Specific attribute (deprecated should we keep it ?) */
839 static int hf_bgp_ssa_t
= -1;
840 static int hf_bgp_ssa_type
= -1;
841 static int hf_bgp_ssa_len
= -1;
842 static int hf_bgp_ssa_value
= -1;
843 static int hf_bgp_ssa_l2tpv3_pref
= -1;
844 static int hf_bgp_ssa_l2tpv3_s
= -1;
845 static int hf_bgp_ssa_l2tpv3_unused
= -1;
846 static int hf_bgp_ssa_l2tpv3_cookie_len
= -1;
847 static int hf_bgp_ssa_l2tpv3_session_id
= -1;
848 static int hf_bgp_ssa_l2tpv3_cookie
= -1;
850 /* BGP NLRI head field */
851 static int hf_bgp_update_nlri
= -1;
853 static int hf_bgp_mp_reach_nlri_ipv4_prefix
= -1;
854 static int hf_bgp_mp_unreach_nlri_ipv4_prefix
= -1;
855 static int hf_bgp_mp_nlri_tnl_id
= -1;
856 static int hf_bgp_withdrawn_prefix
= -1;
857 static int hf_bgp_nlri_prefix
= -1;
858 static int hf_bgp_nlri_path_id
= -1;
860 /* BGP mcast IP VPN nlri header field */
862 static int hf_bgp_mcast_vpn_nlri_t
= -1;
863 static int hf_bgp_mcast_vpn_nlri_route_type
= -1;
864 static int hf_bgp_mcast_vpn_nlri_length
= -1;
865 static int hf_bgp_mcast_vpn_nlri_rd
= -1;
866 static int hf_bgp_mcast_vpn_nlri_origin_router_ipv4
= -1;
867 static int hf_bgp_mcast_vpn_nlri_origin_router_ipv6
= -1;
868 static int hf_bgp_mcast_vpn_nlri_source_as
= -1;
869 static int hf_bgp_mcast_vpn_nlri_source_length
= -1;
870 static int hf_bgp_mcast_vpn_nlri_group_length
= -1;
871 static int hf_bgp_mcast_vpn_nlri_source_addr_ipv4
= -1;
872 static int hf_bgp_mcast_vpn_nlri_source_addr_ipv6
= -1;
873 static int hf_bgp_mcast_vpn_nlri_group_addr_ipv4
= -1;
874 static int hf_bgp_mcast_vpn_nlri_group_addr_ipv6
= -1;
875 static int hf_bgp_mcast_vpn_nlri_route_key
= -1;
877 /* BGP flow spec nlri header field */
879 static int hf_bgp_flowspec_nlri_t
= -1;
880 static int hf_bgp_flowspec_nlri_filter
= -1;
881 static int hf_bgp_flowspec_nlri_filter_type
= -1;
882 static int hf_bgp_flowspec_nlri_length
= -1;
883 static int hf_bgp_flowspec_nlri_dst_pref_ipv4
= -1;
884 static int hf_bgp_flowspec_nlri_src_pref_ipv4
= -1;
885 static int hf_bgp_flowspec_nlri_op_flags
= -1;
886 static int hf_bgp_flowspec_nlri_op_eol
= -1;
887 static int hf_bgp_flowspec_nlri_op_and
= -1;
888 static int hf_bgp_flowspec_nlri_op_val_len
= -1;
889 static int hf_bgp_flowspec_nlri_op_un_bit4
= -1;
890 static int hf_bgp_flowspec_nlri_op_un_bit5
= -1;
891 static int hf_bgp_flowspec_nlri_op_lt
= -1;
892 static int hf_bgp_flowspec_nlri_op_gt
= -1;
893 static int hf_bgp_flowspec_nlri_op_eq
= -1;
894 static int hf_bgp_flowspec_nlri_dec_val_8
= -1;
895 static int hf_bgp_flowspec_nlri_dec_val_16
= -1;
896 static int hf_bgp_flowspec_nlri_dec_val_32
= -1;
897 static int hf_bgp_flowspec_nlri_dec_val_64
= -1;
898 static int hf_bgp_flowspec_nlri_op_flg_not
= -1;
899 static int hf_bgp_flowspec_nlri_op_flg_match
= -1;
900 static int hf_bgp_flowspec_nlri_tcp_flags
= -1;
901 static int hf_bgp_flowspec_nlri_tcp_flags_cwr
= -1;
902 static int hf_bgp_flowspec_nlri_tcp_flags_ecn
= -1;
903 static int hf_bgp_flowspec_nlri_tcp_flags_urg
= -1;
904 static int hf_bgp_flowspec_nlri_tcp_flags_ack
= -1;
905 static int hf_bgp_flowspec_nlri_tcp_flags_push
= -1;
906 static int hf_bgp_flowspec_nlri_tcp_flags_reset
= -1;
907 static int hf_bgp_flowspec_nlri_tcp_flags_syn
= -1;
908 static int hf_bgp_flowspec_nlri_tcp_flags_fin
= -1;
909 static int hf_bgp_flowspec_nlri_fflag
= -1;
910 static int hf_bgp_flowspec_nlri_fflag_lf
= -1;
911 static int hf_bgp_flowspec_nlri_fflag_ff
= -1;
912 static int hf_bgp_flowspec_nlri_fflag_isf
= -1;
913 static int hf_bgp_flowspec_nlri_fflag_df
= -1;
914 static int hf_bgp_flowspec_nlri_dscp
= -1;
916 /* BGP update safi ndt nlri draft-nalawade-idr-mdt-safi-03 */
918 static int hf_bgp_mdt_nlri_safi_rd
= -1;
919 static int hf_bgp_mdt_nlri_safi_ipv4_addr
= -1;
920 static int hf_bgp_mdt_nlri_safi_group_addr
= -1;
922 /* BGP update extended community header field */
924 /* BGP QoS propagation draft-knoll-idr-qos-attribute */
926 static int hf_bgp_ext_com_qos_flags
= -1;
927 static int hf_bgp_ext_com_qos_flags_remarking
= -1;
928 static int hf_bgp_ext_com_qos_flags_ignore_remarking
= -1;
929 static int hf_bgp_ext_com_qos_flags_agg_marking
= -1;
930 static int hf_bgp_ext_com_cos_flags
= -1;
931 static int hf_bgp_ext_com_cos_flags_be
= -1;
932 static int hf_bgp_ext_com_cos_flags_ef
= -1;
933 static int hf_bgp_ext_com_cos_flags_af
= -1;
934 static int hf_bgp_ext_com_cos_flags_le
= -1;
935 static int hf_bgp_ext_com_qos_set_number
= -1;
936 static int hf_bgp_ext_com_qos_tech_type
= -1;
937 static int hf_bgp_ext_com_qos_marking_o
= -1;
938 static int hf_bgp_ext_com_qos_marking_a
= -1;
939 static int hf_bgp_ext_com_qos_default_to_zero
= -1;
941 /* BGP Flow spec extended community RFC 5575 */
943 static int hf_bgp_ext_com_flow_rate_float
= -1;
944 static int hf_bgp_ext_com_flow_act_allset
= -1;
945 static int hf_bgp_ext_com_flow_act_term_act
= -1;
946 static int hf_bgp_ext_com_flow_act_samp_act
= -1;
947 static int hf_bgp_ext_com_flow_redir_as
= -1;
948 static int hf_bgp_ext_com_flow_redir_an
= -1;
949 static int hf_bgp_ext_com_flow_redir
= -1;
951 /* BGP L2 extended community RFC 4761, RFC 6624 */
952 /* draft-ietf-l2vpn-vpls-multihoming */
954 static int hf_bgp_ext_com_l2_encaps
= -1;
955 static int hf_bgp_ext_com_l2_c_flags
= -1;
956 static int hf_bgp_ext_com_l2_mtu
= -1;
957 static int hf_bgp_ext_com_l2_flag_d
= -1;
958 static int hf_bgp_ext_com_l2_flag_z1
= -1;
959 static int hf_bgp_ext_com_l2_flag_f
= -1;
960 static int hf_bgp_ext_com_l2_flag_z345
= -1;
961 static int hf_bgp_ext_com_l2_flag_c
= -1;
962 static int hf_bgp_ext_com_l2_flag_s
= -1;
964 static gint ett_bgp
= -1;
965 static gint ett_bgp_prefix
= -1;
966 static gint ett_bgp_unfeas
= -1;
967 static gint ett_bgp_attrs
= -1;
968 static gint ett_bgp_attr
= -1;
969 static gint ett_bgp_attr_flags
= -1;
970 static gint ett_bgp_mp_nhna
= -1;
971 static gint ett_bgp_mp_reach_nlri
= -1;
972 static gint ett_bgp_mp_unreach_nlri
= -1;
973 static gint ett_bgp_mp_snpa
= -1;
974 static gint ett_bgp_nlri
= -1;
975 static gint ett_bgp_open
= -1;
976 static gint ett_bgp_update
= -1;
977 static gint ett_bgp_notification
= -1;
978 static gint ett_bgp_route_refresh
= -1; /* ROUTE-REFRESH message tree */
979 static gint ett_bgp_capability
= -1;
980 static gint ett_bgp_as_paths
= -1;
981 static gint ett_bgp_as_path_segments
= -1;
982 static gint ett_bgp_communities
= -1;
983 static gint ett_bgp_cluster_list
= -1; /* cluster list tree */
984 static gint ett_bgp_options
= -1; /* optional parameters tree */
985 static gint ett_bgp_option
= -1; /* an optional parameter tree */
986 static gint ett_bgp_cap
= -1; /* an cap parameter tree */
987 static gint ett_bgp_extended_communities
= -1; /* extended communities list tree */
988 static gint ett_bgp_extended_com_fspec_redir
= -1; /* extended communities BGP flow act redirect */
989 static gint ett_bgp_ext_com_flags
= -1; /* extended communities flags tree */
990 static gint ett_bgp_ext_com_l2_flags
= -1; /* extended commuties tree for l2 services flags */
991 static gint ett_bgp_ssa
= -1; /* safi specific attribute */
992 static gint ett_bgp_ssa_subtree
= -1; /* safi specific attribute Subtrees */
993 static gint ett_bgp_orf
= -1; /* orf (outbound route filter) tree */
994 static gint ett_bgp_orf_entry
= -1; /* orf entry tree */
995 static gint ett_bgp_mcast_vpn_nlri
= -1;
996 static gint ett_bgp_flow_spec_nlri
= -1;
997 static gint ett_bgp_flow_spec_nlri_filter
= -1; /* tree decoding multiple op and value pairs */
998 static gint ett_bgp_flow_spec_nlri_op_flags
= -1; /* tree decoding each op and val pair within the op and value set */
999 static gint ett_bgp_flow_spec_nlri_tcp
= -1;
1000 static gint ett_bgp_flow_spec_nlri_ff
= -1;
1001 static gint ett_bgp_tunnel_tlv
= -1;
1002 static gint ett_bgp_tunnel_tlv_subtree
= -1;
1003 static gint ett_bgp_tunnel_subtlv
= -1;
1004 static gint ett_bgp_tunnel_subtlv_subtree
= -1;
1006 static expert_field ei_bgp_cap_len_bad
= EI_INIT
;
1007 static expert_field ei_bgp_cap_gr_helper_mode_only
= EI_INIT
;
1008 static expert_field ei_bgp_notify_minor_unknown
= EI_INIT
;
1009 static expert_field ei_bgp_route_refresh_orf_type_unknown
= EI_INIT
;
1010 static expert_field ei_bgp_length_invalid
= EI_INIT
;
1011 static expert_field ei_bgp_afi_type_not_supported
= EI_INIT
;
1013 /* desegmentation */
1014 static gboolean bgp_desegment
= TRUE
;
1016 static gint bgp_asn_len
= 0;
1019 * Detect IPv4 prefixes conform to BGP Additional Path but NOT conform to standard BGP
1021 * A real BGP speaker would rely on the BGP Additional Path in the BGP Open messages.
1022 * But it is not suitable for a packet analyse because the BGP sessions are not supposed to
1023 * restart very often, and Open messages from both sides of the session would be needed
1024 * to determine the result of the capability negociation.
1025 * Code inspired from the decode_prefix4 function
1028 detect_add_path_prefix4(tvbuff_t
*tvb
, gint offset
, gint end
) {
1032 /* Must be compatible with BGP Additional Path */
1033 for (o
= offset
+ 4; o
< end
; o
+= 4) {
1034 prefix_len
= tvb_get_guint8(tvb
, o
);
1035 if( prefix_len
> 32) {
1036 return 0; /* invalid prefix length - not BGP add-path */
1038 addr_len
= (prefix_len
+ 7) / 8;
1041 return 0; /* invalid offset - not BGP add-path */
1043 if (prefix_len
% 8) {
1044 /* detect bits set after the end of the prefix */
1045 if( tvb_get_guint8(tvb
, o
- 1 ) & (0xFF >> (prefix_len
% 8)) ) {
1046 return 0; /* invalid prefix content - not BGP add-path */
1050 /* Must NOT be compatible with standard BGP */
1051 for (o
= offset
; o
< end
; ) {
1052 prefix_len
= tvb_get_guint8(tvb
, o
);
1053 if( prefix_len
> 32) {
1054 return 1; /* invalid prefix length - may be BGP add-path */
1056 addr_len
= (prefix_len
+ 7) / 8;
1059 return 1; /* invalid offset - may be BGP add-path */
1061 if (prefix_len
% 8) {
1062 /* detect bits set after the end of the prefix */
1063 if( tvb_get_guint8(tvb
, o
- 1 ) & (0xFF >> (prefix_len
% 8)) ) {
1064 return 1; /* invalid prefix content - may be BGP add-path (or a bug) */
1068 return 0; /* valid - do not assume Additional Path */
1071 * Decode an IPv4 prefix with Path Identifier
1072 * Code inspired from the decode_prefix4 function
1075 decode_path_prefix4(proto_tree
*tree
, int hf_path_id
, int hf_addr
, tvbuff_t
*tvb
, gint offset
,
1079 proto_tree
*prefix_tree
;
1081 guint8 addr_bytes
[4];
1083 } ip_addr
; /* IP address */
1084 guint8 plen
; /* prefix length */
1085 int length
; /* number of octets needed for prefix */
1086 guint32 path_identifier
;
1087 /* snarf path identifier length and prefix */
1088 path_identifier
= tvb_get_ntohl(tvb
, offset
);
1089 plen
= tvb_get_guint8(tvb
, offset
+ 4);
1090 length
= ipv4_addr_and_mask(tvb
, offset
+ 4 + 1, ip_addr
.addr_bytes
, plen
);
1092 proto_tree_add_text(tree
, tvb
, offset
+ 4 , 1, "%s length %u invalid (> 32)",
1096 /* put prefix into protocol tree */
1097 ti
= proto_tree_add_text(tree
, tvb
, offset
,
1098 4 + 1 + length
, "%s/%u PathId %u ",
1099 ip_to_str(ip_addr
.addr_bytes
), plen
, path_identifier
);
1100 prefix_tree
= proto_item_add_subtree(ti
, ett_bgp_prefix
);
1101 if (hf_path_id
!= -1) {
1102 proto_tree_add_uint(prefix_tree
, hf_path_id
, tvb
, offset
, 4,
1105 proto_tree_add_text(prefix_tree
, tvb
, offset
, 4,
1106 "%s Path Id: %u", tag
, path_identifier
);
1108 proto_tree_add_text(prefix_tree
, tvb
, offset
+ 4, 1, "%s prefix length: %u",
1110 if (hf_addr
!= -1) {
1111 proto_tree_add_ipv4(prefix_tree
, hf_addr
, tvb
, offset
+ 4 + 1, length
,
1114 proto_tree_add_text(prefix_tree
, tvb
, offset
+ 4 + 1, length
,
1115 "%s prefix: %s", tag
, ip_to_str(ip_addr
.addr_bytes
));
1117 return(4 + 1 + length
);
1121 * Decode an IPv4 prefix.
1124 decode_prefix4(proto_tree
*tree
, proto_item
*parent_item
, int hf_addr
, tvbuff_t
*tvb
, gint offset
,
1125 guint16 tlen
, const char *tag
)
1128 proto_tree
*prefix_tree
;
1130 guint8 addr_bytes
[4];
1132 } ip_addr
; /* IP address */
1133 guint8 plen
; /* prefix length */
1134 int length
; /* number of octets needed for prefix */
1136 /* snarf length and prefix */
1137 plen
= tvb_get_guint8(tvb
, offset
);
1138 length
= ipv4_addr_and_mask(tvb
, offset
+ 1, ip_addr
.addr_bytes
, plen
);
1140 proto_tree_add_text(tree
, tvb
, offset
, 1, "%s length %u invalid (> 32)",
1145 /* put prefix into protocol tree */
1146 ti
= proto_tree_add_text(tree
, tvb
, offset
,
1147 tlen
!= 0 ? tlen
: 1 + length
, "%s/%u",
1148 ip_to_str(ip_addr
.addr_bytes
), plen
);
1149 /* append parent item if not NULL */
1150 if (parent_item
!= NULL
)
1151 proto_item_append_text(parent_item
, " (%s/%u)",
1152 ip_to_str(ip_addr
.addr_bytes
), plen
);
1154 prefix_tree
= proto_item_add_subtree(ti
, ett_bgp_prefix
);
1155 proto_tree_add_text(prefix_tree
, tvb
, offset
, 1, "%s prefix length: %u",
1157 if (hf_addr
!= -1) {
1158 proto_tree_add_ipv4(prefix_tree
, hf_addr
, tvb
, offset
+ 1, length
,
1161 proto_tree_add_text(prefix_tree
, tvb
, offset
+ 1, length
,
1162 "%s prefix: %s", tag
, ip_to_str(ip_addr
.addr_bytes
));
1168 * Decode an IPv6 prefix.
1171 decode_prefix6(proto_tree
*tree
, int hf_addr
, tvbuff_t
*tvb
, gint offset
,
1172 guint16 tlen
, const char *tag
)
1175 proto_tree
*prefix_tree
;
1176 struct e_in6_addr addr
; /* IPv6 address */
1177 int plen
; /* prefix length */
1178 int length
; /* number of octets needed for prefix */
1180 /* snarf length and prefix */
1181 plen
= tvb_get_guint8(tvb
, offset
);
1182 length
= ipv6_addr_and_mask(tvb
, offset
+ 1, &addr
, plen
);
1184 proto_tree_add_text(tree
, tvb
, offset
, 1, "%s length %u invalid",
1189 /* put prefix into protocol tree */
1190 ti
= proto_tree_add_text(tree
, tvb
, offset
,
1191 tlen
!= 0 ? tlen
: 1 + length
, "%s/%u",
1192 ip6_to_str(&addr
), plen
);
1193 prefix_tree
= proto_item_add_subtree(ti
, ett_bgp_prefix
);
1194 proto_tree_add_text(prefix_tree
, tvb
, offset
, 1, "%s prefix length: %u",
1196 if (hf_addr
!= -1) {
1197 proto_tree_add_ipv6(prefix_tree
, hf_addr
, tvb
, offset
+ 1, length
,
1200 proto_tree_add_text(prefix_tree
, tvb
, offset
+ 1, length
,
1201 "%s prefix: %s", tag
, ip6_to_str(&addr
));
1207 decode_bgp_rd(tvbuff_t
*tvb
, gint offset
)
1210 wmem_strbuf_t
*strbuf
;
1212 rd_type
= tvb_get_ntohs(tvb
,offset
);
1213 strbuf
= wmem_strbuf_new_label(wmem_packet_scope());
1216 case FORMAT_AS2_LOC
:
1217 wmem_strbuf_append_printf(strbuf
, "%u:%u", tvb_get_ntohs(tvb
, offset
+ 2),
1218 tvb_get_ntohl(tvb
, offset
+ 4));
1221 wmem_strbuf_append_printf(strbuf
, "%s:%u", tvb_ip_to_str(tvb
, offset
+ 2),
1222 tvb_get_ntohs(tvb
, offset
+ 6));
1224 case FORMAT_AS4_LOC
:
1225 wmem_strbuf_append_printf(strbuf
, "%u:%u", tvb_get_ntohl(tvb
, offset
+ 2),
1226 tvb_get_ntohs(tvb
, offset
+ 6));
1229 wmem_strbuf_append_printf(strbuf
, "Unknown (0x%04x) RD type",rd_type
);
1231 } /* switch (rd_type) */
1233 return (char*)wmem_strbuf_get_str(strbuf
);
1237 decode_mcast_vpn_nlri_addresses(proto_tree
*tree
, tvbuff_t
*tvb
,
1242 /* Multicast Source Address */
1243 proto_tree_add_item(tree
, hf_bgp_mcast_vpn_nlri_source_length
, tvb
, offset
,
1245 addr_len
= tvb_get_guint8(tvb
, offset
);
1246 if (addr_len
!= 32 && addr_len
!= 128)
1249 if (addr_len
== 32) {
1250 proto_tree_add_item(tree
, hf_bgp_mcast_vpn_nlri_source_addr_ipv4
, tvb
,
1251 offset
, 4, ENC_BIG_ENDIAN
);
1254 proto_tree_add_item(tree
, hf_bgp_mcast_vpn_nlri_source_addr_ipv6
, tvb
,
1255 offset
, 16, ENC_NA
);
1259 /* Multicast Group Address */
1260 proto_tree_add_item(tree
, hf_bgp_mcast_vpn_nlri_group_length
, tvb
, offset
,
1262 addr_len
= tvb_get_guint8(tvb
, offset
);
1263 if (addr_len
!= 32 && addr_len
!= 128)
1266 if (addr_len
== 32) {
1267 proto_tree_add_item(tree
, hf_bgp_mcast_vpn_nlri_group_addr_ipv4
, tvb
,
1268 offset
, 4, ENC_BIG_ENDIAN
);
1271 proto_tree_add_item(tree
, hf_bgp_mcast_vpn_nlri_group_addr_ipv6
, tvb
,
1272 offset
, 16, ENC_NA
);
1280 * function to decode operator in BGP flow spec NLRI when it address decimal values (TCP ports, UDP ports, ports, ...)
1284 decode_bgp_flow_spec_dec_operator(proto_tree
*tree
, tvbuff_t
*tvb
, gint offset
)
1287 proto_item
*op_item
;
1288 proto_tree
*op_tree
;
1290 op_item
= proto_tree_add_item(tree
, hf_bgp_flowspec_nlri_op_flags
, tvb
, offset
, 1, ENC_NA
);
1291 op_tree
= proto_item_add_subtree(op_item
, ett_bgp_flow_spec_nlri_op_flags
);
1293 proto_tree_add_item(op_tree
, hf_bgp_flowspec_nlri_op_eol
,tvb
,offset
,1, ENC_BIG_ENDIAN
);
1294 proto_tree_add_item(op_tree
, hf_bgp_flowspec_nlri_op_and
, tvb
,offset
,1, ENC_BIG_ENDIAN
);
1295 proto_tree_add_item(op_tree
, hf_bgp_flowspec_nlri_op_val_len
,tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1296 proto_tree_add_item(op_tree
, hf_bgp_flowspec_nlri_op_un_bit4
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1297 proto_tree_add_item(op_tree
, hf_bgp_flowspec_nlri_op_lt
, tvb
,offset
, 1, ENC_BIG_ENDIAN
);
1298 proto_tree_add_item(op_tree
, hf_bgp_flowspec_nlri_op_gt
, tvb
,offset
, 1, ENC_BIG_ENDIAN
);
1299 proto_tree_add_item(op_tree
, hf_bgp_flowspec_nlri_op_eq
, tvb
,offset
, 1, ENC_BIG_ENDIAN
);
1303 * Decode an operator and decimal values of BGP flow spec NLRI
1306 decode_bgp_nlri_op_dec_value(proto_tree
*parent_tree
, proto_item
*parent_item
, tvbuff_t
*tvb
, gint offset
)
1308 guint8 nlri_operator
;
1309 guint cursor_op_val
=0;
1312 guint8 shift_amount
=0;
1315 proto_item_append_text(parent_item
," (");
1318 nlri_operator
= tvb_get_guint8(tvb
, offset
+cursor_op_val
);
1319 shift_amount
= nlri_operator
&0x30;
1320 shift_amount
= shift_amount
>> 4;
1321 value_len
= 1 << shift_amount
; /* as written in RFC 5575 section 4 */
1322 /* call to a operator decode function */
1323 decode_bgp_flow_spec_dec_operator(parent_tree
, tvb
, offset
+cursor_op_val
);
1324 if (first_loop
== 0)
1326 /* If first operator we remoe a white space and or (||) is not relevant */
1327 /* BGP flow spec NLRI operator bitmask */
1328 proto_item_append_text(parent_item
,"%s%s%s%s",
1329 ((nlri_operator
& BGPNLRI_FSPEC_AND_BIT
) == 0) ? "" : "&& ",
1330 ((nlri_operator
& BGPNLRI_FSPEC_GREATER_THAN
) == 0) ? "" : ">",
1331 ((nlri_operator
& BGPNLRI_FSPEC_LESS_THAN
) == 0) ? "" : "<",
1332 ((nlri_operator
& BGPNLRI_FSPEC_EQUAL
) == 0) ? "" : "=");
1337 proto_item_append_text(parent_item
," %s%s%s%s",
1338 ((nlri_operator
& BGPNLRI_FSPEC_AND_BIT
) == 0) ? "||" : "&& ",
1339 ((nlri_operator
& BGPNLRI_FSPEC_GREATER_THAN
) == 0) ? "" : ">",
1340 ((nlri_operator
& BGPNLRI_FSPEC_LESS_THAN
) == 0) ? "" : "<",
1341 ((nlri_operator
& BGPNLRI_FSPEC_EQUAL
) == 0) ? "" : "=");
1343 cursor_op_val
++; /* we manage this operator we move to the value */
1344 switch (value_len
) {
1346 proto_tree_add_item(parent_tree
, hf_bgp_flowspec_nlri_dec_val_8
, tvb
, offset
+cursor_op_val
, 1,ENC_BIG_ENDIAN
);
1347 value
= tvb_get_guint8(tvb
,offset
+cursor_op_val
);
1350 proto_tree_add_item(parent_tree
, hf_bgp_flowspec_nlri_dec_val_16
, tvb
, offset
+cursor_op_val
, 2,ENC_BIG_ENDIAN
);
1351 value
= tvb_get_ntohs(tvb
,offset
+cursor_op_val
);
1354 proto_tree_add_item(parent_tree
, hf_bgp_flowspec_nlri_dec_val_32
, tvb
, offset
+cursor_op_val
, 4, ENC_BIG_ENDIAN
);
1355 value
= tvb_get_ntohl(tvb
,offset
+cursor_op_val
);
1358 proto_tree_add_item(parent_tree
, hf_bgp_flowspec_nlri_dec_val_64
, tvb
, offset
+cursor_op_val
, 8, ENC_BIG_ENDIAN
);
1363 cursor_op_val
= cursor_op_val
+ value_len
;
1364 proto_item_append_text(parent_item
,"%u", value
);
1365 } while ((nlri_operator
&BGPNLRI_FSPEC_END_OF_LST
) == 0);
1366 proto_item_append_text(parent_item
,")");
1367 return (cursor_op_val
);
1372 * function to decode operator in BGP flow spec NLRI when it address a bitmask values (TCP flags, fragmentation flags,...)
1376 decode_bgp_flow_spec_bitmask_operator(proto_tree
*tree
, tvbuff_t
*tvb
, gint offset
)
1378 proto_item
*op_item
;
1379 proto_tree
*op_tree
;
1381 op_item
= proto_tree_add_item(tree
, hf_bgp_flowspec_nlri_op_flags
, tvb
, offset
, 1, ENC_NA
);
1382 op_tree
= proto_item_add_subtree(op_item
, ett_bgp_flow_spec_nlri_op_flags
);
1384 proto_tree_add_item(op_tree
, hf_bgp_flowspec_nlri_op_eol
,tvb
,offset
,1, ENC_BIG_ENDIAN
);
1385 proto_tree_add_item(op_tree
, hf_bgp_flowspec_nlri_op_and
, tvb
,offset
,1, ENC_BIG_ENDIAN
);
1386 proto_tree_add_item(op_tree
, hf_bgp_flowspec_nlri_op_val_len
,tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1387 proto_tree_add_item(op_tree
, hf_bgp_flowspec_nlri_op_un_bit4
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1388 proto_tree_add_item(op_tree
, hf_bgp_flowspec_nlri_op_un_bit5
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1389 proto_tree_add_item(op_tree
, hf_bgp_flowspec_nlri_op_flg_not
, tvb
,offset
, 1,ENC_BIG_ENDIAN
);
1390 proto_tree_add_item(op_tree
, hf_bgp_flowspec_nlri_op_flg_match
, tvb
,offset
, 1,ENC_BIG_ENDIAN
);
1394 * Decode an operator and tcp flags bitmask of BGP flow spec NLRI
1397 decode_bgp_nlri_op_tcpf_value(proto_tree
*parent_tree
, proto_item
*parent_item
, tvbuff_t
*tvb
, gint offset
)
1399 guint8 nlri_operator
;
1401 guint cursor_op_val
=0;
1402 proto_tree
*tcp_tree
;
1403 proto_item
*tcp_item
;
1405 guint8 shift_amount
=0;
1408 proto_item_append_text(parent_item
," (");
1411 nlri_operator
= tvb_get_guint8(tvb
, offset
+cursor_op_val
);
1412 shift_amount
= nlri_operator
&0x30;
1413 shift_amount
= shift_amount
>> 4;
1414 value_len
= 1 << shift_amount
; /* as written in RFC 5575 section 4 */
1415 decode_bgp_flow_spec_bitmask_operator(parent_tree
, tvb
, offset
+cursor_op_val
); /* call to a operator decode function */
1416 if (first_loop
== 0)
1418 /* If first operator we remove a white space and or (||) is not relevant */
1419 proto_item_append_text(parent_item
,"%s%s%s%s",
1420 ((nlri_operator
& BGPNLRI_FSPEC_AND_BIT
) == 0) ? "" : "&& ",
1421 ((nlri_operator
& BGPNLRI_FSPEC_GREATER_THAN
) == 0) ? "" : ">",
1422 ((nlri_operator
& BGPNLRI_FSPEC_LESS_THAN
) == 0) ? "" : "<",
1423 ((nlri_operator
& BGPNLRI_FSPEC_EQUAL
) == 0) ? "" : "=");
1428 proto_item_append_text(parent_item
," %s%s%s%s",
1429 ((nlri_operator
& BGPNLRI_FSPEC_AND_BIT
) == 0) ? "||" : "&& ",
1430 ((nlri_operator
& BGPNLRI_FSPEC_GREATER_THAN
) == 0) ? "" : ">",
1431 ((nlri_operator
& BGPNLRI_FSPEC_LESS_THAN
) == 0) ? "" : "<",
1432 ((nlri_operator
& BGPNLRI_FSPEC_EQUAL
) == 0) ? "" : "=");
1434 cursor_op_val
++; /* we manage this operator we move to the value */
1435 if (value_len
== 2) {
1436 cursor_op_val
++; /* tcp flags are coded over 2 bytes only the second one is significant, we move to second byte */
1439 tcp_item
= proto_tree_add_item(parent_tree
, hf_bgp_flowspec_nlri_tcp_flags
, tvb
, offset
+cursor_op_val
, 1, ENC_NA
);
1440 tcp_tree
= proto_item_add_subtree(tcp_item
, ett_bgp_flow_spec_nlri_tcp
);
1441 tcp_flags
= tvb_get_guint8(tvb
,offset
+cursor_op_val
);
1443 proto_tree_add_item(tcp_tree
, hf_bgp_flowspec_nlri_tcp_flags_cwr
, tvb
, offset
+cursor_op_val
, 1, ENC_BIG_ENDIAN
);
1444 proto_tree_add_item(tcp_tree
, hf_bgp_flowspec_nlri_tcp_flags_ecn
, tvb
, offset
+cursor_op_val
, 1, ENC_BIG_ENDIAN
);
1445 proto_tree_add_item(tcp_tree
, hf_bgp_flowspec_nlri_tcp_flags_urg
, tvb
, offset
+cursor_op_val
, 1, ENC_BIG_ENDIAN
);
1446 proto_tree_add_item(tcp_tree
, hf_bgp_flowspec_nlri_tcp_flags_ack
, tvb
, offset
+cursor_op_val
, 1, ENC_BIG_ENDIAN
);
1447 proto_tree_add_item(tcp_tree
, hf_bgp_flowspec_nlri_tcp_flags_push
, tvb
, offset
+cursor_op_val
, 1, ENC_BIG_ENDIAN
);
1448 proto_tree_add_item(tcp_tree
, hf_bgp_flowspec_nlri_tcp_flags_reset
, tvb
, offset
+cursor_op_val
, 1, ENC_BIG_ENDIAN
);
1449 proto_tree_add_item(tcp_tree
, hf_bgp_flowspec_nlri_tcp_flags_syn
, tvb
, offset
+cursor_op_val
, 1, ENC_BIG_ENDIAN
);
1450 proto_tree_add_item(tcp_tree
, hf_bgp_flowspec_nlri_tcp_flags_fin
, tvb
, offset
+cursor_op_val
, 1, ENC_BIG_ENDIAN
);
1451 proto_item_append_text(parent_item
," %s%s%s%s%s%s",
1452 ((tcp_flags
& BGPNLRI_FSPEC_TH_URG
) == 0) ? "" : "U",
1453 ((tcp_flags
& BGPNLRI_FSPEC_TH_ACK
) == 0) ? "" : "A",
1454 ((tcp_flags
& BGPNLRI_FSPEC_TH_PUSH
) == 0) ? "" : "P",
1455 ((tcp_flags
& BGPNLRI_FSPEC_TH_RST
) == 0) ? "" : "R",
1456 ((tcp_flags
& BGPNLRI_FSPEC_TH_SYN
) == 0) ? "" : "S",
1457 ((tcp_flags
& BGPNLRI_FSPEC_TH_FIN
) == 0) ? "" : "F");
1458 cursor_op_val
= cursor_op_val
+ value_len
;
1459 } while ((nlri_operator
&BGPNLRI_FSPEC_END_OF_LST
) == 0);
1460 proto_item_append_text(parent_item
,")");
1461 return (cursor_op_val
);
1466 * Decode an operator and fragmentation bitmask of BGP flow spec NLRI
1469 decode_bgp_nlri_op_fflag_value(proto_tree
*parent_tree
, proto_item
*parent_item
, tvbuff_t
*tvb
, gint offset
)
1471 guint8 nlri_operator
;
1472 guint8 fragment_flags
;
1473 guint cursor_op_val
=0;
1474 proto_tree
*ff_tree
;
1475 proto_item
*ff_item
;
1477 guint8 shift_amount
=0;
1480 proto_item_append_text(parent_item
," (");
1483 nlri_operator
= tvb_get_guint8(tvb
, offset
+cursor_op_val
);
1484 shift_amount
= nlri_operator
&0x30;
1485 shift_amount
= shift_amount
>> 4;
1486 value_len
= 1 << shift_amount
; /* as written in RFC 5575 section 4 */
1487 /* call a function to decode operator addressing bitmaks */
1488 decode_bgp_flow_spec_bitmask_operator(parent_tree
, tvb
, offset
+cursor_op_val
);
1489 if (first_loop
== 0)
1491 /* If first operator we remove a white space and or (||) is not relevant */
1492 proto_item_append_text(parent_item
,"%s%s%s%s",
1493 ((nlri_operator
& BGPNLRI_FSPEC_AND_BIT
) == 0) ? "" : "&& ",
1494 ((nlri_operator
& BGPNLRI_FSPEC_GREATER_THAN
) == 0) ? "" : ">",
1495 ((nlri_operator
& BGPNLRI_FSPEC_LESS_THAN
) == 0) ? "" : "<",
1496 ((nlri_operator
& BGPNLRI_FSPEC_EQUAL
) == 0) ? "" : "=");
1501 proto_item_append_text(parent_item
," %s%s%s%s",
1502 ((nlri_operator
& BGPNLRI_FSPEC_AND_BIT
) == 0) ? "||" : "&& ",
1503 ((nlri_operator
& BGPNLRI_FSPEC_GREATER_THAN
) == 0) ? "" : ">",
1504 ((nlri_operator
& BGPNLRI_FSPEC_LESS_THAN
) == 0) ? "" : "<",
1505 ((nlri_operator
& BGPNLRI_FSPEC_EQUAL
) == 0) ? "" : "=");
1507 cursor_op_val
++; /* we manage this operator we move to the value */
1508 if (value_len
!= 1) {
1509 return -1; /* frag flags have to be coded in 1 byte */
1511 fragment_flags
= tvb_get_guint8(tvb
,offset
+cursor_op_val
);
1512 ff_item
= proto_tree_add_item(parent_tree
, hf_bgp_flowspec_nlri_fflag
, tvb
, offset
+cursor_op_val
, 1, ENC_NA
);
1513 ff_tree
= proto_item_add_subtree(ff_item
, ett_bgp_flow_spec_nlri_ff
);
1514 proto_tree_add_item(ff_tree
, hf_bgp_flowspec_nlri_fflag_lf
, tvb
, offset
+cursor_op_val
, 1, ENC_BIG_ENDIAN
);
1515 proto_tree_add_item(ff_tree
, hf_bgp_flowspec_nlri_fflag_ff
, tvb
, offset
+cursor_op_val
, 1, ENC_BIG_ENDIAN
);
1516 proto_tree_add_item(ff_tree
, hf_bgp_flowspec_nlri_fflag_isf
, tvb
, offset
+cursor_op_val
, 1, ENC_BIG_ENDIAN
);
1517 proto_tree_add_item(ff_tree
, hf_bgp_flowspec_nlri_fflag_df
, tvb
, offset
+cursor_op_val
, 1, ENC_BIG_ENDIAN
);
1518 proto_item_append_text(parent_item
," %s%s%s%s",
1519 ((fragment_flags
& BGPNLRI_FSPEC_FG_DF
) == 0) ? "" : "DF",
1520 ((fragment_flags
& BGPNLRI_FSPEC_FG_ISF
) == 0) ? "" : "IsF",
1521 ((fragment_flags
& BGPNLRI_FSPEC_FG_FF
) == 0) ? "" : "FF",
1522 ((fragment_flags
& BGPNLRI_FSPEC_FG_LF
) == 0) ? "" : "LF");
1523 cursor_op_val
= cursor_op_val
+ value_len
;
1524 } while ((nlri_operator
&BGPNLRI_FSPEC_END_OF_LST
) == 0);
1525 proto_item_append_text(parent_item
,")");
1526 return (cursor_op_val
);
1530 * Decode an operator and DSCP value of BGP flow spec NLRI
1533 decode_bgp_nlri_op_dscp_value(proto_tree
*parent_tree
, proto_item
*parent_item
, tvbuff_t
*tvb
, gint offset
)
1535 guint8 nlri_operator
;
1537 guint cursor_op_val
=0;
1539 guint8 shift_amount
=0;
1542 proto_item_append_text(parent_item
," (");
1545 nlri_operator
= tvb_get_guint8(tvb
, offset
+cursor_op_val
);
1546 shift_amount
= nlri_operator
&0x30;
1547 shift_amount
= shift_amount
>> 4;
1548 value_len
= 1 << shift_amount
; /* as written in RFC 5575 section 4 */
1549 /* call a function to decode operator addressing bitmaks */
1550 decode_bgp_flow_spec_bitmask_operator(parent_tree
, tvb
, offset
+cursor_op_val
);
1551 if (first_loop
== 0)
1553 /* If first operator we remove a white space and or (||) is not relevant */
1554 proto_item_append_text(parent_item
,"%s%s%s%s",
1555 ((nlri_operator
& BGPNLRI_FSPEC_AND_BIT
) == 0) ? "" : "&& ",
1556 ((nlri_operator
& BGPNLRI_FSPEC_GREATER_THAN
) == 0) ? "" : ">",
1557 ((nlri_operator
& BGPNLRI_FSPEC_LESS_THAN
) == 0) ? "" : "<",
1558 ((nlri_operator
& BGPNLRI_FSPEC_EQUAL
) == 0) ? "" : "=");
1563 proto_item_append_text(parent_item
," %s%s%s%s",
1564 ((nlri_operator
& BGPNLRI_FSPEC_AND_BIT
) == 0) ? "||" : "&& ",
1565 ((nlri_operator
& BGPNLRI_FSPEC_GREATER_THAN
) == 0) ? "" : ">",
1566 ((nlri_operator
& BGPNLRI_FSPEC_LESS_THAN
) == 0) ? "" : "<",
1567 ((nlri_operator
& BGPNLRI_FSPEC_EQUAL
) == 0) ? "" : "=");
1569 cursor_op_val
++; /* we manage this operator we move to the value */
1570 if (value_len
!= 1) {
1571 return -1; /* frag flags have to be coded in 1 byte */
1573 dscp_flags
= tvb_get_guint8(tvb
,offset
+cursor_op_val
);
1574 dscp_flags
= dscp_flags
>> 2;
1575 proto_tree_add_item(parent_tree
, hf_bgp_flowspec_nlri_dscp
, tvb
, offset
+cursor_op_val
, 1, ENC_BIG_ENDIAN
);
1576 proto_item_append_text(parent_item
,"%s",val_to_str_ext_const(dscp_flags
,&dscp_vals_ext
, "Unknown DSCP"));
1577 cursor_op_val
= cursor_op_val
+ value_len
;
1578 } while ((nlri_operator
&BGPNLRI_FSPEC_END_OF_LST
) == 0);
1579 proto_item_append_text(parent_item
,")");
1580 return (cursor_op_val
);
1586 * Decode an FLOWSPEC nlri as define in RFC 5575
1589 decode_flowspec_nlri(proto_tree
*tree
, tvbuff_t
*tvb
, gint offset
, guint16 afi
, packet_info
*pinfo
)
1591 guint tot_flow_len
; /* total length of the flow spec NLRI */
1592 guint offset_len
; /* offset of the flow spec NLRI itself could be 1 or 2 bytes */
1593 guint cursor_fspec
; /* cursor to move into flow spec nlri */
1597 proto_item
*filter_item
;
1598 proto_tree
*nlri_tree
;
1599 proto_tree
*filter_tree
;
1602 if (afi
!= AFNUM_INET
)
1604 expert_add_info(pinfo
, NULL
, &ei_bgp_afi_type_not_supported
);
1608 tot_flow_len
= tvb_get_guint8(tvb
, offset
);
1609 /* if nlri length is greater than 240 bytes, it is encoded over 2 bytes */
1610 /* with most significant nibble all in one. 240 is encoded 0xf0f0, 241 0xf0f1 */
1611 /* max possible value value is 4095 Oxffff */
1613 if (tot_flow_len
>= 240)
1615 len_16
= tvb_get_ntohs(tvb
, offset
);
1616 tot_flow_len
= len_16
>> 4; /* move 4 bits to the right to remove first f */
1622 item
= proto_tree_add_item(tree
, hf_bgp_flowspec_nlri_t
, tvb
, offset
,
1623 tot_flow_len
+offset_len
, ENC_NA
);
1624 proto_item_set_text(item
, "FLOW_SPEC_NLRI (%u byte%s)",
1625 tot_flow_len
+offset_len
, plurality(tot_flow_len
+offset_len
, "", "s"));
1627 nlri_tree
= proto_item_add_subtree(item
, ett_bgp_flow_spec_nlri
);
1629 proto_tree_add_uint(nlri_tree
, hf_bgp_flowspec_nlri_length
, tvb
, offset
,
1630 offset_len
, tot_flow_len
);
1632 offset
= offset
+ offset_len
;
1635 while (cursor_fspec
< tot_flow_len
)
1637 filter_item
= proto_tree_add_item(nlri_tree
, hf_bgp_flowspec_nlri_filter
, tvb
, offset
+cursor_fspec
, 1, ENC_NA
);
1638 filter_tree
= proto_item_add_subtree(filter_item
, ett_bgp_flow_spec_nlri_filter
);
1639 proto_tree_add_item(filter_tree
, hf_bgp_flowspec_nlri_filter_type
, tvb
, offset
+cursor_fspec
, 1, ENC_NA
);
1640 proto_item_append_text(filter_item
, ": %s", val_to_str(tvb_get_guint8(tvb
,offset
+cursor_fspec
), flowspec_nlri_opvaluepair_type
, "Unknown filter %d"));
1641 switch (tvb_get_guint8(tvb
,offset
+cursor_fspec
)) {
1642 case BGPNLRI_FSPEC_DST_PFIX
:
1644 filter_len
= decode_prefix4(filter_tree
, filter_item
, hf_bgp_flowspec_nlri_dst_pref_ipv4
, tvb
, offset
+cursor_fspec
, 0, "Destination IP filter");
1645 if (filter_len
== -1)
1646 cursor_fspec
= tot_flow_len
;
1648 case BGPNLRI_FSPEC_SRC_PFIX
:
1650 filter_len
= decode_prefix4(filter_tree
, filter_item
, hf_bgp_flowspec_nlri_src_pref_ipv4
, tvb
, offset
+cursor_fspec
, 0, "Source IP filter");
1651 if (filter_len
== -1)
1652 cursor_fspec
= tot_flow_len
;
1654 case BGPNLRI_FSPEC_IP_PROTO
:
1656 filter_len
= decode_bgp_nlri_op_dec_value(filter_tree
, filter_item
, tvb
, offset
+cursor_fspec
);
1658 case BGPNLRI_FSPEC_PORT
:
1660 filter_len
= decode_bgp_nlri_op_dec_value(filter_tree
, filter_item
, tvb
, offset
+cursor_fspec
);
1662 case BGPNLRI_FSPEC_DST_PORT
:
1664 filter_len
= decode_bgp_nlri_op_dec_value(filter_tree
, filter_item
, tvb
, offset
+cursor_fspec
);
1666 case BGPNLRI_FSPEC_SRC_PORT
:
1668 filter_len
= decode_bgp_nlri_op_dec_value(filter_tree
, filter_item
, tvb
, offset
+cursor_fspec
);
1670 case BGPNLRI_FSPEC_ICMP_TP
:
1672 filter_len
= decode_bgp_nlri_op_dec_value(filter_tree
, filter_item
, tvb
, offset
+cursor_fspec
);
1674 case BGPNLRI_FSPEC_ICMP_CD
:
1676 filter_len
= decode_bgp_nlri_op_dec_value(filter_tree
, filter_item
, tvb
, offset
+cursor_fspec
);
1678 case BGPNLRI_FSPEC_TCP_FLAGS
:
1680 filter_len
= decode_bgp_nlri_op_tcpf_value(filter_tree
, filter_item
, tvb
, offset
+cursor_fspec
);
1682 case BGPNLRI_FSPEC_PCK_LEN
:
1684 filter_len
= decode_bgp_nlri_op_dec_value(filter_tree
, filter_item
, tvb
, offset
+cursor_fspec
);
1686 case BGPNLRI_FSPEC_DSCP
:
1688 filter_len
= decode_bgp_nlri_op_dscp_value(filter_tree
, filter_item
, tvb
, offset
+cursor_fspec
);
1690 case BGPNLRI_FSPEC_FRAGMENT
:
1692 filter_len
= decode_bgp_nlri_op_fflag_value(filter_tree
, filter_item
, tvb
, offset
+cursor_fspec
);
1695 proto_tree_add_text(filter_tree
, tvb
, offset
+cursor_fspec
,1,
1696 "NLRI Type unknown (%u)",tvb_get_guint8(tvb
,offset
+cursor_fspec
));
1700 cursor_fspec
+= filter_len
;
1703 proto_item_set_len(filter_item
,filter_len
+1);
1705 return(tot_flow_len
);
1709 * Decode an MCAST-VPN nlri as defined in draft-ietf-l3vpn-2547bis-mcast-bgp-08.txt .
1712 decode_mcast_vpn_nlri(proto_tree
*tree
, tvbuff_t
*tvb
, gint offset
, guint16 afi
)
1714 guint8 route_type
, length
, ip_length
;
1716 proto_tree
*nlri_tree
;
1717 guint32 route_key_length
;
1720 ip_length
= (afi
== AFNUM_INET
) ? 4 : 16;
1722 route_type
= tvb_get_guint8(tvb
, offset
);
1723 proto_tree_add_item(tree
, hf_bgp_mcast_vpn_nlri_route_type
, tvb
,
1724 offset
, 1, ENC_BIG_ENDIAN
);
1727 length
= tvb_get_guint8(tvb
, offset
);
1728 proto_tree_add_item(tree
, hf_bgp_mcast_vpn_nlri_length
, tvb
, offset
,
1732 if (length
< tvb_reported_length_remaining(tvb
, offset
))
1735 item
= proto_tree_add_item(tree
, hf_bgp_mcast_vpn_nlri_t
, tvb
, offset
,
1737 proto_item_set_text(item
, "%s (%u byte%s)",
1738 val_to_str_const(route_type
, mcast_vpn_route_type
, "Unknown"),
1739 length
, plurality(length
, "", "s"));
1741 nlri_tree
= proto_item_add_subtree(item
, ett_bgp_mcast_vpn_nlri
);
1743 switch (route_type
) {
1744 case MCAST_VPN_RTYPE_INTRA_AS_IPMSI_AD
:
1745 item
= proto_tree_add_item(nlri_tree
, hf_bgp_mcast_vpn_nlri_rd
, tvb
,
1746 offset
, BGP_ROUTE_DISTINGUISHER_SIZE
,
1748 proto_item_set_text(item
, "Route Distinguisher: %s",
1749 decode_bgp_rd(tvb
, offset
));
1750 offset
+= BGP_ROUTE_DISTINGUISHER_SIZE
;
1752 if (afi
== AFNUM_INET
)
1753 proto_tree_add_item(nlri_tree
,
1754 hf_bgp_mcast_vpn_nlri_origin_router_ipv4
,
1755 tvb
, offset
, ip_length
, ENC_BIG_ENDIAN
);
1757 proto_tree_add_item(nlri_tree
,
1758 hf_bgp_mcast_vpn_nlri_origin_router_ipv6
,
1759 tvb
, offset
, ip_length
, ENC_NA
);
1762 case MCAST_VPN_RTYPE_INTER_AS_IPMSI_AD
:
1763 item
= proto_tree_add_item(nlri_tree
, hf_bgp_mcast_vpn_nlri_rd
, tvb
,
1764 offset
, BGP_ROUTE_DISTINGUISHER_SIZE
,
1766 proto_item_set_text(item
, "Route Distinguisher: %s",
1767 decode_bgp_rd(tvb
, offset
));
1768 offset
+= BGP_ROUTE_DISTINGUISHER_SIZE
;
1770 proto_tree_add_item(nlri_tree
, hf_bgp_mcast_vpn_nlri_source_as
, tvb
,
1771 offset
, 4, ENC_BIG_ENDIAN
);
1774 case MCAST_VPN_RTYPE_SPMSI_AD
:
1775 item
= proto_tree_add_item(nlri_tree
, hf_bgp_mcast_vpn_nlri_rd
, tvb
,
1776 offset
, BGP_ROUTE_DISTINGUISHER_SIZE
,
1778 proto_item_set_text(item
, "Route Distinguisher: %s",
1779 decode_bgp_rd(tvb
, offset
));
1780 offset
+= BGP_ROUTE_DISTINGUISHER_SIZE
;
1782 ret
= decode_mcast_vpn_nlri_addresses(nlri_tree
, tvb
, offset
);
1787 case MCAST_VPN_RTYPE_LEAF_AD
:
1788 route_key_length
= length
- ip_length
;
1789 item
= proto_tree_add_item(nlri_tree
,
1790 hf_bgp_mcast_vpn_nlri_route_key
, tvb
,
1791 offset
, route_key_length
, ENC_NA
);
1792 proto_item_set_text(item
, "Route Key (%u byte%s)", route_key_length
,
1793 plurality(route_key_length
, "", "s"));
1794 offset
+= route_key_length
;
1796 if (afi
== AFNUM_INET
)
1797 proto_tree_add_item(nlri_tree
,
1798 hf_bgp_mcast_vpn_nlri_origin_router_ipv4
,
1799 tvb
, offset
, ip_length
, ENC_BIG_ENDIAN
);
1801 proto_tree_add_item(nlri_tree
,
1802 hf_bgp_mcast_vpn_nlri_origin_router_ipv6
,
1803 tvb
, offset
, ip_length
, ENC_NA
);
1806 case MCAST_VPN_RTYPE_SOURCE_ACTIVE_AD
:
1807 item
= proto_tree_add_item(nlri_tree
, hf_bgp_mcast_vpn_nlri_rd
, tvb
,
1808 offset
, BGP_ROUTE_DISTINGUISHER_SIZE
,
1810 proto_item_set_text(item
, "Route Distinguisher: %s",
1811 decode_bgp_rd(tvb
, offset
));
1812 offset
+= BGP_ROUTE_DISTINGUISHER_SIZE
;
1814 ret
= decode_mcast_vpn_nlri_addresses(nlri_tree
, tvb
, offset
);
1819 case MCAST_VPN_RTYPE_SHARED_TREE_JOIN
:
1820 case MCAST_VPN_RTYPE_SOURCE_TREE_JOIN
:
1821 item
= proto_tree_add_item(nlri_tree
, hf_bgp_mcast_vpn_nlri_rd
, tvb
,
1822 offset
, BGP_ROUTE_DISTINGUISHER_SIZE
,
1824 proto_item_set_text(item
, "Route Distinguisher: %s",
1825 decode_bgp_rd(tvb
, offset
));
1826 offset
+= BGP_ROUTE_DISTINGUISHER_SIZE
;
1828 proto_tree_add_item(nlri_tree
, hf_bgp_mcast_vpn_nlri_source_as
, tvb
,
1832 ret
= decode_mcast_vpn_nlri_addresses(nlri_tree
, tvb
, offset
);
1838 /* route type field (1 byte) + length field (1 byte) + length */
1843 * Decodes an MDT-SAFI message.
1846 decode_mdt_safi(proto_tree
*tree
, tvbuff_t
*tvb
, gint offset
)
1848 const guint ip_length
= 4;
1849 const guint mdt_safi_nlri_length_bits
= 128;
1850 guint length
; /* length in bits */
1851 gint orig_offset
= offset
;
1854 length
= tvb_get_guint8(tvb
, offset
);
1855 if (length
!= mdt_safi_nlri_length_bits
)
1859 item
= proto_tree_add_item(tree
, hf_bgp_mdt_nlri_safi_rd
, tvb
,
1860 offset
, BGP_ROUTE_DISTINGUISHER_SIZE
, ENC_NA
);
1861 proto_item_set_text(item
, "Route Distinguisher: %s",
1862 decode_bgp_rd(tvb
, offset
));
1863 offset
+= BGP_ROUTE_DISTINGUISHER_SIZE
;
1865 proto_tree_add_item(tree
, hf_bgp_mdt_nlri_safi_ipv4_addr
, tvb
,
1866 offset
, ip_length
, ENC_BIG_ENDIAN
);
1867 offset
+= ip_length
;
1869 proto_tree_add_item(tree
, hf_bgp_mdt_nlri_safi_group_addr
, tvb
,
1870 offset
, ip_length
, ENC_BIG_ENDIAN
);
1871 offset
+= ip_length
;
1873 return offset
- orig_offset
;
1877 * Decode an MPLS label stack
1878 * XXX - We should change *buf to **buf, use ep_alloc() and drop the buflen
1882 decode_MPLS_stack(tvbuff_t
*tvb
, gint offset
, wmem_strbuf_t
*stack_strbuf
)
1884 guint32 label_entry
; /* an MPLS label enrty (label + COS field + stack bit */
1885 gint indx
; /* index for the label stack */
1888 label_entry
= 0x000000 ;
1890 wmem_strbuf_truncate(stack_strbuf
, 0);
1892 while ((label_entry
& 0x000001) == 0) {
1894 label_entry
= tvb_get_ntoh24(tvb
, indx
) ;
1896 /* withdrawn routes may contain 0 or 0x800000 in the first label */
1897 if((indx
-offset
)==0&&(label_entry
==0||label_entry
==0x800000)) {
1898 wmem_strbuf_append(stack_strbuf
, "0 (withdrawn)");
1902 wmem_strbuf_append_printf(stack_strbuf
, "%u%s", label_entry
>> 4,
1903 ((label_entry
& 0x000001) == 0) ? "," : " (bottom)");
1907 if ((label_entry
& 0x000001) == 0) {
1908 /* real MPLS multi-label stack in BGP? - maybe later; for now, it must be a bogus packet */
1909 wmem_strbuf_append(stack_strbuf
, " (BOGUS: Bottom of Stack NOT set!)");
1914 return((indx
- offset
) / 3);
1918 * Decode a multiprotocol address
1922 mp_addr_to_str (guint16 afi
, guint8 safi
, tvbuff_t
*tvb
, gint offset
, wmem_strbuf_t
*strbuf
, gint nhlen
)
1924 int length
; /* length of the address in byte */
1925 guint32 ip4addr
,ip4addr2
; /* IPv4 address */
1926 guint16 rd_type
; /* Route Distinguisher type */
1927 struct e_in6_addr ip6addr
; /* IPv6 address */
1932 case SAFNUM_UNICAST
:
1933 case SAFNUM_MULCAST
:
1934 case SAFNUM_UNIMULC
:
1935 case SAFNUM_MPLS_LABEL
:
1936 case SAFNUM_ENCAPSULATION
:
1937 case SAFNUM_ROUTE_TARGET
:
1938 /* RTF NHop can be IPv4 or IPv6. They are differentiated by length of the field*/
1941 wmem_strbuf_append(strbuf
, tvb_ip_to_str(tvb
, offset
));
1942 } else if (nhlen
== 16) {
1943 wmem_strbuf_append(strbuf
, tvb_ip6_to_str(tvb
, offset
));
1945 wmem_strbuf_append(strbuf
, "Unknown address");
1950 ip4addr
= tvb_get_ipv4(tvb
, offset
);
1951 wmem_strbuf_append(strbuf
, ip_to_str((guint8
*)&ip4addr
));
1953 case SAFNUM_LAB_VPNUNICAST
:
1954 case SAFNUM_LAB_VPNMULCAST
:
1955 case SAFNUM_LAB_VPNUNIMULC
:
1956 rd_type
=tvb_get_ntohs(tvb
,offset
) ;
1957 wmem_strbuf_truncate(strbuf
, 0);
1959 case FORMAT_AS2_LOC
:
1960 length
= 8 + sizeof(ip4addr
);
1961 ip4addr
= tvb_get_ipv4(tvb
, offset
+ 8); /* Next Hop */
1962 wmem_strbuf_append_printf(strbuf
, "Empty Label Stack RD=%u:%u IPv4=%s",
1963 tvb_get_ntohs(tvb
, offset
+ 2),
1964 tvb_get_ntohl(tvb
, offset
+ 4),
1965 ip_to_str((guint8
*)&ip4addr
));
1968 length
= 8 + sizeof(ip4addr
);
1969 ip4addr
= tvb_get_ipv4(tvb
, offset
+ 2); /* IP part of the RD */
1970 ip4addr2
= tvb_get_ipv4(tvb
, offset
+ 8); /* Next Hop */
1971 wmem_strbuf_append_printf(strbuf
, "Empty Label Stack RD=%s:%u IPv4=%s",
1972 ip_to_str((guint8
*)&ip4addr
),
1973 tvb_get_ntohs(tvb
, offset
+ 6),
1974 ip_to_str((guint8
*)&ip4addr2
));
1976 case FORMAT_AS4_LOC
:
1977 length
= 8 + sizeof(ip4addr
);
1978 ip4addr
= tvb_get_ipv4(tvb
, offset
+ 8); /* Next Hop */
1979 wmem_strbuf_append_printf(strbuf
, "Empty Label Stack RD=%u.%u:%u IPv4=%s",
1980 tvb_get_ntohs(tvb
, offset
+ 2),
1981 tvb_get_ntohs(tvb
, offset
+ 4),
1982 tvb_get_ntohs(tvb
, offset
+ 6),
1983 ip_to_str((guint8
*)&ip4addr
));
1987 wmem_strbuf_append_printf(strbuf
, "Unknown (0x%04x) labeled VPN IPv4 address format",rd_type
);
1989 } /* switch (rd_type) */
1993 wmem_strbuf_truncate(strbuf
, 0);
1994 wmem_strbuf_append_printf(strbuf
, "Unknown SAFI (%u) for AFI %u", safi
, afi
);
1996 } /* switch (safi) */
1999 wmem_strbuf_truncate(strbuf
, 0);
2001 case SAFNUM_UNICAST
:
2002 case SAFNUM_MULCAST
:
2003 case SAFNUM_UNIMULC
:
2004 case SAFNUM_MPLS_LABEL
:
2005 case SAFNUM_ENCAPSULATION
:
2008 tvb_get_ipv6(tvb
, offset
, &ip6addr
);
2009 wmem_strbuf_append_printf(strbuf
, "%s", ip6_to_str(&ip6addr
));
2011 case SAFNUM_LAB_VPNUNICAST
:
2012 case SAFNUM_LAB_VPNMULCAST
:
2013 case SAFNUM_LAB_VPNUNIMULC
:
2014 rd_type
=tvb_get_ntohs(tvb
,offset
) ;
2016 case FORMAT_AS2_LOC
:
2018 tvb_get_ipv6(tvb
, offset
+ 8, &ip6addr
); /* Next Hop */
2019 wmem_strbuf_append_printf(strbuf
, "Empty Label Stack RD=%u:%u IPv6=%s",
2020 tvb_get_ntohs(tvb
, offset
+ 2),
2021 tvb_get_ntohl(tvb
, offset
+ 4),
2022 ip6_to_str(&ip6addr
));
2026 ip4addr
= tvb_get_ipv4(tvb
, offset
+ 2); /* IP part of the RD */
2027 tvb_get_ipv6(tvb
, offset
+ 8, &ip6addr
); /* Next Hop */
2028 wmem_strbuf_append_printf(strbuf
, "Empty Label Stack RD=%s:%u IPv6=%s",
2029 ip_to_str((guint8
*)&ip4addr
),
2030 tvb_get_ntohs(tvb
, offset
+ 6),
2031 ip6_to_str(&ip6addr
));
2033 case FORMAT_AS4_LOC
:
2035 tvb_get_ipv6(tvb
, offset
+ 8, &ip6addr
); /* Next Hop */
2036 wmem_strbuf_append_printf(strbuf
, "Empty Label Stack RD=%u:%u IPv6=%s",
2037 tvb_get_ntohl(tvb
, offset
+ 2),
2038 tvb_get_ntohs(tvb
, offset
+ 6),
2039 ip6_to_str(&ip6addr
));
2043 wmem_strbuf_append_printf(strbuf
, "Unknown (0x%04x) labeled VPN IPv6 address format",rd_type
);
2045 } /* switch (rd_type) */
2049 wmem_strbuf_append_printf(strbuf
, "Unknown SAFI (%u) for AFI %u", safi
, afi
);
2051 } /* switch (safi) */
2054 case AFNUM_L2VPN_OLD
:
2055 wmem_strbuf_truncate(strbuf
, 0);
2057 case SAFNUM_LAB_VPNUNICAST
: /* only labeles prefixes do make sense */
2058 case SAFNUM_LAB_VPNMULCAST
:
2059 case SAFNUM_LAB_VPNUNIMULC
:
2061 length
= 4; /* the next-hop is simply an ipv4 addr */
2062 ip4addr
= tvb_get_ipv4(tvb
, offset
+ 0);
2063 wmem_strbuf_append_printf(strbuf
, "IPv4=%s",
2064 ip_to_str((guint8
*)&ip4addr
));
2068 wmem_strbuf_append_printf(strbuf
, "Unknown SAFI (%u) for AFI %u", safi
, afi
);
2070 } /* switch (safi) */
2074 wmem_strbuf_truncate(strbuf
, 0);
2075 wmem_strbuf_append_printf(strbuf
, "Unknown AFI (%u) value", afi
);
2077 } /* switch (afi) */
2082 * Decode a multiprotocol prefix
2085 decode_prefix_MP(proto_tree
*tree
, int hf_addr4
, int hf_addr6
,
2086 guint16 afi
, guint8 safi
, tvbuff_t
*tvb
, gint offset
,
2087 const char *tag
, packet_info
*pinfo
)
2089 int start_offset
= offset
;
2091 proto_tree
*prefix_tree
;
2092 int total_length
; /* length of the entire item */
2093 int length
; /* length of the prefix address, in bytes */
2094 guint plen
; /* length of the prefix address, in bits */
2095 guint labnum
; /* number of labels */
2096 guint16 tnl_id
; /* Tunnel Identifier */
2097 int ce_id
,labblk_off
,labblk_size
;
2099 guint8 addr_bytes
[4];
2101 } ip4addr
, ip4addr2
; /* IPv4 address */
2102 struct e_in6_addr ip6addr
; /* IPv6 address */
2103 guint16 rd_type
; /* Route Distinguisher type */
2104 wmem_strbuf_t
*stack_strbuf
; /* label stack */
2105 wmem_strbuf_t
*comm_strbuf
;
2112 case SAFNUM_UNICAST
:
2113 case SAFNUM_MULCAST
:
2114 case SAFNUM_UNIMULC
:
2115 total_length
= decode_prefix4(tree
, NULL
,hf_addr4
, tvb
, offset
, 0, tag
);
2116 if (total_length
< 0)
2120 case SAFNUM_MPLS_LABEL
:
2121 plen
= tvb_get_guint8(tvb
, offset
);
2122 stack_strbuf
= wmem_strbuf_new_label(wmem_packet_scope());
2123 labnum
= decode_MPLS_stack(tvb
, offset
+ 1, stack_strbuf
);
2125 offset
+= (1 + labnum
* 3);
2126 if (plen
<= (labnum
* 3*8)) {
2127 proto_tree_add_text(tree
, tvb
, start_offset
, 1,
2128 "%s Labeled IPv4 prefix length %u invalid",
2132 plen
-= (labnum
* 3*8);
2133 length
= ipv4_addr_and_mask(tvb
, offset
, ip4addr
.addr_bytes
, plen
);
2135 proto_tree_add_text(tree
, tvb
, start_offset
, 1,
2136 "%s Labeled IPv4 prefix length %u invalid",
2137 tag
, plen
+ (labnum
* 3*8));
2141 ti
= proto_tree_add_text(tree
, tvb
, start_offset
,
2142 (offset
+ length
) - start_offset
,
2143 "Label Stack=%s IPv4=%s/%u",
2144 wmem_strbuf_get_str(stack_strbuf
),
2145 ip_to_str(ip4addr
.addr_bytes
), plen
);
2146 prefix_tree
= proto_item_add_subtree(ti
, ett_bgp_prefix
);
2147 proto_tree_add_text(prefix_tree
, tvb
, start_offset
, 1, "%s Prefix length: %u",
2148 tag
, plen
+ labnum
* 3 * 8);
2149 proto_tree_add_text(prefix_tree
, tvb
, start_offset
+ 1, 3 * labnum
, "%s Label Stack: %s",
2150 tag
, wmem_strbuf_get_str(stack_strbuf
));
2151 if (hf_addr4
!= -1) {
2152 proto_tree_add_ipv4(prefix_tree
, hf_addr4
, tvb
, offset
,
2153 length
, ip4addr
.addr
);
2155 proto_tree_add_text(prefix_tree
, tvb
, offset
, length
,
2156 "%s IPv4 prefix: %s",
2157 tag
, ip_to_str(ip4addr
.addr_bytes
));
2159 total_length
= (1 + labnum
*3) + length
;
2161 case SAFNUM_MCAST_VPN
:
2162 total_length
= decode_mcast_vpn_nlri(tree
, tvb
, offset
, afi
);
2163 if (total_length
< 0)
2167 total_length
= decode_mdt_safi(tree
, tvb
, offset
);
2168 if (total_length
< 0)
2171 case SAFNUM_ROUTE_TARGET
:
2172 plen
= tvb_get_guint8(tvb
, offset
);
2175 proto_tree_add_text(tree
, tvb
, offset
, 1,
2176 "%s Wildcard route target", tag
);
2181 if ((plen
< 32) || (plen
> 96)) {
2182 proto_tree_add_text(tree
, tvb
, offset
, 1,
2183 "%s Route target length %u invalid",
2188 length
= (plen
+ 7)/8;
2189 comm_strbuf
= wmem_strbuf_new_label(wmem_packet_scope());
2191 switch (tvb_get_ntohs(tvb
, offset
+ 1 + 4)) {
2192 case BGP_EXT_COM_RT_0
:
2193 wmem_strbuf_append_printf(comm_strbuf
, "%u:%u",
2194 tvb_get_ntohs(tvb
, offset
+ 1 + 6),
2195 tvb_get_ntohl(tvb
, offset
+ 1 + 8));
2197 case BGP_EXT_COM_RT_1
:
2198 wmem_strbuf_append_printf(comm_strbuf
, "%s:%u",
2199 tvb_ip_to_str(tvb
, offset
+ 1 + 6),
2200 tvb_get_ntohs(tvb
, offset
+ 1 + 10));
2202 case BGP_EXT_COM_RT_2
:
2203 wmem_strbuf_append_printf(comm_strbuf
, "%u:%u",
2204 tvb_get_ntohl(tvb
, 6),
2205 tvb_get_ntohs(tvb
, offset
+ 1 + 10));
2208 wmem_strbuf_append_printf(comm_strbuf
, "Invalid RT type");
2211 ti
= proto_tree_add_text(tree
, tvb
, offset
+ 1, length
, "%s %u:%s/%u",
2212 tag
, tvb_get_ntohl(tvb
, offset
+ 1 + 0),
2213 wmem_strbuf_get_str(comm_strbuf
),
2215 prefix_tree
= proto_item_add_subtree(ti
, ett_bgp_prefix
);
2216 proto_tree_add_text(prefix_tree
, tvb
, offset
, 1, "%s Prefix length: %u",
2218 proto_tree_add_text(prefix_tree
, tvb
, offset
+ 1, 4, "%s Originating AS: %u",
2219 tag
, tvb_get_ntohl(tvb
, offset
+ 1 + 0));
2220 proto_tree_add_text(prefix_tree
, tvb
, offset
+ 1 + 4, length
- 4, "%s Community prefix: %s",
2221 tag
, wmem_strbuf_get_str(comm_strbuf
));
2222 total_length
= 1 + length
;
2224 case SAFNUM_ENCAPSULATION
:
2225 plen
= tvb_get_guint8(tvb
, offset
);
2227 proto_tree_add_text(tree
, tvb
, offset
, 1,
2228 "%s IPv4 address length %u invalid",
2233 ip4addr
.addr
= tvb_get_ipv4(tvb
, offset
);
2235 proto_tree_add_text(tree
, tvb
, offset
,
2237 "Endpoint Address: %s",
2238 ip_to_str((guint8
*)&ip4addr
));
2240 total_length
= 5; /* length(1 octet) + address(4 octets) */
2243 plen
= tvb_get_guint8(tvb
, offset
);
2245 proto_tree_add_text(tree
, tvb
, start_offset
, 1,
2246 "%s Tunnel IPv4 prefix length %u invalid",
2250 tnl_id
= tvb_get_ntohs(tvb
, offset
+ 1);
2251 offset
+= 3; /* Length + Tunnel Id */
2252 plen
-= 16; /* 2-octet Identifier */
2253 length
= ipv4_addr_and_mask(tvb
, offset
, ip4addr
.addr_bytes
, plen
);
2255 proto_tree_add_text(tree
, tvb
, start_offset
, 1,
2256 "%s Tunnel IPv4 prefix length %u invalid",
2260 ti
= proto_tree_add_text(tree
, tvb
, start_offset
,
2261 (offset
+ length
) - start_offset
,
2262 "Tunnel Identifier=0x%x IPv4=%s/%u",
2263 tnl_id
, ip_to_str(ip4addr
.addr_bytes
), plen
);
2264 prefix_tree
= proto_item_add_subtree(ti
, ett_bgp_prefix
);
2266 proto_tree_add_text(prefix_tree
, tvb
, start_offset
, 1, "%s Prefix length: %u",
2268 proto_tree_add_item(prefix_tree
, hf_bgp_mp_nlri_tnl_id
, tvb
,
2269 start_offset
+ 1, 2, ENC_BIG_ENDIAN
);
2270 if (hf_addr4
!= -1) {
2271 proto_tree_add_ipv4(prefix_tree
, hf_addr4
, tvb
, offset
,
2272 length
, ip4addr
.addr
);
2274 proto_tree_add_text(prefix_tree
, tvb
, offset
, length
,
2275 "%s IPv4 prefix: %s",
2276 tag
, ip_to_str(ip4addr
.addr_bytes
));
2278 total_length
= 1 + 2 + length
; /* length field + Tunnel Id + IPv4 len */
2281 case SAFNUM_LAB_VPNUNICAST
:
2282 case SAFNUM_LAB_VPNMULCAST
:
2283 case SAFNUM_LAB_VPNUNIMULC
:
2284 plen
= tvb_get_guint8(tvb
, offset
);
2285 stack_strbuf
= wmem_strbuf_new_label(wmem_packet_scope());
2286 labnum
= decode_MPLS_stack(tvb
, offset
+ 1, stack_strbuf
);
2288 offset
+= (1 + labnum
* 3);
2289 if (plen
<= (labnum
* 3*8)) {
2290 proto_tree_add_text(tree
, tvb
, start_offset
, 1,
2291 "%s Labeled VPN IPv4 prefix length %u invalid",
2295 plen
-= (labnum
* 3*8);
2297 rd_type
= tvb_get_ntohs(tvb
, offset
);
2299 proto_tree_add_text(tree
, tvb
, start_offset
, 1,
2300 "%s Labeled VPN IPv4 prefix length %u invalid",
2301 tag
, plen
+ (labnum
* 3*8));
2308 case FORMAT_AS2_LOC
: /* Code borrowed from the decode_prefix4 function */
2309 length
= ipv4_addr_and_mask(tvb
, offset
+ 8, ip4addr
.addr_bytes
, plen
);
2311 proto_tree_add_text(tree
, tvb
, start_offset
, 1,
2312 "%s Labeled VPN IPv4 prefix length %u invalid",
2313 tag
, plen
+ (labnum
* 3*8) + 8*8);
2317 ti
= proto_tree_add_text(tree
, tvb
, start_offset
,
2318 (offset
+ 8 + length
) - start_offset
,
2319 "Label Stack=%s RD=%u:%u, IPv4=%s/%u",
2320 wmem_strbuf_get_str(stack_strbuf
),
2321 tvb_get_ntohs(tvb
, offset
+ 2),
2322 tvb_get_ntohl(tvb
, offset
+ 4),
2323 ip_to_str(ip4addr
.addr_bytes
), plen
);
2324 prefix_tree
= proto_item_add_subtree(ti
, ett_bgp_prefix
);
2325 proto_tree_add_text(prefix_tree
, tvb
, start_offset
, 1, "%s Prefix length: %u",
2326 tag
, plen
+ labnum
* 3 * 8 + 8 * 8);
2327 proto_tree_add_text(prefix_tree
, tvb
, start_offset
+ 1, 3 * labnum
,
2328 "%s Label Stack: %s", tag
, wmem_strbuf_get_str(stack_strbuf
));
2329 proto_tree_add_text(prefix_tree
, tvb
, start_offset
+ 1 + 3 * labnum
, 8,
2330 "%s Route Distinguisher: %u:%u", tag
, tvb_get_ntohs(tvb
, offset
+ 2),
2331 tvb_get_ntohl(tvb
, offset
+ 4));
2332 if (hf_addr4
!= -1) {
2333 proto_tree_add_ipv4(prefix_tree
, hf_addr4
, tvb
,
2334 offset
+ 8, length
, ip4addr
.addr
);
2336 proto_tree_add_text(prefix_tree
, tvb
, offset
+ 8,
2337 length
, "%s IPv4 prefix: %s", tag
,
2338 ip_to_str(ip4addr
.addr_bytes
));
2340 total_length
= (1 + labnum
* 3 + 8) + length
;
2343 case FORMAT_IP_LOC
: /* Code borrowed from the decode_prefix4 function */
2344 tvb_memcpy(tvb
, ip4addr
.addr_bytes
, offset
+ 2, 4);
2346 length
= ipv4_addr_and_mask(tvb
, offset
+ 8, ip4addr2
.addr_bytes
, plen
);
2348 proto_tree_add_text(tree
, tvb
, start_offset
, 1,
2349 "%s Labeled VPN IPv4 prefix length %u invalid",
2350 tag
, plen
+ (labnum
* 3*8) + 8*8);
2354 ti
= proto_tree_add_text(tree
, tvb
, start_offset
,
2355 (offset
+ 8 + length
) - start_offset
,
2356 "Label Stack=%s RD=%s:%u, IPv4=%s/%u",
2357 wmem_strbuf_get_str(stack_strbuf
),
2358 ip_to_str(ip4addr
.addr_bytes
),
2359 tvb_get_ntohs(tvb
, offset
+ 6),
2360 ip_to_str(ip4addr2
.addr_bytes
),
2362 prefix_tree
= proto_item_add_subtree(ti
, ett_bgp_prefix
);
2363 proto_tree_add_text(prefix_tree
, tvb
, start_offset
, 1, "%s Prefix length: %u",
2364 tag
, plen
+ labnum
* 3 * 8 + 8 * 8);
2365 proto_tree_add_text(prefix_tree
, tvb
, start_offset
+ 1, 3 * labnum
,
2366 "%s Label Stack: %s", tag
, wmem_strbuf_get_str(stack_strbuf
));
2367 proto_tree_add_text(prefix_tree
, tvb
, start_offset
+ 1 + 3 * labnum
, 8,
2368 "%s Route Distinguisher: %s:%u", tag
, ip_to_str(ip4addr
.addr_bytes
),
2369 tvb_get_ntohs(tvb
, offset
+ 6));
2370 if (hf_addr4
!= -1) {
2371 proto_tree_add_ipv4(prefix_tree
, hf_addr4
, tvb
,
2372 offset
+ 8, length
, ip4addr2
.addr
);
2374 proto_tree_add_text(prefix_tree
, tvb
, offset
+ 8,
2375 length
, "%s IPv4 prefix: %s", tag
,
2376 ip_to_str(ip4addr2
.addr_bytes
));
2378 total_length
= (1 + labnum
* 3 + 8) + length
;
2381 case FORMAT_AS4_LOC
: /* Code borrowed from the decode_prefix4 function */
2382 length
= ipv4_addr_and_mask(tvb
, offset
+ 8, ip4addr
.addr_bytes
, plen
);
2384 proto_tree_add_text(tree
, tvb
, start_offset
, 1,
2385 "%s Labeled VPN IPv4 prefix length %u invalid",
2386 tag
, plen
+ (labnum
* 3*8) + 8*8);
2390 ti
= proto_tree_add_text(tree
, tvb
, start_offset
,
2391 (offset
+ 8 + length
) - start_offset
,
2392 "Label Stack=%s RD=%u.%u:%u, IPv4=%s/%u",
2393 wmem_strbuf_get_str(stack_strbuf
),
2394 tvb_get_ntohs(tvb
, offset
+ 2),
2395 tvb_get_ntohs(tvb
, offset
+ 4),
2396 tvb_get_ntohs(tvb
, offset
+ 6),
2397 ip_to_str(ip4addr
.addr_bytes
), plen
);
2398 prefix_tree
= proto_item_add_subtree(ti
, ett_bgp_prefix
);
2399 proto_tree_add_text(prefix_tree
, tvb
, start_offset
, 1, "%s Prefix length: %u",
2400 tag
, plen
+ labnum
* 3 * 8 + 8 * 8);
2401 proto_tree_add_text(prefix_tree
, tvb
, start_offset
+ 1, 3 * labnum
,
2402 "%s Label Stack: %s", tag
, wmem_strbuf_get_str(stack_strbuf
));
2403 proto_tree_add_text(prefix_tree
, tvb
, start_offset
+ 1 + 3 * labnum
, 8,
2404 "%s Route Distinguisher: %u.%u:%u", tag
, tvb_get_ntohs(tvb
, offset
+ 2),
2405 tvb_get_ntohs(tvb
, offset
+ 4), tvb_get_ntohs(tvb
, offset
+ 6));
2406 if (hf_addr4
!= -1) {
2407 proto_tree_add_ipv4(prefix_tree
, hf_addr4
, tvb
,
2408 offset
+ 8, length
, ip4addr
.addr
);
2410 proto_tree_add_text(prefix_tree
, tvb
, offset
+ 8,
2411 length
, "%s IPv4 prefix: %s", tag
,
2412 ip_to_str(ip4addr
.addr_bytes
));
2414 total_length
= (1 + labnum
* 3 + 8) + length
;
2418 proto_tree_add_text(tree
, tvb
, start_offset
,
2419 (offset
- start_offset
) + 2,
2420 "Unknown labeled VPN IPv4 address format %u", rd_type
);
2422 } /* switch (rd_type) */
2425 case SAFNUM_FSPEC_RULE
:
2426 case SAFNUM_FSPEC_VPN_RULE
:
2427 total_length
= decode_flowspec_nlri(tree
, tvb
, offset
, afi
, pinfo
);
2428 if(total_length
< 0)
2433 proto_tree_add_text(tree
, tvb
, start_offset
, 0,
2434 "Unknown SAFI (%u) for AFI %u", safi
, afi
);
2436 } /* switch (safi) */
2442 case SAFNUM_UNICAST
:
2443 case SAFNUM_MULCAST
:
2444 case SAFNUM_UNIMULC
:
2445 total_length
= decode_prefix6(tree
, hf_addr6
, tvb
, offset
, 0, tag
);
2446 if (total_length
< 0)
2450 case SAFNUM_MPLS_LABEL
:
2451 plen
= tvb_get_guint8(tvb
, offset
);
2452 stack_strbuf
= wmem_strbuf_new_label(wmem_packet_scope());
2453 labnum
= decode_MPLS_stack(tvb
, offset
+ 1, stack_strbuf
);
2455 offset
+= (1 + labnum
* 3);
2456 if (plen
<= (labnum
* 3*8)) {
2457 proto_tree_add_text(tree
, tvb
, start_offset
, 1,
2458 "%s Labeled IPv6 prefix length %u invalid", tag
, plen
);
2461 plen
-= (labnum
* 3*8);
2463 length
= ipv6_addr_and_mask(tvb
, offset
, &ip6addr
, plen
);
2465 proto_tree_add_text(tree
, tvb
, start_offset
, 1,
2466 "%s Labeled IPv6 prefix length %u invalid",
2467 tag
, plen
+ (labnum
* 3*8));
2471 proto_tree_add_text(tree
, tvb
, start_offset
,
2472 (offset
+ length
) - start_offset
,
2473 "Label Stack=%s, IPv6=%s/%u",
2474 wmem_strbuf_get_str(stack_strbuf
),
2475 ip6_to_str(&ip6addr
), plen
);
2476 total_length
= (1 + labnum
* 3) + length
;
2478 case SAFNUM_ENCAPSULATION
:
2479 plen
= tvb_get_guint8(tvb
, offset
);
2481 proto_tree_add_text(tree
, tvb
, offset
, 1,
2482 "%s IPv6 address length %u invalid",
2487 tvb_get_ipv6(tvb
, offset
, &ip6addr
);
2489 proto_tree_add_text(tree
, tvb
, offset
,
2491 "Endpoint Address: %s",
2492 ip6_to_str(&ip6addr
));
2494 total_length
= 17; /* length(1 octet) + address(16 octets) */
2497 plen
= tvb_get_guint8(tvb
, offset
);
2499 proto_tree_add_text(tree
, tvb
, start_offset
, 1,
2500 "%s Tunnel IPv6 prefix length %u invalid",
2504 tnl_id
= tvb_get_ntohs(tvb
, offset
+ 1);
2505 offset
+= 3; /* Length + Tunnel Id */
2506 plen
-= 16; /* 2-octet Identifier */
2507 length
= ipv6_addr_and_mask(tvb
, offset
, &ip6addr
, plen
);
2509 proto_tree_add_text(tree
, tvb
, start_offset
, 1,
2510 "%s Tunnel IPv6 prefix length %u invalid",
2514 proto_tree_add_text(tree
, tvb
, start_offset
,
2515 (offset
+ length
) - start_offset
,
2516 "Tunnel Identifier=0x%x IPv6=%s/%u",
2517 tnl_id
, ip6_to_str(&ip6addr
), plen
);
2518 total_length
= (1 + 2) + length
; /* length field + Tunnel Id + IPv4 len */
2521 case SAFNUM_LAB_VPNUNICAST
:
2522 case SAFNUM_LAB_VPNMULCAST
:
2523 case SAFNUM_LAB_VPNUNIMULC
:
2524 plen
= tvb_get_guint8(tvb
, offset
);
2525 stack_strbuf
= wmem_strbuf_new_label(wmem_packet_scope());
2526 labnum
= decode_MPLS_stack(tvb
, offset
+ 1, stack_strbuf
);
2528 offset
+= (1 + labnum
* 3);
2529 if (plen
<= (labnum
* 3*8)) {
2530 proto_tree_add_text(tree
, tvb
, start_offset
, 1,
2531 "%s Labeled VPN IPv6 prefix length %u invalid", tag
, plen
);
2534 plen
-= (labnum
* 3*8);
2536 rd_type
= tvb_get_ntohs(tvb
,offset
);
2538 proto_tree_add_text(tree
, tvb
, start_offset
, 1,
2539 "%s Labeled VPN IPv6 prefix length %u invalid",
2540 tag
, plen
+ (labnum
* 3*8));
2547 case FORMAT_AS2_LOC
:
2548 length
= ipv6_addr_and_mask(tvb
, offset
+ 8, &ip6addr
, plen
);
2550 proto_tree_add_text(tree
, tvb
, start_offset
, 1,
2551 "%s Labeled VPN IPv6 prefix length %u invalid",
2552 tag
, plen
+ (labnum
* 3*8) + 8*8);
2556 proto_tree_add_text(tree
, tvb
, start_offset
,
2557 (offset
+ 8 + length
) - start_offset
,
2558 "Label Stack=%s RD=%u:%u, IPv6=%s/%u",
2559 wmem_strbuf_get_str(stack_strbuf
),
2560 tvb_get_ntohs(tvb
, offset
+ 2),
2561 tvb_get_ntohl(tvb
, offset
+ 4),
2562 ip6_to_str(&ip6addr
), plen
);
2563 total_length
= (1 + labnum
* 3 + 8) + length
;
2567 tvb_memcpy(tvb
, ip4addr
.addr_bytes
, offset
+ 2, 4);
2569 length
= ipv6_addr_and_mask(tvb
, offset
+ 8, &ip6addr
, plen
);
2571 proto_tree_add_text(tree
, tvb
, start_offset
, 1,
2572 "%s Labeled VPN IPv6 prefix length %u invalid",
2573 tag
, plen
+ (labnum
* 3*8) + 8*8);
2577 proto_tree_add_text(tree
, tvb
, start_offset
,
2578 (offset
+ 8 + length
) - start_offset
,
2579 "Label Stack=%s RD=%s:%u, IPv6=%s/%u",
2580 wmem_strbuf_get_str(stack_strbuf
),
2581 ip_to_str(ip4addr
.addr_bytes
),
2582 tvb_get_ntohs(tvb
, offset
+ 6),
2583 ip6_to_str(&ip6addr
), plen
);
2584 total_length
= (1 + labnum
* 3 + 8) + length
;
2587 case FORMAT_AS4_LOC
:
2588 length
= ipv6_addr_and_mask(tvb
, offset
+ 8, &ip6addr
, plen
);
2590 proto_tree_add_text(tree
, tvb
, start_offset
, 1,
2591 "%s Labeled VPN IPv6 prefix length %u invalid",
2592 tag
, plen
+ (labnum
* 3*8) + 8*8);
2596 proto_tree_add_text(tree
, tvb
, start_offset
,
2597 (offset
+ 8 + length
) - start_offset
,
2598 "Label Stack=%s RD=%u.%u:%u, IPv6=%s/%u",
2599 wmem_strbuf_get_str(stack_strbuf
),
2600 tvb_get_ntohs(tvb
, offset
+ 2),
2601 tvb_get_ntohs(tvb
, offset
+ 4),
2602 tvb_get_ntohs(tvb
, offset
+ 6),
2603 ip6_to_str(&ip6addr
), plen
);
2604 total_length
= (1 + labnum
* 3 + 8) + length
;
2607 proto_tree_add_text(tree
, tvb
, start_offset
, 0,
2608 "Unknown labeled VPN IPv6 address format %u", rd_type
);
2610 } /* switch (rd_type) */
2614 proto_tree_add_text(tree
, tvb
, start_offset
, 0,
2615 "Unknown SAFI (%u) for AFI %u", safi
, afi
);
2617 } /* switch (safi) */
2621 case AFNUM_L2VPN_OLD
:
2624 case SAFNUM_LAB_VPNUNICAST
:
2625 case SAFNUM_LAB_VPNMULCAST
:
2626 case SAFNUM_LAB_VPNUNIMULC
:
2628 plen
= tvb_get_ntohs(tvb
,offset
);
2629 rd_type
=tvb_get_ntohs(tvb
,offset
+2);
2631 /* RFC6074 Section 7 BGP-AD and VPLS-BGP Interoperability
2632 Both BGP-AD and VPLS-BGP [RFC4761] use the same AFI/SAFI. In order
2633 for both BGP-AD and VPLS-BGP to co-exist, the NLRI length must be
2634 used as a demultiplexer.
2636 The BGP-AD NLRI has an NLRI length of 12 bytes, containing only an
2637 8-byte RD and a 4-byte VSI-ID. VPLS-BGP [RFC4761] uses a 17-byte
2638 NLRI length. Therefore, implementations of BGP-AD must ignore NLRI
2639 that are greater than 12 bytes.
2641 if(plen
== 12) /* BGP-AD */
2645 case FORMAT_AS2_LOC
:
2646 proto_tree_add_text(tree
, tvb
, start_offset
,
2647 (offset
+ plen
+ 2) - start_offset
,
2648 "RD: %u:%u, PE_addr: %s",
2649 tvb_get_ntohs(tvb
, offset
+ 4),
2650 tvb_get_ntohl(tvb
, offset
+ 6),
2651 tvb_ip_to_str(tvb
, offset
+ 10));
2655 proto_tree_add_text(tree
, tvb
, offset
,
2656 (offset
+ plen
+ 2) - start_offset
,
2657 "RD: %s:%u, PE_addr: %s",
2658 tvb_ip_to_str(tvb
, offset
+ 10),
2659 tvb_get_ntohs(tvb
, offset
+ 8),
2660 tvb_ip_to_str(tvb
, offset
+ 10));
2662 case FORMAT_AS4_LOC
:
2663 proto_tree_add_text(tree
, tvb
, start_offset
,
2664 (offset
+ plen
+ 2) - start_offset
,
2665 "RD: %u.%u:%u, PE_addr: %s",
2666 tvb_get_ntohs(tvb
, offset
+ 4),
2667 tvb_get_ntohs(tvb
, offset
+ 6),
2668 tvb_get_ntohs(tvb
, offset
+ 8),
2669 tvb_ip_to_str(tvb
, offset
+ 10));
2672 proto_tree_add_text(tree
, tvb
, start_offset
,
2673 (offset
- start_offset
) + 2,
2674 "Unknown labeled VPN address format %u", rd_type
);
2676 } /* switch (rd_type) */
2677 }else{ /* VPLS-BGP */
2678 ce_id
=tvb_get_ntohs(tvb
,offset
+10);
2679 labblk_off
=tvb_get_ntohs(tvb
,offset
+12);
2680 labblk_size
=tvb_get_ntohs(tvb
,offset
+14);
2681 stack_strbuf
= wmem_strbuf_new_label(wmem_packet_scope());
2682 decode_MPLS_stack(tvb
, offset
+ 16, stack_strbuf
);
2685 case FORMAT_AS2_LOC
:
2686 tvb_memcpy(tvb
, ip4addr
.addr_bytes
, offset
+ 6, 4);
2687 proto_tree_add_text(tree
, tvb
, start_offset
,
2688 (offset
+ plen
+ 1) - start_offset
,
2689 "RD: %u:%s, CE-ID: %u, Label-Block Offset: %u, "
2690 "Label-Block Size: %u Label Base %s",
2691 tvb_get_ntohs(tvb
, offset
+ 4),
2692 ip_to_str(ip4addr
.addr_bytes
),
2696 wmem_strbuf_get_str(stack_strbuf
));
2700 tvb_memcpy(tvb
, ip4addr
.addr_bytes
, offset
+ 4, 4);
2701 proto_tree_add_text(tree
, tvb
, offset
,
2702 (offset
+ plen
+ 1) - start_offset
,
2703 "RD: %s:%u, CE-ID: %u, Label-Block Offset: %u, "
2704 "Label-Block Size: %u, Label Base %s",
2705 ip_to_str(ip4addr
.addr_bytes
),
2706 tvb_get_ntohs(tvb
, offset
+ 8),
2710 wmem_strbuf_get_str(stack_strbuf
));
2712 case FORMAT_AS4_LOC
:
2713 proto_tree_add_text(tree
, tvb
, offset
,
2714 (offset
+ plen
+ 1) - start_offset
,
2715 "RD: %u.%u:%u, CE-ID: %u, Label-Block Offset: %u, "
2716 "Label-Block Size: %u, Label Base %s",
2717 tvb_get_ntohs(tvb
, offset
+ 4),
2718 tvb_get_ntohs(tvb
, offset
+ 6),
2719 tvb_get_ntohs(tvb
, offset
+ 8),
2723 wmem_strbuf_get_str(stack_strbuf
));
2726 proto_tree_add_text(tree
, tvb
, start_offset
,
2727 (offset
- start_offset
) + 2,
2728 "Unknown labeled VPN address format %u", rd_type
);
2730 } /* switch (rd_type) */
2732 /* FIXME there are subTLVs left to decode ... for now lets omit them */
2733 total_length
= plen
+2;
2737 proto_tree_add_text(tree
, tvb
, start_offset
, 0,
2738 "Unknown SAFI (%u) for AFI %u", safi
, afi
);
2740 } /* switch (safi) */
2744 proto_tree_add_text(tree
, tvb
, start_offset
, 0,
2745 "Unknown AFI (%u) value", afi
);
2747 } /* switch (afi) */
2748 return(total_length
);
2752 * Dissect a BGP capability.
2755 dissect_bgp_capability_item(tvbuff_t
*tvb
, proto_tree
*tree
, packet_info
*pinfo
, int offset
, gboolean action
)
2757 proto_tree
*cap_tree
;
2763 ti
= proto_tree_add_item(tree
, hf_bgp_cap
, tvb
, offset
, -1, ENC_NA
);
2764 cap_tree
= proto_item_add_subtree(ti
, ett_bgp_cap
);
2766 proto_tree_add_item(cap_tree
, hf_bgp_cap_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2767 ctype
= tvb_get_guint8(tvb
, offset
);
2768 proto_item_append_text(ti
, ": %s", val_to_str(ctype
, capability_vals
, "Unknown capability %d"));
2771 ti_len
= proto_tree_add_item(cap_tree
, hf_bgp_cap_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2772 clen
= tvb_get_guint8(tvb
, offset
);
2773 proto_item_set_len(ti
, clen
+2);
2777 proto_tree_add_item(cap_tree
, hf_bgp_cap_action
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2778 proto_item_set_len(ti
, clen
+3);
2782 /* check the capability type */
2784 case BGP_CAPABILITY_RESERVED
:
2786 expert_add_info_format(pinfo
, ti_len
, &ei_bgp_cap_len_bad
, "Capability length %u wrong, must be = 0", clen
);
2787 proto_tree_add_item(cap_tree
, hf_bgp_cap_unknown
, tvb
, offset
, clen
, ENC_NA
);
2791 case BGP_CAPABILITY_MULTIPROTOCOL
:
2793 expert_add_info_format(pinfo
, ti_len
, &ei_bgp_cap_len_bad
, "Capability length %u is wrong, must be = 4", clen
);
2794 proto_tree_add_item(cap_tree
, hf_bgp_cap_unknown
, tvb
, offset
, clen
, ENC_NA
);
2799 proto_tree_add_item(cap_tree
, hf_bgp_cap_mp_afi
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2803 proto_tree_add_item(cap_tree
, hf_bgp_cap_reserved
, tvb
, offset
, 1, ENC_NA
);
2807 proto_tree_add_item(cap_tree
, hf_bgp_cap_mp_safi
, tvb
, offset
, 1, ENC_NA
);
2812 case BGP_CAPABILITY_GRACEFUL_RESTART
:
2813 if ((clen
< 6) && (clen
!= 2)) {
2814 expert_add_info_format(pinfo
, ti_len
, &ei_bgp_cap_len_bad
, "Capability length %u too short, must be greater than 6", clen
);
2815 proto_tree_add_item(cap_tree
, hf_bgp_cap_unknown
, tvb
, offset
, clen
, ENC_NA
);
2819 int eclen
= offset
+ clen
;
2820 proto_tree
*sub_tree
;
2823 expert_add_info(pinfo
, ti_len
, &ei_bgp_cap_gr_helper_mode_only
);
2827 ti
= proto_tree_add_item(cap_tree
, hf_bgp_cap_gr_timers
, tvb
, offset
, 2, ENC_NA
);
2828 sub_tree
= proto_item_add_subtree(ti
, ett_bgp_cap
);
2829 proto_tree_add_item(sub_tree
, hf_bgp_cap_gr_timers_restart_flag
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2830 proto_tree_add_item(sub_tree
, hf_bgp_cap_gr_timers_restart_time
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2834 * what follows is alist of AFI/SAFI/flag triplets
2835 * read it until the TLV ends
2837 while (offset
< eclen
) {
2839 proto_tree_add_item(cap_tree
, hf_bgp_cap_gr_afi
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2843 proto_tree_add_item(cap_tree
, hf_bgp_cap_gr_safi
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2847 ti
= proto_tree_add_item(cap_tree
, hf_bgp_cap_gr_flag
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2848 sub_tree
= proto_item_add_subtree(ti
, ett_bgp_cap
);
2849 proto_tree_add_item(sub_tree
, hf_bgp_cap_gr_flag_pfs
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2854 case BGP_CAPABILITY_4_OCTET_AS_NUMBER
:
2856 expert_add_info_format(pinfo
, ti_len
, &ei_bgp_cap_len_bad
, "Capability length %u is wrong, must be = 4", clen
);
2857 proto_tree_add_item(cap_tree
, hf_bgp_cap_unknown
, tvb
, offset
, clen
, ENC_NA
);
2861 proto_tree_add_item(cap_tree
, hf_bgp_cap_4as
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2865 case BGP_CAPABILITY_DYNAMIC_CAPABILITY
:
2867 int eclen
= offset
+ clen
;
2869 while (offset
< eclen
) {
2870 proto_tree_add_item(cap_tree
, hf_bgp_cap_dc
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2875 case BGP_CAPABILITY_ADDITIONAL_PATHS
:
2877 expert_add_info_format(pinfo
, ti_len
, &ei_bgp_cap_len_bad
, "Capability length %u is wrong, must be = 4", clen
);
2878 proto_tree_add_item(cap_tree
, hf_bgp_cap_unknown
, tvb
, offset
, clen
, ENC_NA
);
2881 else { /* AFI SAFI Send-receive*/
2883 proto_tree_add_item(cap_tree
, hf_bgp_cap_ap_afi
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2887 proto_tree_add_item(cap_tree
, hf_bgp_cap_ap_safi
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2891 proto_tree_add_item(cap_tree
, hf_bgp_cap_ap_sendreceive
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2897 case BGP_CAPABILITY_ENHANCED_ROUTE_REFRESH
:
2898 case BGP_CAPABILITY_ROUTE_REFRESH_CISCO
:
2899 case BGP_CAPABILITY_ROUTE_REFRESH
:
2901 expert_add_info_format(pinfo
, ti_len
, &ei_bgp_cap_len_bad
, "Capability length %u wrong, must be = 0", clen
);
2902 proto_tree_add_item(cap_tree
, hf_bgp_cap_unknown
, tvb
, offset
, clen
, ENC_NA
);
2906 case BGP_CAPABILITY_ORF_CISCO
:
2907 case BGP_CAPABILITY_COOPERATIVE_ROUTE_FILTERING
:
2909 expert_add_info_format(pinfo
, ti_len
, &ei_bgp_cap_len_bad
, "Capability length %u too short, must be greater than 6", clen
);
2910 proto_tree_add_item(cap_tree
, hf_bgp_cap_unknown
, tvb
, offset
, clen
, ENC_NA
);
2914 guint8 orfnum
; /* number of ORFs */
2917 proto_tree_add_item(cap_tree
, hf_bgp_cap_orf_afi
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2921 proto_tree_add_item(cap_tree
, hf_bgp_cap_reserved
, tvb
, offset
, 1, ENC_NA
);
2925 proto_tree_add_item(cap_tree
, hf_bgp_cap_orf_safi
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2928 /* Number of ORFs */
2929 orfnum
= tvb_get_guint8(tvb
, offset
);
2930 proto_tree_add_item(cap_tree
, hf_bgp_cap_orf_number
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2932 for (i
=0; i
<orfnum
; i
++) {
2934 proto_tree_add_item(cap_tree
, hf_bgp_cap_orf_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2938 proto_tree_add_item(cap_tree
, hf_bgp_cap_orf_sendreceive
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2944 /* unknown capability */
2947 proto_tree_add_item(cap_tree
, hf_bgp_cap_unknown
, tvb
, offset
, clen
, ENC_NA
);
2951 } /* switch (ctype) */
2956 * Dissect a BGP OPEN message.
2958 static const value_string community_vals
[] = {
2959 { BGP_COMM_NO_EXPORT
, "NO_EXPORT" },
2960 { BGP_COMM_NO_ADVERTISE
, "NO_ADVERTISE" },
2961 { BGP_COMM_NO_EXPORT_SUBCONFED
, "NO_EXPORT_SUBCONFED" },
2966 dissect_bgp_open(tvbuff_t
*tvb
, proto_tree
*tree
, packet_info
*pinfo
)
2968 guint8 optlen
; /* Option Length */
2969 int ptype
; /* parameter type */
2970 int plen
; /* parameter length */
2971 int cend
; /* capabilities end */
2972 int oend
; /* options end */
2973 int offset
; /* tvb offset counter */
2974 proto_item
*ti
; /* tree item */
2975 proto_tree
*opt_tree
; /* subtree for options */
2976 proto_tree
*par_tree
; /* subtree for par options */
2978 offset
= BGP_MARKER_SIZE
+ 2 + 1;
2980 proto_tree_add_item(tree
, hf_bgp_open_version
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2983 proto_tree_add_item(tree
, hf_bgp_open_myas
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2986 proto_tree_add_item(tree
, hf_bgp_open_holdtime
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2989 proto_tree_add_item(tree
, hf_bgp_open_identifier
, tvb
, offset
, 4, ENC_NA
);
2992 proto_tree_add_item(tree
, hf_bgp_open_opt_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2993 optlen
= tvb_get_guint8(tvb
, offset
);
2996 /* optional parameters */
2998 oend
= offset
+ optlen
;
3001 ti
= proto_tree_add_item(tree
, hf_bgp_open_opt_params
, tvb
, offset
, optlen
, ENC_NA
);
3002 opt_tree
= proto_item_add_subtree(ti
, ett_bgp_options
);
3004 /* step through all of the optional parameters */
3005 while (offset
< oend
) {
3008 ti
= proto_tree_add_item(opt_tree
, hf_bgp_open_opt_param
, tvb
, offset
, -1, ENC_NA
);
3009 par_tree
= proto_item_add_subtree(ti
, ett_bgp_options
);
3011 /* display and grab the type ... */
3012 proto_tree_add_item(par_tree
, hf_bgp_open_opt_param_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3013 ptype
= tvb_get_guint8(tvb
, offset
);
3014 proto_item_append_text(ti
, ": %s", val_to_str(ptype
, bgp_open_opt_vals
, "Unknown Parameter %d"));
3017 /* ... and length */
3018 proto_tree_add_item(par_tree
, hf_bgp_open_opt_param_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3019 plen
= tvb_get_guint8(tvb
, offset
);
3020 proto_item_set_len(ti
, plen
+2);
3023 /* check the type */
3025 case BGP_OPTION_AUTHENTICATION
:
3026 proto_tree_add_item(par_tree
, hf_bgp_open_opt_param_auth
, tvb
, offset
, plen
, ENC_NA
);
3029 case BGP_OPTION_CAPABILITY
:
3030 /* grab the capability code */
3031 cend
= offset
+ plen
;
3033 /* step through all of the capabilities */
3034 while (offset
< cend
) {
3035 offset
= dissect_bgp_capability_item(tvb
, par_tree
, pinfo
, offset
, FALSE
);
3039 proto_tree_add_item(opt_tree
, hf_bgp_open_opt_param_unknown
, tvb
, offset
, plen
, ENC_NA
);
3041 } /* switch (ptype) */
3047 * Dissect a BGP UPDATE message.
3050 dissect_bgp_update(tvbuff_t
*tvb
, proto_tree
*tree
, packet_info
*pinfo
)
3052 guint8 bgpa_flags
; /* path attributes */
3054 guint16 hlen
; /* message length */
3055 gint o
; /* packet offset */
3057 gint end
; /* message end */
3058 guint16 ext_com
; /* EXTENDED COMMUNITY extended length type */
3059 guint8 ext_com8
; /* EXTENDED COMMUNITY regular type */
3060 gboolean is_regular_type
; /* flag for regular types */
3061 gboolean is_extended_type
; /* flag for extended types */
3062 guint16 len
; /* tmp */
3063 int advance
; /* tmp */
3064 proto_item
*ti
; /* tree item */
3065 proto_item
*sub_ti
; /* tree fir sub item */
3066 proto_tree
*subtree
; /* subtree for attributes */
3067 proto_tree
*subtree2
; /* subtree for attributes */
3068 proto_tree
*subtree3
; /* subtree for attributes */
3069 proto_tree
*subtree4
; /* subtree for attributes */
3070 proto_tree
*subtree5
; /* subtree for attributes */
3071 proto_tree
*subtree6
; /* subtree for attributes */
3072 proto_tree
*as_paths_tree
; /* subtree for AS_PATHs */
3073 proto_tree
*as_path_tree
; /* subtree for AS_PATH */
3074 proto_tree
*as_path_segment_tree
; /* subtree for AS_PATH segments */
3075 proto_tree
*communities_tree
; /* subtree for COMMUNITIES */
3076 proto_tree
*community_tree
; /* subtree for a community */
3077 proto_tree
*cluster_list_tree
; /* subtree for CLUSTER_LIST */
3079 guint8 length
; /* AS_PATH length */
3080 guint8 type
; /* AS_PATH type */
3081 guint32 as_path_item
; /* item in AS_PATH segment */
3082 wmem_strbuf_t
*as_path_emstr
= NULL
; /* AS_PATH */
3083 wmem_strbuf_t
*communities_emstr
= NULL
; /* COMMUNITIES */
3084 wmem_strbuf_t
*cluster_list_emstr
= NULL
; /* CLUSTER_LIST */
3085 wmem_strbuf_t
*junk_emstr
; /* tmp */
3086 guint32 ipaddr
; /* IPv4 address */
3087 guint32 aggregator_as
;
3088 guint16 ssa_type
; /* SSA T + Type */
3089 guint16 ssa_len
; /* SSA TLV Length */
3090 guint8 ssa_v3_len
; /* SSA L2TPv3 Cookie Length */
3091 gfloat linkband
; /* Link bandwidth */
3092 guint16 as_num
; /* Autonomous System Number */
3093 guint16 encaps_tunnel_type
; /* Encapsulation Tunnel Type */
3094 guint16 encaps_tunnel_len
; /* Encapsulation TLV Length */
3095 guint8 encaps_tunnel_subtype
; /* Encapsulation Tunnel Sub-TLV Type */
3096 guint8 encaps_tunnel_sublen
; /* Encapsulation TLV Sub-TLV Length */
3101 hlen
= tvb_get_ntohs(tvb
, BGP_MARKER_SIZE
);
3102 o
= BGP_HEADER_SIZE
;
3103 junk_emstr
= wmem_strbuf_new_label(wmem_packet_scope());
3105 /* check for withdrawals */
3106 len
= tvb_get_ntohs(tvb
, o
);
3107 proto_tree_add_item(tree
, hf_bgp_update_withdrawn_routes_length
, tvb
, o
, 2, ENC_BIG_ENDIAN
);
3110 /* parse unfeasible prefixes */
3112 ti
= proto_tree_add_item(tree
, hf_bgp_update_withdrawn_routes
, tvb
, o
, len
, ENC_NA
);
3113 subtree
= proto_item_add_subtree(ti
, ett_bgp_unfeas
);
3114 /* parse each prefix */
3117 /* Heuristic to detect if IPv4 prefix are using Path Identifiers */
3118 if( detect_add_path_prefix4(tvb
, o
, end
) ) {
3119 /* IPv4 prefixes with Path Id */
3121 i
= decode_path_prefix4(subtree
, hf_bgp_nlri_path_id
, hf_bgp_withdrawn_prefix
, tvb
, o
,
3129 i
= decode_prefix4(subtree
, NULL
, hf_bgp_withdrawn_prefix
, tvb
, o
, len
,
3138 /* check for advertisements */
3139 len
= tvb_get_ntohs(tvb
, o
);
3140 proto_tree_add_item(tree
, hf_bgp_update_total_path_attribute_length
, tvb
, o
, 2, ENC_BIG_ENDIAN
);
3142 /* path attributes */
3144 ti
= proto_tree_add_item(tree
, hf_bgp_update_path_attributes
, tvb
, o
+2, len
, ENC_NA
);
3145 subtree
= proto_item_add_subtree(ti
, ett_bgp_attrs
);
3148 proto_item
*hidden_item
;
3149 proto_item
*ti_pa
, *ti_flags
;
3150 proto_tree
*flags_tree
;
3153 guint16 alen
, tlen
, aoff
, aoff_save
;
3159 bgpa_flags
= tvb_get_guint8(tvb
, o
+ i
);
3160 bgpa_type
= tvb_get_guint8(tvb
, o
+ i
+1);
3162 /* check for the Extended Length bit */
3163 if (bgpa_flags
& BGP_ATTR_FLAG_EXTENDED_LENGTH
) {
3164 alen
= tvb_get_ntohs(tvb
, o
+ i
+ BGP_SIZE_OF_PATH_ATTRIBUTE
);
3165 aoff
= BGP_SIZE_OF_PATH_ATTRIBUTE
+2;
3167 alen
= tvb_get_guint8(tvb
, o
+ i
+ BGP_SIZE_OF_PATH_ATTRIBUTE
);
3168 aoff
= BGP_SIZE_OF_PATH_ATTRIBUTE
+1;
3173 ti_pa
= proto_tree_add_item(subtree
, hf_bgp_update_path_attribute
, tvb
, o
+ i
, tlen
+ aoff
, ENC_NA
);
3174 proto_item_append_text(ti_pa
, " - %s", val_to_str_const(bgpa_type
, bgpattr_type
, "Unknown %d"));
3176 subtree2
= proto_item_add_subtree(ti_pa
, ett_bgp_attr
);
3178 ti_flags
= proto_tree_add_item(subtree2
, hf_bgp_update_path_attribute_flags
, tvb
, o
+ i
, 1, ENC_NA
);
3179 flags_tree
= proto_item_add_subtree(ti_flags
, ett_bgp_attr_flags
);
3181 /* add flag bitfield subtrees */
3182 proto_tree_add_item(flags_tree
, hf_bgp_update_path_attribute_flags_optional
, tvb
, o
+ i
, 1, ENC_BIG_ENDIAN
);
3183 proto_tree_add_item(flags_tree
, hf_bgp_update_path_attribute_flags_transitive
, tvb
, o
+ i
, 1, ENC_BIG_ENDIAN
);
3184 proto_tree_add_item(flags_tree
, hf_bgp_update_path_attribute_flags_partial
, tvb
, o
+ i
, 1, ENC_BIG_ENDIAN
);
3185 proto_tree_add_item(flags_tree
, hf_bgp_update_path_attribute_flags_extended_length
, tvb
, o
+ i
, 1, ENC_BIG_ENDIAN
);
3186 proto_item_append_text(ti_flags
,"%s%s%s%s",
3187 ((bgpa_flags
& BGP_ATTR_FLAG_OPTIONAL
) == 0) ? ": Well-known" : ": Optional",
3188 ((bgpa_flags
& BGP_ATTR_FLAG_TRANSITIVE
) == 0) ? ", Non-transitive" : ", Transitive",
3189 ((bgpa_flags
& BGP_ATTR_FLAG_PARTIAL
) == 0) ? ", Complete" : ", Partial",
3190 ((bgpa_flags
& BGP_ATTR_FLAG_EXTENDED_LENGTH
) == 0) ? "" : ", Extended Length");
3192 proto_tree_add_item(subtree2
, hf_bgp_update_path_attribute_type_code
, tvb
, o
+ i
+ 1, 1, ENC_BIG_ENDIAN
);
3194 proto_tree_add_item(subtree2
, hf_bgp_update_path_attribute_length
, tvb
, o
+ i
+ BGP_SIZE_OF_PATH_ATTRIBUTE
, aoff
- BGP_SIZE_OF_PATH_ATTRIBUTE
, ENC_BIG_ENDIAN
);
3196 /* Path Attribute Type */
3197 switch (bgpa_type
) {
3198 case BGPTYPE_ORIGIN
:
3200 proto_tree_add_text(subtree2
, tvb
, o
+ i
+ aoff
, tlen
,
3201 "Origin (invalid): %u byte%s", tlen
,
3202 plurality(tlen
, "", "s"));
3204 proto_tree_add_item(subtree2
, hf_bgp_update_path_attribute_origin
, tvb
,
3205 o
+ i
+ aoff
, 1, ENC_BIG_ENDIAN
);
3206 proto_item_append_text(ti_pa
, ": %s", val_to_str_const(tvb_get_guint8(tvb
, o
+ i
+ aoff
), bgpattr_origin
, "Unknown"));
3209 case BGPTYPE_AS_PATH
:
3210 case BGPTYPE_NEW_AS_PATH
:
3212 (o + current attribute + aoff bytes to first tuple) */
3215 /* must be freed by second switch! */
3216 /* "tlen * 11" (10 digits + space) should be a good estimate
3217 of how long the AS path string could be */
3218 if (as_path_emstr
== NULL
)
3219 as_path_emstr
= wmem_strbuf_sized_new(wmem_packet_scope(), (tlen
+ 1) * 11, 0);
3220 wmem_strbuf_truncate(as_path_emstr
, 0);
3222 /* estimate the length of the AS number */
3223 if (bgpa_type
== BGPTYPE_NEW_AS_PATH
)
3226 if (bgp_asn_len
== 0) {
3227 guint unknown_segment_type
= 0;
3228 guint asn_is_null
= 0;
3232 while ((k
< end
) && !unknown_segment_type
&& !asn_is_null
)
3234 type
= tvb_get_guint8(tvb
, k
++);
3236 /* type of segment is unknown */
3237 if (type
!= AS_SET
&&
3238 type
!= AS_SEQUENCE
&&
3239 type
!= AS_CONFED_SEQUENCE
&&
3240 type
!= AS_CONFED_SEQUENCE
)
3241 unknown_segment_type
= 1;
3243 length
= tvb_get_guint8(tvb
, k
++);
3245 /* Check for invalid ASN */
3246 for (d
= 0; d
< length
&& !unknown_segment_type
&& !asn_is_null
; d
++)
3248 if(tvb_get_ntohs(tvb
, k
) == 0)
3253 if(k
!= end
|| unknown_segment_type
|| asn_is_null
)
3257 asn_len
= bgp_asn_len
;
3261 /* snarf each AS path */
3263 const gchar
*str
= wmem_strbuf_get_str(as_path_emstr
);
3264 type
= tvb_get_guint8(tvb
, q
++);
3265 if (wmem_strbuf_get_len(as_path_emstr
) > 1 &&
3266 str
[wmem_strbuf_get_len(as_path_emstr
) - 1] != ' ')
3267 wmem_strbuf_append_c(as_path_emstr
, ' ');
3268 if (type
== AS_SET
) {
3269 wmem_strbuf_append_c(as_path_emstr
, '{');
3271 else if (type
== AS_CONFED_SET
) {
3272 wmem_strbuf_append_c(as_path_emstr
, '[');
3274 else if (type
== AS_CONFED_SEQUENCE
) {
3275 wmem_strbuf_append_c(as_path_emstr
, '(');
3277 length
= tvb_get_guint8(tvb
, q
++);
3279 /* snarf each value in path */
3280 for (j
= 0; j
< length
; j
++) {
3281 wmem_strbuf_append_printf(as_path_emstr
, "%u%s",
3283 tvb_get_ntohs(tvb
, q
) : tvb_get_ntohl(tvb
, q
),
3284 (type
== AS_SET
|| type
== AS_CONFED_SET
) ?
3289 /* cleanup end of string */
3290 if (type
== AS_SET
) {
3291 wmem_strbuf_truncate(as_path_emstr
, wmem_strbuf_get_len(as_path_emstr
) - 2);
3292 wmem_strbuf_append_c(as_path_emstr
, '}');
3294 else if (type
== AS_CONFED_SET
) {
3295 wmem_strbuf_truncate(as_path_emstr
, wmem_strbuf_get_len(as_path_emstr
) - 2);
3296 wmem_strbuf_append_c(as_path_emstr
, ']');
3298 else if (type
== AS_CONFED_SEQUENCE
) {
3299 wmem_strbuf_truncate(as_path_emstr
, wmem_strbuf_get_len(as_path_emstr
) - 1);
3300 wmem_strbuf_append_c(as_path_emstr
, ')');
3303 wmem_strbuf_truncate(as_path_emstr
, wmem_strbuf_get_len(as_path_emstr
) - 1);
3307 /* check for empty AS_PATH */
3309 wmem_strbuf_truncate(as_path_emstr
, 0);
3310 wmem_strbuf_append_printf(as_path_emstr
, "empty");
3313 proto_item_append_text(ti_pa
, ": %s", wmem_strbuf_get_str(as_path_emstr
));
3315 ti
= proto_tree_add_text(subtree2
, tvb
, o
+ i
+ aoff
, tlen
,
3316 "AS path: %s", wmem_strbuf_get_str(as_path_emstr
));
3317 as_paths_tree
= proto_item_add_subtree(ti
, ett_bgp_as_paths
);
3320 (o + current attribute + aoff bytes to first tuple) */
3324 /* snarf each AS path tuple, we have to step through each one
3325 again to make a separate subtree so we can't just reuse
3326 as_path_gstr from above */
3327 /* XXX - Can we use some g_string*() trickery instead, e.g.
3328 g_string_erase()? */
3330 wmem_strbuf_truncate(as_path_emstr
, 0);
3331 type
= tvb_get_guint8(tvb
, q
++);
3332 if (type
== AS_SET
) {
3333 wmem_strbuf_append_c(as_path_emstr
, '{');
3335 else if (type
== AS_CONFED_SET
) {
3336 wmem_strbuf_append_c(as_path_emstr
, '[');
3338 else if (type
== AS_CONFED_SEQUENCE
) {
3339 wmem_strbuf_append_c(as_path_emstr
, '(');
3341 length
= tvb_get_guint8(tvb
, q
++);
3343 /* snarf each value in path */
3344 for (j
= 0; j
< length
; j
++) {
3345 wmem_strbuf_append_printf(as_path_emstr
, "%u%s",
3347 tvb_get_ntohs(tvb
, q
) : tvb_get_ntohl(tvb
, q
),
3348 (type
== AS_SET
|| type
== AS_CONFED_SET
) ? ", " : " ");
3352 /* cleanup end of string */
3353 if (type
== AS_SET
) {
3354 wmem_strbuf_truncate(as_path_emstr
, wmem_strbuf_get_len(as_path_emstr
) - 2);
3355 wmem_strbuf_append_c(as_path_emstr
, '}');
3357 else if (type
== AS_CONFED_SET
) {
3358 wmem_strbuf_truncate(as_path_emstr
, wmem_strbuf_get_len(as_path_emstr
) - 2);
3359 wmem_strbuf_append_c(as_path_emstr
, ']');
3361 else if (type
== AS_CONFED_SEQUENCE
) {
3362 wmem_strbuf_truncate(as_path_emstr
, wmem_strbuf_get_len(as_path_emstr
) - 1);
3363 wmem_strbuf_append_c(as_path_emstr
, ')');
3366 wmem_strbuf_truncate(as_path_emstr
, wmem_strbuf_get_len(as_path_emstr
) - 1);
3369 /* length here means number of ASs, ie length * 2 bytes */
3370 ti
= proto_tree_add_text(as_paths_tree
, tvb
,
3371 q
- length
* asn_len
- 2,
3372 length
* asn_len
+ 2, "AS path segment: %s",
3373 wmem_strbuf_get_str(as_path_emstr
));
3374 as_path_tree
= proto_item_add_subtree(ti
, ett_bgp_as_paths
);
3375 proto_tree_add_text(as_path_tree
, tvb
, q
- length
* asn_len
- 2,
3376 1, "Path segment type: %s (%u)",
3377 val_to_str_const(type
, as_segment_type
, "Unknown"), type
);
3378 proto_tree_add_text(as_path_tree
, tvb
, q
- length
* asn_len
- 1,
3379 1, "Path segment length: %u AS%s", length
,
3380 plurality(length
, "", "s"));
3382 /* backup and reprint path segment value(s) only */
3383 q
-= asn_len
* length
;
3384 ti
= proto_tree_add_text(as_path_tree
, tvb
, q
,
3385 length
* asn_len
, "Path segment value:");
3386 as_path_segment_tree
= proto_item_add_subtree(ti
,
3387 ett_bgp_as_path_segments
);
3388 for (j
= 0; j
< length
; j
++) {
3389 as_path_item
= (asn_len
== 2) ?
3390 tvb_get_ntohs(tvb
, q
) : tvb_get_ntohl(tvb
, q
);
3391 proto_item_append_text(ti
, " %u", as_path_item
);
3392 hidden_item
= proto_tree_add_uint(as_path_segment_tree
, hf_bgp_update_path_attribute_as_path
, tvb
,
3393 q
, asn_len
, as_path_item
);
3394 PROTO_ITEM_SET_HIDDEN(hidden_item
);
3400 case BGPTYPE_NEXT_HOP
:
3402 proto_tree_add_text(subtree2
, tvb
, o
+ i
+ aoff
, tlen
,
3403 "Next hop (invalid): %u byte%s", tlen
,
3404 plurality(tlen
, "", "s"));
3406 proto_tree_add_item(subtree2
, hf_bgp_update_path_attribute_next_hop
, tvb
,
3407 o
+ i
+ aoff
, 4, ENC_BIG_ENDIAN
);
3408 proto_item_append_text(ti_pa
, ": %s ", tvb_ip_to_str(tvb
, o
+ i
+ aoff
));
3411 case BGPTYPE_MULTI_EXIT_DISC
:
3413 proto_tree_add_text(subtree2
, tvb
, o
+ i
+ aoff
, tlen
,
3414 "Multiple exit discriminator (invalid): %u byte%s",
3415 tlen
, plurality(tlen
, "", "s"));
3417 proto_tree_add_item(subtree2
, hf_bgp_update_path_attribute_multi_exit_disc
, tvb
,
3418 o
+ i
+ aoff
, tlen
, ENC_BIG_ENDIAN
);
3419 proto_item_append_text(ti_pa
,": %u", tvb_get_ntohl(tvb
, o
+ i
+ aoff
));
3422 case BGPTYPE_LOCAL_PREF
:
3424 proto_tree_add_text(subtree2
, tvb
, o
+ i
+ aoff
, tlen
,
3425 "Local preference (invalid): %u byte%s", tlen
,
3426 plurality(tlen
, "", "s"));
3428 proto_tree_add_item(subtree2
, hf_bgp_update_path_attribute_local_pref
, tvb
,
3429 o
+ i
+ aoff
, tlen
, ENC_BIG_ENDIAN
);
3430 proto_item_append_text(ti_pa
, ": %u", tvb_get_ntohl(tvb
, o
+ i
+ aoff
));
3433 case BGPTYPE_ATOMIC_AGGREGATE
:
3435 proto_tree_add_text(subtree2
, tvb
, o
+ i
+ aoff
, tlen
,
3436 "Atomic aggregate (invalid): %u byte%s", tlen
,
3437 plurality(tlen
, "", "s"));
3440 case BGPTYPE_AGGREGATOR
:
3441 if (tlen
!= 6 && tlen
!= 8) {
3442 proto_tree_add_text(subtree2
, tvb
, o
+ i
+ aoff
, tlen
,
3443 "Aggregator (invalid): %u byte%s", tlen
,
3444 plurality(tlen
, "", "s"));
3447 case BGPTYPE_NEW_AGGREGATOR
:
3448 if (bgpa_type
== BGPTYPE_NEW_AGGREGATOR
&& tlen
!= 8)
3449 proto_tree_add_text(subtree2
, tvb
, o
+ i
+ aoff
, tlen
,
3450 "Aggregator (invalid): %u byte%s", tlen
,
3451 plurality(tlen
, "", "s"));
3455 aggregator_as
= (asn_len
== 2) ?
3456 tvb_get_ntohs(tvb
, o
+ i
+ aoff
) :
3457 tvb_get_ntohl(tvb
, o
+ i
+ aoff
);
3458 proto_tree_add_uint(subtree2
, hf_bgp_update_path_attribute_aggregator_as
, tvb
,
3459 o
+ i
+ aoff
, asn_len
, aggregator_as
);
3460 proto_tree_add_item(subtree2
, hf_bgp_update_path_attribute_aggregator_origin
, tvb
,
3461 o
+ i
+ aoff
+ asn_len
, 4, ENC_BIG_ENDIAN
);
3463 proto_item_append_text(ti_pa
, ": AS: %u origin: %s", aggregator_as
,
3464 tvb_ip_to_str(tvb
, o
+ i
+ aoff
+ asn_len
));
3467 case BGPTYPE_COMMUNITIES
:
3468 if (tlen
% 4 != 0) {
3469 proto_tree_add_text(subtree2
, tvb
, o
+ i
+ aoff
, tlen
,
3470 "Communities (invalid): %u byte%s", tlen
,
3471 plurality(tlen
, "", "s"));
3476 (o + current attribute + aoff bytes to first tuple) */
3479 /* must be freed by second switch! */
3480 /* "tlen * 12" (5 digits, a :, 5 digits + space ) should be
3481 a good estimate of how long the communities string could
3483 if (communities_emstr
== NULL
)
3484 communities_emstr
= wmem_strbuf_sized_new(wmem_packet_scope(), (tlen
+ 1) * 12, 0);
3485 wmem_strbuf_truncate(communities_emstr
, 0);
3487 /* snarf each community */
3489 /* check for well-known communities */
3490 if (tvb_get_ntohl(tvb
, q
) == BGP_COMM_NO_EXPORT
)
3491 wmem_strbuf_append(communities_emstr
, "NO_EXPORT ");
3492 else if (tvb_get_ntohl(tvb
, q
) == BGP_COMM_NO_ADVERTISE
)
3493 wmem_strbuf_append(communities_emstr
, "NO_ADVERTISE ");
3494 else if (tvb_get_ntohl(tvb
, q
) == BGP_COMM_NO_EXPORT_SUBCONFED
)
3495 wmem_strbuf_append(communities_emstr
, "NO_EXPORT_SUBCONFED ");
3497 wmem_strbuf_append_printf(communities_emstr
, "%u:%u ",
3498 tvb_get_ntohs(tvb
, q
),
3499 tvb_get_ntohs(tvb
, q
+ 2));
3503 /* cleanup end of string */
3504 wmem_strbuf_truncate(communities_emstr
, wmem_strbuf_get_len(communities_emstr
) - 1);
3506 proto_item_append_text(ti_pa
,": %s", wmem_strbuf_get_str(communities_emstr
));
3508 ti
= proto_tree_add_text(subtree2
, tvb
, o
+ i
+ aoff
, tlen
,
3509 "Communities: %s", communities_emstr
?
3510 wmem_strbuf_get_str(communities_emstr
) : "<none>");
3511 communities_tree
= proto_item_add_subtree(ti
,
3512 ett_bgp_communities
);
3515 (o + current attribute + aoff bytes to first tuple) */
3519 /* snarf each community */
3521 /* check for reserved values */
3522 guint32 community
= tvb_get_ntohl(tvb
, q
);
3523 if ((community
& 0xFFFF0000) == FOURHEX0
||
3524 (community
& 0xFFFF0000) == FOURHEXF
) {
3525 proto_tree_add_text(communities_tree
, tvb
,
3527 "Community: %s (0x%08x)",
3528 val_to_str_const(community
, community_vals
, "(reserved)"),
3532 ti
= proto_tree_add_text(communities_tree
, tvb
,
3533 q
- 3 + aoff
, 4, "Community: %u:%u",
3534 tvb_get_ntohs(tvb
, q
), tvb_get_ntohs(tvb
, q
+ 2));
3535 community_tree
= proto_item_add_subtree(ti
,
3536 ett_bgp_communities
);
3537 proto_tree_add_item(community_tree
, hf_bgp_update_community_as
,
3538 tvb
, q
- 3 + aoff
, 2, ENC_BIG_ENDIAN
);
3539 proto_tree_add_item(community_tree
, hf_bgp_update_path_attribute_community_value
,
3540 tvb
, q
- 1 + aoff
, 2, ENC_BIG_ENDIAN
);
3547 case BGPTYPE_ORIGINATOR_ID
:
3549 proto_tree_add_text(subtree2
, tvb
, o
+ i
+ aoff
, tlen
,
3550 "Originator identifier (invalid): %u byte%s", tlen
,
3551 plurality(tlen
, "", "s"));
3553 proto_tree_add_item(subtree2
, hf_bgp_update_path_attribute_originator_id
, tvb
,
3554 o
+ i
+ aoff
, tlen
, ENC_BIG_ENDIAN
);
3555 proto_item_append_text(ti_pa
, ": %s ", tvb_ip_to_str(tvb
, o
+ i
+ aoff
));
3558 case BGPTYPE_MP_REACH_NLRI
:
3560 * RFC 2545 specifies that there may be more than one
3561 * address in the MP_REACH_NLRI attribute in section
3562 * 3, "Constructing the Next Hop field".
3564 * Yes, RFC 2858 says you can't do that, and, yes, RFC
3565 * 2858 obsoletes RFC 2283, which says you can do that,
3566 * but that doesn't mean we shouldn't dissect packets
3567 * that conform to RFC 2283 but not RFC 2858, as some
3568 * device on the network might implement the 2283-style
3569 * BGP extensions rather than RFC 2858-style extensions.
3571 af
= tvb_get_ntohs(tvb
, o
+ i
+ aoff
);
3572 proto_tree_add_text(subtree2
, tvb
, o
+ i
+ aoff
, 2,
3573 "Address family: %s (%u)",
3574 val_to_str_const(af
, afn_vals
, "Unknown"), af
);
3575 saf
= tvb_get_guint8(tvb
, o
+ i
+ aoff
+ 2) ;
3576 proto_tree_add_text(subtree2
, tvb
, o
+ i
+ aoff
+ 2, 1,
3577 "Subsequent address family identifier: %s (%u)",
3578 val_to_str_const(saf
, bgpattr_nlri_safi
, saf
>= 134 ? "Vendor specific" : "Unknown"),
3580 nexthop_len
= tvb_get_guint8(tvb
, o
+ i
+ aoff
+ 3);
3581 ti
= proto_tree_add_text(subtree2
, tvb
, o
+ i
+ aoff
+ 3,
3583 "Next hop network address (%d byte%s)",
3584 nexthop_len
, plurality(nexthop_len
, "", "s"));
3585 subtree3
= proto_item_add_subtree(ti
, ett_bgp_mp_nhna
);
3588 * The addresses don't contain lengths, so if we
3589 * don't understand the address family type, we
3590 * cannot parse the subsequent addresses as we
3591 * don't know how long they are.
3595 proto_tree_add_text(subtree3
, tvb
, o
+ i
+ aoff
+ 4,
3596 nexthop_len
, "Unknown Address Family");
3602 case AFNUM_L2VPN_OLD
:
3605 while (j
< nexthop_len
) {
3606 advance
= mp_addr_to_str(af
, saf
, tvb
, o
+ i
+ aoff
+ 4 + j
,
3607 junk_emstr
, nexthop_len
) ;
3608 if (advance
== 0) /* catch if this is a unknown AFI type*/
3610 if (j
+ advance
> nexthop_len
)
3612 proto_tree_add_text(subtree3
, tvb
,o
+ i
+ aoff
+ 4 + j
,
3613 advance
, "Next hop: %s (%u)",
3614 wmem_strbuf_get_str(junk_emstr
), advance
);
3621 tlen
-= nexthop_len
+ 4;
3622 aoff
+= nexthop_len
+ 4 ;
3625 snpa
= tvb_get_guint8(tvb
, o
+ i
+ aoff
);
3626 ti
= proto_tree_add_text(subtree2
, tvb
, o
+ i
+ aoff
, 1,
3627 "Subnetwork points of attachment: %u", snpa
);
3630 subtree3
= proto_item_add_subtree(ti
, ett_bgp_mp_snpa
);
3631 for (/*nothing*/; snpa
> 0; snpa
--) {
3632 proto_tree_add_text(subtree3
, tvb
, o
+ i
+ aoff
+ off
, 1,
3633 "SNPA length: %u", tvb_get_guint8(tvb
, o
+ i
+ aoff
+ off
));
3635 proto_tree_add_text(subtree3
, tvb
, o
+ i
+ aoff
+ off
,
3636 tvb_get_guint8(tvb
, o
+ i
+ aoff
+ off
- 1),
3637 "SNPA (%u byte%s)", tvb_get_guint8(tvb
, o
+ i
+ aoff
+ off
- 1),
3638 plurality(tvb_get_guint8(tvb
, o
+ i
+ aoff
+ off
- 1), "", "s"));
3639 off
+= tvb_get_guint8(tvb
, o
+ i
+ aoff
+ off
- 1);
3645 ti
= proto_tree_add_text(subtree2
, tvb
, o
+ i
+ aoff
, tlen
,
3646 "Network layer reachability information (%u byte%s)",
3647 tlen
, plurality(tlen
, "", "s"));
3649 subtree3
= proto_item_add_subtree(ti
,ett_bgp_mp_reach_nlri
);
3650 if (af
!= AFNUM_INET
&& af
!= AFNUM_INET6
&& af
!= AFNUM_L2VPN
) {
3651 proto_tree_add_text(subtree3
, tvb
, o
+ i
+ aoff
,
3652 tlen
, "Unknown Address Family");
3655 advance
= decode_prefix_MP(subtree3
,
3656 hf_bgp_mp_reach_nlri_ipv4_prefix
,
3659 tvb
, o
+ i
+ aoff
, "MP Reach NLRI", pinfo
);
3669 case BGPTYPE_MP_UNREACH_NLRI
:
3670 af
= tvb_get_ntohs(tvb
, o
+ i
+ aoff
);
3671 proto_tree_add_text(subtree2
, tvb
, o
+ i
+ aoff
, 2,
3672 "Address family: %s (%u)",
3673 val_to_str_const(af
, afn_vals
, "Unknown"), af
);
3674 saf
= tvb_get_guint8(tvb
, o
+ i
+ aoff
+ 2) ;
3675 proto_tree_add_text(subtree2
, tvb
, o
+ i
+ aoff
+ 2, 1,
3676 "Subsequent address family identifier: %s (%u)",
3677 val_to_str_const(saf
, bgpattr_nlri_safi
, saf
>= 134 ? "Vendor specific" : "Unknown"),
3679 ti
= proto_tree_add_text(subtree2
, tvb
, o
+ i
+ aoff
+ 3,
3680 tlen
- 3, "Withdrawn routes (%u byte%s)", tlen
- 3,
3681 plurality(tlen
- 3, "", "s"));
3687 subtree3
= proto_item_add_subtree(ti
,ett_bgp_mp_unreach_nlri
);
3690 advance
= decode_prefix_MP(subtree3
,
3691 hf_bgp_mp_unreach_nlri_ipv4_prefix
,
3694 tvb
, o
+ i
+ aoff
, "MP Unreach NLRI", pinfo
);
3703 case BGPTYPE_CLUSTER_LIST
:
3704 if (tlen
% 4 != 0) {
3705 proto_tree_add_text(subtree2
, tvb
, o
+ i
+ aoff
, tlen
,
3706 "Cluster list (invalid): %u byte%s", tlen
,
3707 plurality(tlen
, "", "s"));
3712 (o + current attribute + aoff bytes to first tuple) */
3715 /* must be freed by second switch! */
3716 /* "tlen * 16" (12 digits, 3 dots + space ) should be
3717 a good estimate of how long the cluster_list string could
3719 if (cluster_list_emstr
== NULL
)
3720 cluster_list_emstr
= wmem_strbuf_sized_new(wmem_packet_scope(), (tlen
+ 1) * 16, 0);
3721 wmem_strbuf_truncate(cluster_list_emstr
, 0);
3723 /* snarf each cluster list */
3725 wmem_strbuf_append_printf(cluster_list_emstr
, "%s ", tvb_ip_to_str(tvb
, q
));
3728 /* cleanup end of string */
3729 wmem_strbuf_truncate(cluster_list_emstr
, wmem_strbuf_get_len(cluster_list_emstr
) - 1);
3731 proto_item_append_text(ti_pa
, ": %s", wmem_strbuf_get_str(cluster_list_emstr
));
3733 ti
= proto_tree_add_text(subtree2
, tvb
, o
+ i
+ aoff
, tlen
,
3734 "Cluster list: %s", cluster_list_emstr
?
3735 wmem_strbuf_get_str(cluster_list_emstr
) : "<none>");
3736 cluster_list_tree
= proto_item_add_subtree(ti
,
3737 ett_bgp_cluster_list
);
3740 (o + current attribute + aoff bytes to first tuple) */
3744 /* snarf each cluster identifier */
3746 proto_tree_add_item(cluster_list_tree
, hf_bgp_update_path_attribute_cluster_list
,
3747 tvb
, q
- 3 + aoff
, 4, ENC_NA
);
3752 case BGPTYPE_EXTENDED_COMMUNITY
:
3754 proto_tree_add_text(subtree2
, tvb
, o
+ i
+ aoff
, tlen
, "Extended community (invalid) : %u byte%s", tlen
,
3755 plurality(tlen
, "", "s"));
3758 end
= o
+ i
+ aoff
+ tlen
;
3759 ti
= proto_tree_add_text(subtree2
,tvb
,q
,tlen
, "Carried Extended communities");
3760 subtree3
= proto_item_add_subtree(ti
,ett_bgp_extended_communities
);
3763 ext_com8
= tvb_get_guint8(tvb
,q
); /* handle regular types (8 bit) */
3764 ext_com
= tvb_get_ntohs(tvb
,q
); /* handle extended length types (16 bit) */
3765 wmem_strbuf_truncate(junk_emstr
, 0);
3766 wmem_strbuf_append_printf(junk_emstr
, "%s", val_to_str(ext_com8
,bgpext_com8_type
,"Unknown %d"));
3767 is_regular_type
= FALSE
;
3768 is_extended_type
= FALSE
;
3769 /* handle regular types (8 bit) */
3771 case BGP_EXT_COM_QOS_MARK_T
:
3772 case BGP_EXT_COM_QOS_MARK_NT
:
3773 is_regular_type
= TRUE
;
3774 ti
= proto_tree_add_text(subtree3
,tvb
,q
,8, "%s", wmem_strbuf_get_str(junk_emstr
));
3776 subtree4
= proto_item_add_subtree(ti
,ett_bgp_extended_communities
);
3777 proto_tree_add_text(subtree4
, tvb
, q
, 1,
3778 "Type: 0x%02x", tvb_get_guint8(tvb
,q
));
3779 ti
= proto_tree_add_item(subtree4
, hf_bgp_ext_com_qos_flags
, tvb
, q
+1, 1, ENC_BIG_ENDIAN
);
3780 subtree5
= proto_item_add_subtree(ti
,ett_bgp_ext_com_flags
);
3781 /* add flag bitfield */
3782 proto_tree_add_item(subtree5
, hf_bgp_ext_com_qos_flags_remarking
, tvb
, q
+1, 1, ENC_BIG_ENDIAN
);
3783 proto_tree_add_item(subtree5
, hf_bgp_ext_com_qos_flags_ignore_remarking
, tvb
, q
+1, 1, ENC_BIG_ENDIAN
);
3784 proto_tree_add_item(subtree5
, hf_bgp_ext_com_qos_flags_agg_marking
, tvb
, q
+1, 1, ENC_BIG_ENDIAN
);
3786 proto_tree_add_item(subtree4
, hf_bgp_ext_com_qos_set_number
, tvb
, q
+2, 1, ENC_BIG_ENDIAN
);
3787 proto_tree_add_item(subtree4
, hf_bgp_ext_com_qos_tech_type
, tvb
, q
+3, 1, ENC_BIG_ENDIAN
);
3788 proto_tree_add_item(subtree4
, hf_bgp_ext_com_qos_marking_o
, tvb
, q
+4, 2, ENC_BIG_ENDIAN
);
3789 proto_tree_add_item(subtree4
, hf_bgp_ext_com_qos_marking_a
, tvb
, q
+6, 1, ENC_BIG_ENDIAN
);
3790 proto_tree_add_item(subtree4
, hf_bgp_ext_com_qos_default_to_zero
, tvb
, q
+7, 1, ENC_BIG_ENDIAN
);
3792 case BGP_EXT_COM_COS_CAP_T
:
3793 is_regular_type
= TRUE
;
3794 ti
= proto_tree_add_text(subtree3
,tvb
,q
,8, "%s", wmem_strbuf_get_str(junk_emstr
));
3796 subtree4
= proto_item_add_subtree(ti
,ett_bgp_extended_communities
);
3797 proto_tree_add_text(subtree4
, tvb
, q
, 1,
3798 "Type: 0x%02x", tvb_get_guint8(tvb
,q
));
3799 ti
= proto_tree_add_item(subtree4
, hf_bgp_ext_com_cos_flags
, tvb
, q
+1, 1, ENC_BIG_ENDIAN
);
3800 subtree5
= proto_item_add_subtree(ti
,ett_bgp_ext_com_flags
);
3801 /* add flag bitfield */
3802 proto_tree_add_item(subtree5
, hf_bgp_ext_com_cos_flags_be
, tvb
, q
+1, 1, ENC_BIG_ENDIAN
);
3803 proto_tree_add_item(subtree5
, hf_bgp_ext_com_cos_flags_ef
, tvb
, q
+1, 1, ENC_BIG_ENDIAN
);
3804 proto_tree_add_item(subtree5
, hf_bgp_ext_com_cos_flags_af
, tvb
, q
+1, 1, ENC_BIG_ENDIAN
);
3805 proto_tree_add_item(subtree5
, hf_bgp_ext_com_cos_flags_le
, tvb
, q
+1, 1, ENC_BIG_ENDIAN
);
3806 proto_tree_add_text(subtree4
, tvb
, q
+2, 1,
3807 "Flags byte 2..7 : 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
3808 tvb_get_guint8(tvb
,q
+2),tvb_get_guint8(tvb
,q
+3),tvb_get_guint8(tvb
,q
+4),
3809 tvb_get_guint8(tvb
,q
+5),tvb_get_guint8(tvb
,q
+6),tvb_get_guint8(tvb
,q
+7));
3811 } /* switch (ext_com8) */
3813 if (!is_regular_type
) {
3814 wmem_strbuf_truncate(junk_emstr
, 0);
3815 wmem_strbuf_append_printf(junk_emstr
, "%s", val_to_str(ext_com
,bgpext_com_type
,"Unknown %d"));
3817 /* handle extended length types (16 bit) */
3819 case BGP_EXT_COM_RT_0
:
3820 case BGP_EXT_COM_RO_0
:
3821 is_extended_type
= TRUE
;
3822 wmem_strbuf_append_printf(junk_emstr
, ": %u%s%d",
3823 tvb_get_ntohs(tvb
,q
+2),":",tvb_get_ntohl(tvb
,q
+4));
3824 proto_tree_add_text(subtree3
,tvb
,q
,8, "%s", wmem_strbuf_get_str(junk_emstr
));
3826 case BGP_EXT_COM_RT_1
:
3827 case BGP_EXT_COM_RO_1
:
3828 is_extended_type
= TRUE
;
3829 ipaddr
= tvb_get_ipv4(tvb
,q
+2);
3830 wmem_strbuf_append_printf(junk_emstr
, ": %s%s%u",
3831 ip_to_str((guint8
*)&ipaddr
),":",tvb_get_ntohs(tvb
,q
+6));
3832 proto_tree_add_text(subtree3
,tvb
,q
,8, "%s", wmem_strbuf_get_str(junk_emstr
));
3834 case BGP_EXT_COM_RT_2
:
3835 case BGP_EXT_COM_RO_2
:
3836 is_extended_type
= TRUE
;
3837 wmem_strbuf_append_printf(junk_emstr
, ": %u.%u:%u",
3838 tvb_get_ntohs(tvb
,q
+2),tvb_get_ntohs(tvb
,q
+4) ,tvb_get_ntohs(tvb
,q
+6));
3839 proto_tree_add_text(subtree3
,tvb
,q
,8, "%s", wmem_strbuf_get_str(junk_emstr
));
3841 case BGP_EXT_COM_VPN_ORIGIN
:
3842 case BGP_EXT_COM_OSPF_RID
:
3843 is_extended_type
= TRUE
;
3844 ipaddr
= tvb_get_ipv4(tvb
,q
+2);
3845 wmem_strbuf_append_printf(junk_emstr
, ": %s", ip_to_str((guint8
*)&ipaddr
));
3846 proto_tree_add_text(subtree3
,tvb
,q
,8, "%s", wmem_strbuf_get_str(junk_emstr
));
3848 case BGP_EXT_COM_OSPF_RTYPE
:
3849 is_extended_type
= TRUE
;
3850 ipaddr
= tvb_get_ipv4(tvb
,q
+2);
3851 wmem_strbuf_append_printf(junk_emstr
, ": Area: %s, Type: %s", ip_to_str((guint8
*)&ipaddr
),
3852 val_to_str_const(tvb_get_guint8(tvb
,q
+6),bgpext_ospf_rtype
,"Unknown"));
3853 /* print OSPF Metric type if selected */
3854 /* always print E2 even if not external route -- receiving router should ignore */
3855 if ( (tvb_get_guint8(tvb
,q
+7)) & BGP_OSPF_RTYPE_METRIC_TYPE
) {
3856 wmem_strbuf_append(junk_emstr
, " E2");
3857 } else if ((tvb_get_guint8(tvb
,q
+6)==BGP_OSPF_RTYPE_EXT
) || (tvb_get_guint8(tvb
,q
+6)==BGP_OSPF_RTYPE_NSSA
)) {
3858 wmem_strbuf_append(junk_emstr
, " E1");
3860 wmem_strbuf_append(junk_emstr
, ", no options");
3862 proto_tree_add_text(subtree3
,tvb
,q
,8, "%s", wmem_strbuf_get_str(junk_emstr
));
3864 case BGP_EXT_COM_LINKBAND
:
3865 is_extended_type
= TRUE
;
3866 as_num
= tvb_get_ntohs(tvb
,q
+2);
3867 linkband
= tvb_get_ntohieee_float(tvb
,q
+4);
3868 wmem_strbuf_append_printf(junk_emstr
, ": ASN %u, %.3f Mbps", as_num
,linkband
*8/1000000);
3869 proto_tree_add_text(subtree3
,tvb
,q
,8, "%s", wmem_strbuf_get_str(junk_emstr
));
3871 case BGP_EXT_COM_L2INFO
:
3872 is_extended_type
= TRUE
;
3873 ti
= proto_tree_add_text(subtree3
,tvb
,q
,8, "%s", wmem_strbuf_get_str(junk_emstr
));
3875 subtree4
= proto_item_add_subtree(ti
,ett_bgp_extended_communities
);
3876 proto_tree_add_item(subtree4
, hf_bgp_ext_com_l2_encaps
,tvb
,q
+2, 1, ENC_BIG_ENDIAN
);
3877 sub_ti
= proto_tree_add_item(subtree4
, hf_bgp_ext_com_l2_c_flags
, tvb
, q
+3, 1, ENC_BIG_ENDIAN
);
3878 subtree5
= proto_item_add_subtree(sub_ti
, ett_bgp_ext_com_l2_flags
);
3879 proto_tree_add_item(subtree5
, hf_bgp_ext_com_l2_flag_d
, tvb
, q
+3, 1, ENC_BIG_ENDIAN
);
3880 proto_tree_add_item(subtree5
, hf_bgp_ext_com_l2_flag_z1
, tvb
, q
+3, 1, ENC_BIG_ENDIAN
);
3881 proto_tree_add_item(subtree5
, hf_bgp_ext_com_l2_flag_f
, tvb
, q
+3, 1, ENC_BIG_ENDIAN
);
3882 proto_tree_add_item(subtree5
, hf_bgp_ext_com_l2_flag_z345
, tvb
, q
+3, 1, ENC_BIG_ENDIAN
);
3883 proto_tree_add_item(subtree5
, hf_bgp_ext_com_l2_flag_c
, tvb
, q
+3, 1, ENC_BIG_ENDIAN
);
3884 proto_tree_add_item(subtree5
, hf_bgp_ext_com_l2_flag_s
, tvb
, q
+3, 1, ENC_BIG_ENDIAN
);
3886 proto_tree_add_item(subtree4
, hf_bgp_ext_com_l2_mtu
, tvb
, q
+4, 2, ENC_BIG_ENDIAN
);
3888 case BGP_EXT_COM_FLOW_ACT
:
3889 is_extended_type
= TRUE
;
3890 proto_tree_add_text(subtree3
,tvb
,q
,2,"Flow Spec Traffic Action");
3891 proto_tree_add_item(subtree3
,hf_bgp_ext_com_flow_act_allset
, tvb
, q
+2, 5, ENC_NA
);
3892 proto_tree_add_item(subtree3
,hf_bgp_ext_com_flow_act_samp_act
,tvb
,q
+7,1,ENC_BIG_ENDIAN
);
3893 proto_tree_add_item(subtree3
,hf_bgp_ext_com_flow_act_term_act
,tvb
,q
+7,1,ENC_BIG_ENDIAN
);
3895 case BGP_EXT_COM_FLOW_MARK
:
3896 is_extended_type
= TRUE
;
3897 proto_tree_add_text(subtree3
,tvb
,q
,2,"Flow Spec Traffic Mark");
3899 case BGP_EXT_COM_FLOW_RATE
:
3900 is_extended_type
= TRUE
;
3901 proto_tree_add_text(subtree3
,tvb
,q
,2,"Flow Spec Traffic Rate Limit");
3902 /* the 2 first bytes are 2 bytes ASN or 2 least significant bytes of a 4 byte ASN */
3903 proto_tree_add_item(subtree3
, hf_bgp_update_community_as
,
3904 tvb
, q
+2, 2, ENC_BIG_ENDIAN
);
3905 /* remaining 4 bytes gives traffic rate in IEEE floating point */
3906 proto_tree_add_item(subtree3
, hf_bgp_ext_com_flow_rate_float
,tvb
,q
+4,4,ENC_BIG_ENDIAN
);
3908 case BGP_EXT_COM_FLOW_RDIR
:
3909 is_extended_type
= TRUE
;
3910 ti
= proto_tree_add_item(subtree3
,hf_bgp_ext_com_flow_redir
,tvb
,q
,8,ENC_NA
);
3911 subtree4
= proto_item_add_subtree(ti
, ett_bgp_extended_com_fspec_redir
);
3912 proto_tree_add_text(subtree4
,tvb
,q
,2,"Flow Spec Traffic Redirect");
3913 /* flow spec RFC doesn't allow to specify RT format, */
3914 /* decoded by default as (2 bytes):an (4 byes) */
3915 proto_tree_add_item(subtree4
,hf_bgp_ext_com_flow_redir_as
,tvb
,q
+2,2,ENC_NA
);
3916 proto_tree_add_item(subtree4
,hf_bgp_ext_com_flow_redir_an
,tvb
,q
+4,4,ENC_NA
);
3917 proto_item_append_text(ti
," RT %u:%u",tvb_get_ntohs(tvb
,q
+2),tvb_get_ntohl(tvb
,q
+4));
3919 } /* switch (ext_com) */
3921 if (!is_regular_type
&& !is_extended_type
)
3922 proto_tree_add_text(subtree3
,tvb
,q
,8, "%s","Unknown");
3927 case BGPTYPE_SAFI_SPECIFIC_ATTR
:
3929 end
= o
+ i
+ aoff
+ tlen
;
3932 ssa_type
= tvb_get_ntohs(tvb
, q
) & BGP_SSA_TYPE
;
3933 ssa_len
= tvb_get_ntohs(tvb
, q
+ 2);
3935 ti
= proto_tree_add_text(subtree2
, tvb
, q
, MIN(ssa_len
+ 4, end
- q
),
3937 val_to_str_const(ssa_type
, bgp_ssa_type
, "Unknown SSA"));
3938 subtree3
= proto_item_add_subtree(ti
, ett_bgp_ssa
);
3940 proto_tree_add_item(subtree3
, hf_bgp_ssa_t
, tvb
,
3941 q
, 1, ENC_BIG_ENDIAN
);
3942 hidden_item
= proto_tree_add_item(subtree3
, hf_bgp_ssa_type
, tvb
,
3943 q
, 2, ENC_BIG_ENDIAN
);
3944 PROTO_ITEM_SET_HIDDEN(hidden_item
);
3945 proto_tree_add_text(subtree3
, tvb
, q
, 2,
3946 "Type: %s", val_to_str_const(ssa_type
, bgp_ssa_type
, "Unknown"));
3947 if ((ssa_len
== 0) || (q
+ ssa_len
> end
)) {
3948 proto_tree_add_text(subtree3
, tvb
, q
+ 2, end
- q
- 2,
3949 "Invalid Length of %u", ssa_len
);
3952 proto_tree_add_item(subtree3
, hf_bgp_ssa_len
, tvb
,
3953 q
+ 2, 2, ENC_BIG_ENDIAN
);
3956 case BGP_SSA_L2TPv3
:
3957 proto_tree_add_item(subtree3
, hf_bgp_ssa_l2tpv3_pref
, tvb
,
3958 q
+ 4, 2, ENC_BIG_ENDIAN
);
3960 ti
= proto_tree_add_text(subtree3
, tvb
, q
+ 6, 1, "Flags");
3961 subtree4
= proto_item_add_subtree(ti
, ett_bgp_ssa_subtree
) ;
3962 proto_tree_add_item(subtree4
, hf_bgp_ssa_l2tpv3_s
, tvb
,
3963 q
+ 6, 1, ENC_BIG_ENDIAN
);
3964 proto_tree_add_item(subtree4
, hf_bgp_ssa_l2tpv3_unused
, tvb
,
3965 q
+ 6, 1, ENC_BIG_ENDIAN
);
3967 ssa_v3_len
= tvb_get_guint8(tvb
, q
+ 7);
3968 if (ssa_v3_len
+ 8 == ssa_len
){
3969 proto_tree_add_item(subtree3
, hf_bgp_ssa_l2tpv3_cookie_len
, tvb
,
3970 q
+ 7, 1, ENC_BIG_ENDIAN
);
3972 proto_tree_add_text(subtree3
, tvb
, q
+ 7, 1,
3973 "Invalid Cookie Length of %u", ssa_v3_len
);
3974 q
+= ssa_len
+ 4; /* 4 from type and length */
3977 proto_tree_add_item(subtree3
, hf_bgp_ssa_l2tpv3_session_id
, tvb
,
3978 q
+ 8, 4, ENC_BIG_ENDIAN
);
3980 proto_tree_add_item(subtree3
, hf_bgp_ssa_l2tpv3_cookie
, tvb
,
3981 q
+ 12, ssa_v3_len
, ENC_NA
);
3982 q
+= ssa_len
+ 4; /* 4 from type and length */
3988 proto_tree_add_item(subtree3
, hf_bgp_ssa_value
, tvb
,
3989 q
+ 4, ssa_len
, ENC_NA
);
3990 q
+= ssa_len
+ 4; /* 4 from type and length */
3992 case BGP_SSA_L2TPv3_IN_IPSec
:
3993 case BGP_SSA_mGRE_IN_IPSec
:
3994 /* These contain BGP_SSA_IPSec and BGP_SSA_L2TPv3/BGP_SSA_mGRE */
3995 q
+= 4; /* 4 from type and length */
3997 } /* switch (bgpa.bgpa_type) */
4000 case BGPTYPE_TUNNEL_ENCAPS_ATTR
:
4002 end
= o
+ i
+ aoff
+ tlen
;
4004 ti
= proto_tree_add_text(subtree2
, tvb
, q
, tlen
, "TLV Encodings");
4005 subtree3
= proto_item_add_subtree(ti
, ett_bgp_tunnel_tlv
);
4008 encaps_tunnel_type
= tvb_get_ntohs(tvb
, q
);
4009 encaps_tunnel_len
= tvb_get_ntohs(tvb
, q
+ 2);
4011 ti
= proto_tree_add_text(subtree3
, tvb
, q
, encaps_tunnel_len
+ 4, "%s (%u bytes)", val_to_str_const(encaps_tunnel_type
, tunnel_type
, "Unknown"), encaps_tunnel_len
+ 4);
4012 subtree4
= proto_item_add_subtree(ti
, ett_bgp_tunnel_tlv_subtree
);
4014 proto_tree_add_item(subtree4
, hf_bgp_update_encaps_tunnel_tlv_type
, tvb
, q
, 2, ENC_NA
);
4015 proto_tree_add_item(subtree4
, hf_bgp_update_encaps_tunnel_tlv_len
, tvb
, q
+ 2, 2, ENC_NA
);
4017 ti
= proto_tree_add_text(subtree4
, tvb
, q
+ 4, encaps_tunnel_len
, "Sub-TLV Encodings");
4018 subtree5
= proto_item_add_subtree(ti
, ett_bgp_tunnel_subtlv
);
4021 j
= q
+ encaps_tunnel_len
;
4023 encaps_tunnel_subtype
= tvb_get_guint8(tvb
, q
);
4024 encaps_tunnel_sublen
= tvb_get_guint8(tvb
, q
+ 1);
4026 ti
= proto_tree_add_text(subtree5
, tvb
, q
, encaps_tunnel_sublen
+ 2, "%s (%u bytes)", val_to_str_const(encaps_tunnel_subtype
, subtlv_type
, "Unknown"), encaps_tunnel_sublen
+ 2);
4027 subtree6
= proto_item_add_subtree(ti
, ett_bgp_tunnel_tlv_subtree
);
4029 proto_tree_add_item(subtree6
, hf_bgp_update_encaps_tunnel_subtlv_type
, tvb
, q
, 1, ENC_NA
);
4030 proto_tree_add_item(subtree6
, hf_bgp_update_encaps_tunnel_subtlv_len
, tvb
, q
+ 1, 1, ENC_NA
);
4032 switch (encaps_tunnel_subtype
) {
4033 case TUNNEL_SUBTLV_ENCAPSULATION
:
4034 if (encaps_tunnel_type
== TUNNEL_TYPE_L2TP_OVER_IP
) {
4035 proto_tree_add_text(subtree6
, tvb
, q
+ 2, 4, "Session ID: %u", tvb_get_letohl(tvb
, q
+ 2));
4036 proto_tree_add_text(subtree6
, tvb
, q
+ 6, encaps_tunnel_sublen
- 4, "Cookie: %s", tvb_bytes_to_str(tvb
, q
+ 6, encaps_tunnel_sublen
- 4));
4037 } else if (encaps_tunnel_type
== TUNNEL_TYPE_GRE
) {
4038 proto_tree_add_text(subtree6
, tvb
, q
+ 2, encaps_tunnel_sublen
, "GRE key: %x", tvb_get_letohl(tvb
, q
+ 2));
4041 case TUNNEL_SUBTLV_PROTO_TYPE
:
4042 proto_tree_add_text(subtree6
, tvb
, q
+ 2, encaps_tunnel_sublen
, "Protocol type: %s (0x%x)", val_to_str_const(tvb_get_ntohs(tvb
, q
+ 2), etype_vals
, "Unknown"), tvb_get_ntohs(tvb
, q
+ 2));
4044 case TUNNEL_SUBTLV_COLOR
:
4045 proto_tree_add_text(subtree6
, tvb
, q
+ 6, encaps_tunnel_sublen
- 4, "Color value: %u", tvb_get_letohl(tvb
, q
+ 6));
4047 case TUNNEL_SUBTLV_LOAD_BALANCE
:
4048 if (encaps_tunnel_type
== TUNNEL_TYPE_L2TP_OVER_IP
|| encaps_tunnel_type
== TUNNEL_TYPE_GRE
) {
4049 proto_tree_add_text(subtree6
, tvb
, q
+ 2, encaps_tunnel_sublen
, "Load-balancing block length: %u", tvb_get_ntohs(tvb
, q
+ 2));
4054 } /* switch (encaps_tunnel_subtype) */
4056 q
+= 2 + encaps_tunnel_sublen
; /* type and length + length of value */
4064 proto_tree_add_text(subtree2
, tvb
, o
+ i
+ aoff
, tlen
,
4065 "Unknown (%u byte%s)", tlen
, plurality(tlen
, "", "s"));
4067 } /* switch (bgpa.bgpa_type) */ /* end of second switch */
4077 /* parse prefixes */
4079 ti
= proto_tree_add_item(tree
, hf_bgp_update_nlri
, tvb
, o
, len
, ENC_NA
);
4080 subtree
= proto_item_add_subtree(ti
, ett_bgp_nlri
);
4082 /* Heuristic to detect if IPv4 prefix are using Path Identifiers */
4083 if( detect_add_path_prefix4(tvb
, o
, end
) ) {
4084 /* IPv4 prefixes with Path Id */
4086 i
= decode_path_prefix4(subtree
, hf_bgp_nlri_path_id
, hf_bgp_nlri_prefix
, tvb
, o
,
4093 /* Standard prefixes */
4095 i
= decode_prefix4(subtree
, NULL
, hf_bgp_nlri_prefix
, tvb
, o
, 0,
4107 * Dissect a BGP NOTIFICATION message.
4110 dissect_bgp_notification(tvbuff_t
*tvb
, proto_tree
*tree
, packet_info
*pinfo
)
4112 int hlen
; /* message length */
4117 hlen
= tvb_get_ntohs(tvb
, BGP_MARKER_SIZE
);
4118 offset
= BGP_MARKER_SIZE
+ 2 + 1;
4121 /* print error code */
4122 proto_tree_add_item(tree
, hf_bgp_notify_major_error
, tvb
, offset
, 1, ENC_NA
);
4123 major_error
= tvb_get_guint8(tvb
, offset
);
4126 switch(major_error
){
4127 case BGP_MAJOR_ERROR_MSG_HDR
:
4128 proto_tree_add_item(tree
, hf_bgp_notify_minor_msg_hdr
, tvb
, offset
, 1, ENC_NA
);
4130 case BGP_MAJOR_ERROR_OPEN_MSG
:
4131 proto_tree_add_item(tree
, hf_bgp_notify_minor_open_msg
, tvb
, offset
, 1, ENC_NA
);
4133 case BGP_MAJOR_ERROR_UPDATE_MSG
:
4134 proto_tree_add_item(tree
,hf_bgp_notify_minor_update_msg
, tvb
, offset
, 1, ENC_NA
);
4136 case BGP_MAJOR_ERROR_HT_EXPIRED
:
4137 proto_tree_add_item(tree
, hf_bgp_notify_minor_ht_expired
, tvb
, offset
, 1, ENC_NA
);
4139 case BGP_MAJOR_ERROR_STATE_MACHINE
:
4140 proto_tree_add_item(tree
, hf_bgp_notify_minor_state_machine
, tvb
, offset
, 1, ENC_NA
);
4142 case BGP_MAJOR_ERROR_CEASE
:
4143 proto_tree_add_item(tree
, hf_bgp_notify_minor_cease
, tvb
, offset
, 1, ENC_NA
);
4145 case BGP_MAJOR_ERROR_CAP_MSG
:
4146 proto_tree_add_item(tree
, hf_bgp_notify_minor_cap_msg
, tvb
, offset
, 1, ENC_NA
);
4149 ti
= proto_tree_add_item(tree
, hf_bgp_notify_minor_unknown
, tvb
, offset
, 1, ENC_NA
);
4150 expert_add_info_format(pinfo
, ti
, &ei_bgp_notify_minor_unknown
, "Unknown notification error (%d)",major_error
);
4155 /* only print if there is optional data */
4156 if (hlen
> BGP_MIN_NOTIFICATION_MSG_SIZE
) {
4157 proto_tree_add_item(tree
, hf_bgp_notify_data
, tvb
, offset
, hlen
- BGP_MIN_NOTIFICATION_MSG_SIZE
, ENC_NA
);
4162 * Dissect a BGP ROUTE-REFRESH message.
4165 dissect_bgp_route_refresh(tvbuff_t
*tvb
, proto_tree
*tree
, packet_info
*pinfo
)
4167 int p
; /* tvb offset counter */
4168 int pend
; /* end of list of entries for one orf type */
4169 guint16 hlen
; /* tvb RR msg length */
4170 proto_item
*ti
; /* tree item */
4171 proto_item
*ti1
; /* tree item */
4172 proto_tree
*subtree
; /* tree for orf */
4173 proto_tree
*subtree1
; /* tree for orf entry */
4174 guint8 orftype
; /* ORF Type */
4175 guint16 orflen
; /* ORF len */
4176 guint8 entryflag
; /* ORF Entry flag: action(add,del,delall) match(permit,deny) */
4177 int entrylen
; /* ORF Entry length */
4178 int advance
; /* tmp */
4184 00 01 00 01 afi,safi= ipv4-unicast
4185 02 80 00 01 defer, prefix-orf, len=1
4189 00 01 00 01 afi,saif= ipv4-unicast
4190 01 80 00 0a immediate, prefix-orf, len=10
4192 00 00 00 05 seqno = 5
4195 10 07 02 prefix = 7.2.0.0/16
4200 hlen
= tvb_get_ntohs(tvb
, BGP_MARKER_SIZE
);
4201 p
= BGP_HEADER_SIZE
;
4204 proto_tree_add_item(tree
, hf_bgp_route_refresh_afi
, tvb
, p
, 2, ENC_BIG_ENDIAN
);
4207 /* Subtype in draft-ietf-idr-bgp-enhanced-route-refresh-02 (for Enhanced Route Refresh Capability) before Reserved*/
4208 proto_tree_add_item(tree
, hf_bgp_route_refresh_subtype
, tvb
, p
, 1, ENC_BIG_ENDIAN
);
4212 proto_tree_add_item(tree
, hf_bgp_route_refresh_safi
, tvb
, p
, 1, ENC_BIG_ENDIAN
);
4215 if ( hlen
== BGP_HEADER_SIZE
+ 4 )
4220 ti
= proto_tree_add_item(tree
, hf_bgp_route_refresh_orf
, tvb
, p
, 4, ENC_NA
);
4221 subtree
= proto_item_add_subtree(ti
, ett_bgp_orf
);
4223 proto_tree_add_item(subtree
, hf_bgp_route_refresh_orf_flag
, tvb
, p
, 1, ENC_BIG_ENDIAN
);
4226 ti1
= proto_tree_add_item(subtree
, hf_bgp_route_refresh_orf_type
, tvb
, p
, 1, ENC_BIG_ENDIAN
);
4227 orftype
= tvb_get_guint8(tvb
, p
);
4230 proto_tree_add_item(subtree
, hf_bgp_route_refresh_orf_length
, tvb
, p
, 2, ENC_BIG_ENDIAN
);
4231 orflen
= tvb_get_ntohs(tvb
, p
);
4232 proto_item_set_len(ti
, orflen
+ 4);
4235 if (orftype
!= BGP_ORF_PREFIX_CISCO
) {
4236 expert_add_info_format(pinfo
, ti1
, &ei_bgp_route_refresh_orf_type_unknown
, "ORFEntry-Unknown (type %u)", orftype
);
4243 ti1
= proto_tree_add_item(subtree
, hf_bgp_route_refresh_orf_entry_prefixlist
, tvb
, p
, 1, ENC_NA
);
4244 subtree1
= proto_item_add_subtree(ti1
, ett_bgp_orf_entry
);
4245 proto_tree_add_item(subtree1
, hf_bgp_route_refresh_orf_entry_action
, tvb
, p
, 1, ENC_BIG_ENDIAN
);
4246 entryflag
= tvb_get_guint8(tvb
, p
);
4247 if (((entryflag
& BGP_ORF_ACTION
) >> 6) == BGP_ORF_REMOVEALL
) {
4251 proto_tree_add_item(subtree1
, hf_bgp_route_refresh_orf_entry_match
, tvb
, p
, 1, ENC_BIG_ENDIAN
);
4254 proto_tree_add_item(subtree1
, hf_bgp_route_refresh_orf_entry_sequence
, tvb
, p
, 4, ENC_BIG_ENDIAN
);
4257 proto_tree_add_item(subtree1
, hf_bgp_route_refresh_orf_entry_prefixmask_lower
, tvb
, p
, 1, ENC_BIG_ENDIAN
);
4260 proto_tree_add_item(subtree1
, hf_bgp_route_refresh_orf_entry_prefixmask_upper
, tvb
, p
, 1, ENC_BIG_ENDIAN
);
4263 advance
= decode_prefix4(subtree1
, NULL
, -1, tvb
, p
, 0, "ORF");
4266 entrylen
= 7 + 1 + advance
;
4268 proto_item_set_len(ti1
, entrylen
);
4276 * Dissect a BGP CAPABILITY message.
4279 dissect_bgp_capability(tvbuff_t
*tvb
, proto_tree
*tree
, packet_info
*pinfo
)
4284 mend
= offset
+ tvb_get_ntohs(tvb
, offset
+ BGP_MARKER_SIZE
);
4285 offset
+= BGP_HEADER_SIZE
;
4286 /* step through all of the capabilities */
4287 while (offset
< mend
) {
4288 offset
= dissect_bgp_capability_item(tvb
, tree
, pinfo
, offset
, TRUE
);
4293 dissect_bgp_pdu(tvbuff_t
*volatile tvb
, packet_info
*pinfo
, proto_tree
*tree
,
4296 guint16 bgp_len
; /* Message length */
4297 guint8 bgp_type
; /* Message type */
4298 const char *typ
; /* Message type (string) */
4299 proto_item
*ti_len
= NULL
; /* length item */
4300 proto_tree
*bgp_tree
= NULL
; /* BGP packet tree */
4302 bgp_len
= tvb_get_ntohs(tvb
, BGP_MARKER_SIZE
);
4303 bgp_type
= tvb_get_guint8(tvb
, BGP_MARKER_SIZE
+ 2);
4304 typ
= val_to_str(bgp_type
, bgptypevals
, "Unknown message type (0x%02x)");
4307 col_add_str(pinfo
->cinfo
, COL_INFO
, typ
);
4309 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", %s", typ
);
4313 ti
= proto_tree_add_item(tree
, proto_bgp
, tvb
, 0, -1, ENC_NA
);
4314 proto_item_append_text(ti
, " - %s", typ
);
4316 /* add a different tree for each message type */
4319 bgp_tree
= proto_item_add_subtree(ti
, ett_bgp_open
);
4322 bgp_tree
= proto_item_add_subtree(ti
, ett_bgp_update
);
4324 case BGP_NOTIFICATION
:
4325 bgp_tree
= proto_item_add_subtree(ti
, ett_bgp_notification
);
4328 bgp_tree
= proto_item_add_subtree(ti
, ett_bgp
);
4330 case BGP_ROUTE_REFRESH_CISCO
:
4331 case BGP_ROUTE_REFRESH
:
4332 bgp_tree
= proto_item_add_subtree(ti
, ett_bgp_route_refresh
);
4334 case BGP_CAPABILITY
:
4335 bgp_tree
= proto_item_add_subtree(ti
, ett_bgp_capability
);
4338 bgp_tree
= proto_item_add_subtree(ti
, ett_bgp
);
4342 proto_tree_add_item(bgp_tree
, hf_bgp_marker
, tvb
, 0, 16, ENC_NA
);
4344 ti_len
= proto_tree_add_item(bgp_tree
, hf_bgp_length
, tvb
, 16, 2, ENC_BIG_ENDIAN
);
4347 if (bgp_len
< BGP_HEADER_SIZE
|| bgp_len
> BGP_MAX_PACKET_SIZE
) {
4348 expert_add_info_format(pinfo
, ti_len
, &ei_bgp_length_invalid
, "Length is invalid %u", bgp_len
);
4352 proto_tree_add_item(bgp_tree
, hf_bgp_type
, tvb
, 16 + 2, 1, ENC_BIG_ENDIAN
);
4356 dissect_bgp_open(tvb
, bgp_tree
, pinfo
);
4359 dissect_bgp_update(tvb
, bgp_tree
, pinfo
);
4361 case BGP_NOTIFICATION
:
4362 dissect_bgp_notification(tvb
, bgp_tree
, pinfo
);
4365 /* no data in KEEPALIVE messages */
4367 case BGP_ROUTE_REFRESH_CISCO
:
4368 case BGP_ROUTE_REFRESH
:
4369 dissect_bgp_route_refresh(tvb
, bgp_tree
, pinfo
);
4371 case BGP_CAPABILITY
:
4372 dissect_bgp_capability(tvb
, bgp_tree
, pinfo
);
4380 * Dissect a BGP packet.
4383 dissect_bgp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
4385 volatile int offset
= 0; /* offset into the tvbuff */
4386 gint reported_length_remaining
;
4387 guint8 bgp_marker
[BGP_MARKER_SIZE
]; /* Marker (should be all ones */
4388 static guchar marker
[] = { /* BGP message marker */
4389 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
4390 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
4392 proto_item
*ti
; /* tree item */
4393 proto_tree
*bgp_tree
; /* BGP packet tree */
4394 guint16 bgp_len
; /* Message length */
4396 guint length_remaining
;
4398 volatile gboolean first
= TRUE
; /* TRUE for the first BGP message in packet */
4399 tvbuff_t
*volatile next_tvb
;
4402 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "BGP");
4403 col_clear(pinfo
->cinfo
, COL_INFO
);
4406 * Scan through the TCP payload looking for a BGP marker.
4408 while ((reported_length_remaining
= tvb_reported_length_remaining(tvb
, offset
))
4411 * "reported_length_remaining" is the number of bytes of TCP payload
4412 * remaining. If it's more than the length of a BGP marker,
4413 * we check only the number of bytes in a BGP marker.
4415 if (reported_length_remaining
> BGP_MARKER_SIZE
)
4416 reported_length_remaining
= BGP_MARKER_SIZE
;
4419 * OK, is there a BGP marker starting at the specified offset -
4420 * or, at least, the beginning of a BGP marker running to the end
4421 * of the TCP payload?
4423 * This will throw an exception if the frame is short; that's what
4426 tvb_memcpy(tvb
, bgp_marker
, offset
, reported_length_remaining
);
4427 if (memcmp(bgp_marker
, marker
, reported_length_remaining
) == 0) {
4429 * Yes - stop scanning and start processing BGP packets.
4435 * No - keep scanning through the tvbuff to try to find a marker.
4441 * If we skipped any bytes, mark it as a BGP continuation.
4444 ti
= proto_tree_add_item(tree
, proto_bgp
, tvb
, 0, -1, ENC_NA
);
4445 bgp_tree
= proto_item_add_subtree(ti
, ett_bgp
);
4447 proto_tree_add_text(bgp_tree
, tvb
, 0, offset
, "Continuation");
4451 * Now process the BGP packets in the TCP payload.
4453 * XXX - perhaps "tcp_dissect_pdus()" should take a starting
4454 * offset, in which case we can replace the loop below with
4455 * a call to "tcp_dissect_pdus()".
4457 while (tvb_reported_length_remaining(tvb
, offset
) > 0) {
4459 * This will throw an exception if we don't have any data left.
4460 * That's what we want. (See "tcp_dissect_pdus()", which is
4463 length_remaining
= tvb_ensure_length_remaining(tvb
, offset
);
4466 * Can we do reassembly?
4468 if (bgp_desegment
&& pinfo
->can_desegment
) {
4470 * Yes - would a BGP header starting at this offset be split
4471 * across segment boundaries?
4473 if (length_remaining
< BGP_HEADER_SIZE
) {
4475 * Yes. Tell the TCP dissector where the data for this message
4476 * starts in the data it handed us and that we need "some more
4477 * data." Don't tell it exactly how many bytes we need because
4478 * if/when we ask for even more (after the header) that will
4481 pinfo
->desegment_offset
= offset
;
4482 pinfo
->desegment_len
= DESEGMENT_ONE_MORE_SEGMENT
;
4488 * Get the length and type from the BGP header.
4490 bgp_len
= tvb_get_ntohs(tvb
, offset
+ BGP_MARKER_SIZE
);
4491 if (bgp_len
< BGP_HEADER_SIZE
) {
4493 * The BGP length doesn't include the BGP header; report that
4496 show_reported_bounds_error(tvb
, pinfo
, tree
);
4501 * Can we do reassembly?
4503 if (bgp_desegment
&& pinfo
->can_desegment
) {
4505 * Yes - is the PDU split across segment boundaries?
4507 if (length_remaining
< bgp_len
) {
4509 * Yes. Tell the TCP dissector where the data for this
4510 * message starts in the data it handed us, and how many
4511 * more bytes we need, and return.
4513 pinfo
->desegment_offset
= offset
;
4514 pinfo
->desegment_len
= bgp_len
- length_remaining
;
4520 * Construct a tvbuff containing the amount of the payload we have
4521 * available. Make its reported length the amount of data in the PDU.
4523 * XXX - if reassembly isn't enabled. the subdissector will throw a
4524 * BoundsError exception, rather than a ReportedBoundsError exception.
4525 * We really want a tvbuff where the length is "length", the reported
4526 * length is "plen", and the "if the snapshot length were infinite"
4527 * length is the minimum of the reported length of the tvbuff handed
4528 * to us and "plen", with a new type of exception thrown if the offset
4529 * is within the reported length but beyond that third length, with
4530 * that exception getting the "Unreassembled Packet" error.
4532 length
= length_remaining
;
4533 if (length
> bgp_len
)
4535 next_tvb
= tvb_new_subset(tvb
, offset
, length
, bgp_len
);
4540 * If it gets an error that means there's no point in
4541 * dissecting any more PDUs, rethrow the exception in
4544 * If it gets any other error, report it and continue, as that
4545 * means that PDU got an error, but that doesn't mean we should
4546 * stop dissecting PDUs within this frame or chunk of reassembled
4549 pd_save
= pinfo
->private_data
;
4551 dissect_bgp_pdu(next_tvb
, pinfo
, tree
, first
);
4553 CATCH_NONFATAL_ERRORS
{
4554 /* Restore the private_data structure in case one of the
4555 * called dissectors modified it (and, due to the exception,
4556 * was unable to restore it).
4558 pinfo
->private_data
= pd_save
;
4559 show_exception(tvb
, pinfo
, tree
, EXCEPT_CODE
, GET_MESSAGE
);
4566 * Step to the next PDU.
4567 * Make sure we don't overflow.
4569 offset_before
= offset
;
4571 if (offset
<= offset_before
)
4577 * Register ourselves.
4580 proto_register_bgp(void)
4583 static hf_register_info hf
[] = {
4586 { "Marker", "bgp.marker", FT_BYTES
, BASE_NONE
,
4587 NULL
, 0x0, "Must be set to all ones (16 Bytes)", HFILL
}},
4589 { "Length", "bgp.length", FT_UINT16
, BASE_DEC
,
4590 NULL
, 0x0, "The total length of the message, including the header in octets", HFILL
}},
4592 { "Type", "bgp.type", FT_UINT8
, BASE_DEC
,
4593 VALS(bgptypevals
), 0x0, "BGP message type", HFILL
}},
4595 { &hf_bgp_open_version
,
4596 { "Version", "bgp.open.version", FT_UINT8
, BASE_DEC
,
4597 NULL
, 0x0, "The protocol version number", HFILL
}},
4598 { &hf_bgp_open_myas
,
4599 { "My AS", "bgp.open.myas", FT_UINT16
, BASE_DEC
,
4600 NULL
, 0x0, "The Autonomous System number of the sender", HFILL
}},
4601 { &hf_bgp_open_holdtime
,
4602 { "Hold Time", "bgp.open.holdtime", FT_UINT16
, BASE_DEC
,
4603 NULL
, 0x0, "The number of seconds the sender proposes for Hold Time", HFILL
}},
4604 { &hf_bgp_open_identifier
,
4605 { "BGP Identifier", "bgp.open.identifier", FT_IPv4
, BASE_NONE
,
4606 NULL
, 0x0, "The BGP Identifier of the sender", HFILL
}},
4607 { &hf_bgp_open_opt_len
,
4608 { "Optional Parameters Length", "bgp.open.opt.len", FT_UINT8
, BASE_DEC
,
4609 NULL
, 0x0, "The total length of the Optional Parameters field in octets", HFILL
}},
4610 { &hf_bgp_open_opt_params
,
4611 { "Optional Parameters", "bgp.open.opt", FT_NONE
, BASE_NONE
,
4612 NULL
, 0x0, "List of optional parameters", HFILL
}},
4613 { &hf_bgp_open_opt_param
,
4614 { "Optional Parameter", "bgp.open.opt.param", FT_NONE
, BASE_NONE
,
4615 NULL
, 0x0, NULL
, HFILL
}},
4616 { &hf_bgp_open_opt_param_type
,
4617 { "Parameter Type", "bgp.open.opt.param.type", FT_UINT8
, BASE_DEC
,
4618 VALS(bgp_open_opt_vals
), 0x0, "Unambiguously identifies individual parameters", HFILL
}},
4619 { &hf_bgp_open_opt_param_len
,
4620 { "Parameter Length", "bgp.open.opt.param.len", FT_UINT8
, BASE_DEC
,
4621 NULL
, 0x0, "Length of the Parameter Value", HFILL
}},
4622 { &hf_bgp_open_opt_param_auth
,
4623 { "Authentication Data", "bgp.open.opt.param.auth", FT_BYTES
, BASE_NONE
,
4624 NULL
, 0x0, "Deprecated", HFILL
}},
4625 { &hf_bgp_open_opt_param_unknown
,
4626 { "Unknown", "bgp.open.opt.param.unknown", FT_BYTES
, BASE_NONE
,
4627 NULL
, 0x0, "Unknown Parameter", HFILL
}},
4628 /* Notification error */
4629 { &hf_bgp_notify_major_error
,
4630 { "Major error Code", "bgp.notify.major_error", FT_UINT8
, BASE_DEC
,
4631 VALS(bgpnotify_major
), 0x0, NULL
, HFILL
}},
4632 { &hf_bgp_notify_minor_msg_hdr
,
4633 { "Minor error Code (Message Header)", "bgp.notify.minor_error", FT_UINT8
, BASE_DEC
,
4634 VALS(bgpnotify_minor_msg_hdr
), 0x0, NULL
, HFILL
}},
4635 { &hf_bgp_notify_minor_open_msg
,
4636 { "Minor error Code (Open Message)", "bgp.notify.minor_error_open", FT_UINT8
, BASE_DEC
,
4637 VALS(bgpnotify_minor_open_msg
), 0x0, NULL
, HFILL
}},
4638 { &hf_bgp_notify_minor_update_msg
,
4639 { "Minor error Code (Update Message)", "bgp.notify.minor_error_update", FT_UINT8
, BASE_DEC
,
4640 VALS(bgpnotify_minor_update_msg
), 0x0, NULL
, HFILL
}},
4641 { &hf_bgp_notify_minor_ht_expired
,
4642 { "Minor error Code (Hold Timer Expired)", "bgp.notify.minor_error_expired", FT_UINT8
, BASE_DEC
,
4643 NULL
, 0x0, NULL
, HFILL
}},
4644 { &hf_bgp_notify_minor_state_machine
,
4645 { "Minor error Code (State Machine)", "bgp.notify.minor_error_state", FT_UINT8
, BASE_DEC
,
4646 VALS(bgpnotify_minor_state_machine
), 0x0, NULL
, HFILL
}},
4647 { &hf_bgp_notify_minor_cease
,
4648 { "Minor error Code (Cease)", "bgp.notify.minor_error_cease", FT_UINT8
, BASE_DEC
,
4649 VALS(bgpnotify_minor_cease
), 0x0, NULL
, HFILL
}},
4650 { &hf_bgp_notify_minor_cap_msg
,
4651 { "Minor error Code (Capability Message)", "bgp.notify.minor_error_capability", FT_UINT8
, BASE_DEC
,
4652 VALS(bgpnotify_minor_cap_msg
), 0x0, NULL
, HFILL
}},
4653 { &hf_bgp_notify_minor_unknown
,
4654 { "Minor error Code (Unknown)", "bgp.notify.minor_error_unknown", FT_UINT8
, BASE_DEC
,
4655 NULL
, 0x0, NULL
, HFILL
}},
4656 { &hf_bgp_notify_data
,
4657 { "Data", "bgp.notify.minor_data", FT_BYTES
, BASE_NONE
,
4658 NULL
, 0x0, NULL
, HFILL
}},
4661 { &hf_bgp_route_refresh_afi
,
4662 { "Address family identifier (AFI)", "bgp.route_refresh.afi", FT_UINT16
, BASE_DEC
,
4663 VALS(afn_vals
), 0x0, NULL
, HFILL
}},
4664 { &hf_bgp_route_refresh_subtype
,
4665 { "Subtype", "bgp.route_refresh.subtype", FT_UINT8
, BASE_DEC
,
4666 VALS(route_refresh_subtype_vals
), 0x0, NULL
, HFILL
}},
4667 { &hf_bgp_route_refresh_safi
,
4668 { "Subsequent address family identifier (SAFI)", "bgp.route_refresh.safi", FT_UINT8
, BASE_DEC
,
4669 VALS(bgpattr_nlri_safi
), 0x0, NULL
, HFILL
}},
4670 { &hf_bgp_route_refresh_orf
,
4671 { "ORF information", "bgp.route_refresh.orf", FT_NONE
, BASE_NONE
,
4672 NULL
, 0x0, NULL
, HFILL
}},
4673 { &hf_bgp_route_refresh_orf_flag
,
4674 { "ORF flag", "bgp.route_refresh.orf.flag", FT_UINT8
, BASE_DEC
,
4675 VALS(orf_when_vals
), 0x0, NULL
, HFILL
}},
4676 { &hf_bgp_route_refresh_orf_type
,
4677 { "ORF type", "bgp.route_refresh.orf.type", FT_UINT8
, BASE_DEC
,
4678 VALS(orf_type_vals
), 0x0, NULL
, HFILL
}},
4679 { &hf_bgp_route_refresh_orf_length
,
4680 { "ORF length", "bgp.route_refresh.orf.length", FT_UINT8
, BASE_DEC
,
4681 NULL
, 0x0, NULL
, HFILL
}},
4682 { &hf_bgp_route_refresh_orf_entry_prefixlist
,
4683 { "ORFEntry PrefixList", "bgp.route_refresh.orf.entry", FT_NONE
, BASE_NONE
,
4684 NULL
, 0x0, NULL
, HFILL
}},
4685 { &hf_bgp_route_refresh_orf_entry_action
,
4686 { "ORFEntry Action", "bgp.route_refresh.orf.entry.action", FT_UINT8
, BASE_DEC
,
4687 VALS(orf_entry_action_vals
), BGP_ORF_ACTION
, NULL
, HFILL
}},
4688 { &hf_bgp_route_refresh_orf_entry_match
,
4689 { "ORFEntry Match", "bgp.route_refresh.orf.entry.match", FT_UINT8
, BASE_DEC
,
4690 VALS(orf_entry_match_vals
), BGP_ORF_MATCH
, NULL
, HFILL
}},
4691 { &hf_bgp_route_refresh_orf_entry_sequence
,
4692 { "ORFEntry Sequence", "bgp.route_refresh.orf.entry.sequence", FT_UINT8
, BASE_DEC
,
4693 NULL
, 0x0, NULL
, HFILL
}},
4694 { &hf_bgp_route_refresh_orf_entry_prefixmask_lower
,
4695 { "ORFEntry PrefixMask length lower bound", "bgp.route_refresh.orf.entry.prefixmask_lower", FT_UINT8
, BASE_DEC
,
4696 NULL
, 0x0, NULL
, HFILL
}},
4697 { &hf_bgp_route_refresh_orf_entry_prefixmask_upper
,
4698 { "ORFEntry PrefixMask length upper bound", "bgp.route_refresh.orf.entry.prefixmask_upper", FT_UINT8
, BASE_DEC
,
4699 NULL
, 0x0, NULL
, HFILL
}},
4703 { "Capability", "bgp.cap", FT_NONE
, BASE_NONE
,
4704 NULL
, 0x0, NULL
, HFILL
}},
4706 { "Type", "bgp.cap.type", FT_UINT8
, BASE_DEC
,
4707 VALS(capability_vals
), 0x0, NULL
, HFILL
}},
4708 { &hf_bgp_cap_length
,
4709 { "Length", "bgp.cap.length", FT_UINT8
, BASE_DEC
,
4710 NULL
, 0x0, NULL
, HFILL
}},
4711 { &hf_bgp_cap_action
,
4712 { "Action", "bgp.cap.action", FT_UINT8
, BASE_DEC
,
4713 VALS(bgpcap_action
), 0x0, NULL
, HFILL
}},
4714 { &hf_bgp_cap_unknown
,
4715 { "Unknown", "bgp.cap.unknown", FT_BYTES
, BASE_NONE
,
4716 NULL
, 0x0, NULL
, HFILL
}},
4717 { &hf_bgp_cap_reserved
,
4718 { "Reserved", "bgp.cap.reserved", FT_BYTES
, BASE_NONE
,
4719 NULL
, 0x0, "Must be Zero", HFILL
}},
4720 { &hf_bgp_cap_mp_afi
,
4721 { "AFI", "bgp.cap.mp.afi", FT_UINT16
, BASE_DEC
,
4722 VALS(afn_vals
), 0x0, NULL
, HFILL
}},
4723 { &hf_bgp_cap_mp_safi
,
4724 { "SAFI", "bgp.cap.mp.safi", FT_UINT8
, BASE_DEC
,
4725 VALS(bgpattr_nlri_safi
), 0x0, NULL
, HFILL
}},
4726 { &hf_bgp_cap_gr_timers
,
4727 { "Restart Timers", "bgp.cap.gr.timers", FT_UINT16
, BASE_HEX
,
4728 NULL
, 0x0, NULL
, HFILL
}},
4729 { &hf_bgp_cap_gr_timers_restart_flag
,
4730 { "Restart", "bgp.cap.gr.timers.restart_flag", FT_BOOLEAN
, 16,
4731 TFS(&tfs_yes_no
), 0x8000, NULL
, HFILL
}},
4732 { &hf_bgp_cap_gr_timers_restart_time
,
4733 { "Time", "bgp.cap.gr.timers.restart_time", FT_UINT16
, BASE_DEC
,
4734 NULL
, 0x0FFF, "in us", HFILL
}},
4735 { &hf_bgp_cap_gr_afi
,
4736 { "AFI", "bgp.cap.gr.afi", FT_UINT16
, BASE_DEC
,
4737 VALS(afn_vals
), 0x0, NULL
, HFILL
}},
4738 { &hf_bgp_cap_gr_safi
,
4739 { "SAFI", "bgp.cap.gr.safi", FT_UINT8
, BASE_DEC
,
4740 VALS(bgpattr_nlri_safi
), 0x0, NULL
, HFILL
}},
4741 { &hf_bgp_cap_gr_flag
,
4742 { "Flag", "bgp.cap.gr.flag", FT_UINT8
, BASE_HEX
,
4743 NULL
, 0x0, NULL
, HFILL
}},
4744 { &hf_bgp_cap_gr_flag_pfs
,
4745 { "Preserve forwarding state", "bgp.cap.gr.flag.pfs", FT_BOOLEAN
, 8,
4746 TFS(&tfs_yes_no
), 0x80, NULL
, HFILL
}},
4748 { "AS Number", "bgp.cap.4as", FT_UINT32
, BASE_DEC
,
4749 NULL
, 0x0, NULL
, HFILL
}},
4751 { "Capability Dynamic", "bgp.cap.dc", FT_UINT8
, BASE_DEC
,
4752 VALS(capability_vals
), 0x0, NULL
, HFILL
}},
4753 { &hf_bgp_cap_ap_afi
,
4754 { "AFI", "bgp.cap.ap.afi", FT_UINT16
, BASE_DEC
,
4755 VALS(afn_vals
), 0x0, NULL
, HFILL
}},
4756 { &hf_bgp_cap_ap_safi
,
4757 { "SAFI", "bgp.cap.ap.safi", FT_UINT8
, BASE_DEC
,
4758 VALS(bgpattr_nlri_safi
), 0x0, NULL
, HFILL
}},
4759 { &hf_bgp_cap_ap_sendreceive
,
4760 { "Send/Receive", "bgp.cap.ap.sendreceive", FT_UINT8
, BASE_DEC
,
4761 VALS(orf_send_recv_vals
), 0x0, NULL
, HFILL
}},
4762 { &hf_bgp_cap_orf_afi
,
4763 { "AFI", "bgp.cap.orf.afi", FT_UINT16
, BASE_DEC
,
4764 VALS(afn_vals
), 0x0, NULL
, HFILL
}},
4765 { &hf_bgp_cap_orf_safi
,
4766 { "SAFI", "bgp.cap.orf.safi", FT_UINT8
, BASE_DEC
,
4767 VALS(bgpattr_nlri_safi
), 0x0, NULL
, HFILL
}},
4768 { &hf_bgp_cap_orf_number
,
4769 { "Number", "bgp.cap.orf.number", FT_UINT8
, BASE_DEC
,
4770 NULL
, 0x0, NULL
, HFILL
}},
4771 { &hf_bgp_cap_orf_type
,
4772 { "Type", "bgp.cap.orf.type", FT_UINT8
, BASE_DEC
,
4773 VALS(orf_type_vals
), 0x0, NULL
, HFILL
}},
4774 { &hf_bgp_cap_orf_sendreceive
,
4775 { "Send Receive", "bgp.cap.orf.sendreceive", FT_UINT8
, BASE_DEC
,
4776 VALS(orf_send_recv_vals
), 0x0, NULL
, HFILL
}},
4779 { &hf_bgp_update_withdrawn_routes_length
,
4780 { "Withdrawn Routes Length", "bgp.update.withdrawn_routes.length", FT_UINT16
, BASE_DEC
,
4781 NULL
, 0x0, NULL
, HFILL
}},
4782 { &hf_bgp_update_withdrawn_routes
,
4783 { "Withdrawn Routes", "bgp.update.withdrawn_routes.length", FT_NONE
, BASE_NONE
,
4784 NULL
, 0x0, NULL
, HFILL
}},
4786 { &hf_bgp_update_path_attribute_aggregator_as
,
4787 { "Aggregator AS", "bgp.update.path_attribute.aggregator_as", FT_UINT16
, BASE_DEC
,
4788 NULL
, 0x0, NULL
, HFILL
}},
4789 /* BGP update path attributes */
4790 { &hf_bgp_update_path_attributes
,
4791 { "Path attributes", "bgp.update.path_attributes", FT_NONE
, BASE_NONE
,
4792 NULL
, 0x0, NULL
, HFILL
}},
4793 { &hf_bgp_update_total_path_attribute_length
,
4794 { "Total Path Attribute Length", "bgp.update.path_attributes.length", FT_UINT16
, BASE_DEC
,
4795 NULL
, 0x0, NULL
, HFILL
}},
4796 { &hf_bgp_update_path_attribute_aggregator_origin
,
4797 { "Aggregator origin", "bgp.update.path_attribute.aggregator_origin", FT_IPv4
, BASE_NONE
,
4798 NULL
, 0x0, NULL
, HFILL
}},
4799 { &hf_bgp_update_path_attribute_as_path
,
4800 { "AS Path", "bgp.update.path_attribute.as_path", FT_UINT16
, BASE_DEC
,
4801 NULL
, 0x0, NULL
, HFILL
}},
4802 { &hf_bgp_update_community_as
,
4803 { "Community AS", "bgp.update.path_attribute.community_as", FT_UINT16
, BASE_DEC
,
4804 NULL
, 0x0, NULL
, HFILL
}},
4805 { &hf_bgp_update_path_attribute_community_value
,
4806 { "Community value", "bgp.update.path_attribute.community_value", FT_UINT16
, BASE_DEC
,
4807 NULL
, 0x0, NULL
, HFILL
}},
4808 { &hf_bgp_update_path_attribute_local_pref
,
4809 { "Local preference", "bgp.update.path_attribute.local_pref", FT_UINT32
, BASE_DEC
,
4810 NULL
, 0x0, NULL
, HFILL
}},
4811 { &hf_bgp_update_path_attribute_multi_exit_disc
,
4812 { "Multiple exit discriminator", "bgp.update.path_attribute.multi_exit_disc", FT_UINT32
, BASE_DEC
,
4813 NULL
, 0x0, NULL
, HFILL
}},
4814 { &hf_bgp_update_path_attribute_next_hop
,
4815 { "Next hop", "bgp.update.path_attribute.next_hop", FT_IPv4
, BASE_NONE
,
4816 NULL
, 0x0, NULL
, HFILL
}},
4817 { &hf_bgp_update_path_attribute_origin
,
4818 { "Origin", "bgp.update.path_attribute.origin", FT_UINT8
, BASE_DEC
,
4819 VALS(bgpattr_origin
), 0x0, NULL
, HFILL
}},
4820 { &hf_bgp_update_path_attribute
,
4821 { "Path Attribut", "bgp.update.path_attribute", FT_NONE
, BASE_NONE
,
4822 NULL
, 0x0, NULL
, HFILL
}},
4823 { &hf_bgp_update_path_attribute_flags
,
4824 { "Flags", "bgp.update.path_attribute.flags", FT_UINT8
, BASE_HEX
,
4825 NULL
, 0x0, NULL
, HFILL
}},
4826 { &hf_bgp_update_path_attribute_flags_optional
,
4827 { "Optional", "bgp.update.path_attribute.flags.optional", FT_BOOLEAN
, 8,
4828 TFS(&tfs_optional_wellknown
), BGP_ATTR_FLAG_OPTIONAL
, NULL
, HFILL
}},
4829 { &hf_bgp_update_path_attribute_flags_transitive
,
4830 { "Transitive", "bgp.update.path_attribute.flags.transitive", FT_BOOLEAN
, 8,
4831 TFS(&tfs_transitive_non_transitive
), BGP_ATTR_FLAG_TRANSITIVE
, NULL
, HFILL
}},
4832 { &hf_bgp_update_path_attribute_flags_partial
,
4833 { "Partial", "bgp.update.path_attribute.flags.partial", FT_BOOLEAN
, 8,
4834 TFS(&tfs_partial_complete
), BGP_ATTR_FLAG_PARTIAL
, NULL
, HFILL
}},
4835 { &hf_bgp_update_path_attribute_flags_extended_length
,
4836 { "Length", "bgp.update.path_attribute.flags.extended_length", FT_BOOLEAN
, 8,
4837 TFS(&tfs_extended_regular_length
), BGP_ATTR_FLAG_EXTENDED_LENGTH
, NULL
, HFILL
}},
4838 { &hf_bgp_update_path_attribute_type_code
,
4839 { "Type Code", "bgp.update.path_attribute.type_code", FT_UINT8
, BASE_DEC
,
4840 VALS(bgpattr_type
), 0x0, NULL
, HFILL
}},
4841 { &hf_bgp_update_path_attribute_length
,
4842 { "Length", "bgp.update.path_attribute.length", FT_UINT16
, BASE_DEC
,
4843 NULL
, 0x0, NULL
, HFILL
}},
4846 { &hf_bgp_update_path_attribute_originator_id
,
4847 { "Originator identifier", "bgp.update.path_attribute.originator_id", FT_IPv4
, BASE_NONE
,
4848 NULL
, 0x0, NULL
, HFILL
}},
4849 { &hf_bgp_update_path_attribute_cluster_list
,
4850 { "Cluster List", "bgp.path_attribute.cluster_list", FT_BYTES
, BASE_NONE
,
4851 NULL
, 0x0, NULL
, HFILL
}},
4853 /* RFC5512 : BGP Encapsulation SAFI and the BGP Tunnel Encapsulation Attribute */
4854 { &hf_bgp_update_encaps_tunnel_tlv_len
,
4855 { "length", "bgp.update.encaps_tunnel_tlv_len", FT_UINT16
,
4856 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
4857 { &hf_bgp_update_encaps_tunnel_tlv_type
,
4858 { "Type code", "bgp.update.encaps_tunnel_tlv_type", FT_UINT16
, BASE_DEC
,
4859 VALS(tunnel_type
), 0x0, NULL
, HFILL
}},
4860 { &hf_bgp_update_encaps_tunnel_subtlv_len
,
4861 { "length", "bgp.update.encaps_tunnel_tlv_sublen", FT_UINT8
,
4862 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
4863 { &hf_bgp_update_encaps_tunnel_subtlv_type
,
4864 { "Type code", "bgp.update.encaps_tunnel_subtlv_type", FT_UINT8
, BASE_DEC
,
4865 VALS(subtlv_type
), 0x0, NULL
, HFILL
}},
4867 /* BGP update path attribut SSA SAFI (deprecated IETF draft) */
4869 { "Transitive bit", "bgp.ssa_t", FT_BOOLEAN
, 8,
4870 NULL
, 0x80, "SSA Transitive bit", HFILL
}},
4872 { "SSA Type", "bgp.ssa_type", FT_UINT16
, BASE_DEC
,
4873 VALS(bgp_ssa_type
), 0x7FFF, NULL
, HFILL
}},
4875 { "Length", "bgp.ssa_len", FT_UINT16
, BASE_DEC
,
4876 NULL
, 0x0, "SSA Length", HFILL
}},
4877 { &hf_bgp_ssa_value
,
4878 { "Value", "bgp.ssa_value", FT_BYTES
, BASE_NONE
,
4879 NULL
, 0x0, "SSA Value", HFILL
}},
4880 { &hf_bgp_ssa_l2tpv3_pref
,
4881 { "Preference", "bgp.ssa_l2tpv3_pref", FT_UINT16
, BASE_DEC
,
4882 NULL
, 0x0, NULL
, HFILL
}},
4883 { &hf_bgp_ssa_l2tpv3_s
,
4884 { "Sequencing bit", "bgp.ssa_l2tpv3_s", FT_BOOLEAN
, 8,
4885 NULL
, 0x80, "Sequencing S-bit", HFILL
}},
4886 { &hf_bgp_ssa_l2tpv3_unused
,
4887 { "Unused", "bgp.ssa_l2tpv3_Unused", FT_BOOLEAN
, 8,
4888 NULL
, 0x7F, "Unused Flags", HFILL
}},
4889 { &hf_bgp_ssa_l2tpv3_cookie_len
,
4890 { "Cookie Length", "bgp.ssa_l2tpv3_cookie_len", FT_UINT8
, BASE_DEC
,
4891 NULL
, 0x0, NULL
, HFILL
}},
4892 { &hf_bgp_ssa_l2tpv3_session_id
,
4893 { "Session ID", "bgp.ssa_l2tpv3_session_id", FT_UINT32
, BASE_DEC
,
4894 NULL
, 0x0, NULL
, HFILL
}},
4895 { &hf_bgp_ssa_l2tpv3_cookie
,
4896 { "Cookie", "bgp.ssa_l2tpv3_cookie", FT_BYTES
, BASE_NONE
,
4897 NULL
, 0x0, NULL
, HFILL
}},
4898 { &hf_bgp_withdrawn_prefix
,
4899 { "Withdrawn prefix", "bgp.withdrawn_prefix", FT_IPv4
, BASE_NONE
,
4900 NULL
, 0x0, NULL
, HFILL
}},
4902 /* NLRI header description */
4903 { &hf_bgp_update_nlri
,
4904 { "Network Layer Reachability Information (NLRI)", "bgp.update.nlri", FT_NONE
, BASE_NONE
,
4905 NULL
, 0x0, NULL
, HFILL
}},
4906 /* Global NLRI description */
4907 { &hf_bgp_mp_reach_nlri_ipv4_prefix
,
4908 { "MP Reach NLRI IPv4 prefix", "bgp.mp_reach_nlri_ipv4_prefix", FT_IPv4
, BASE_NONE
,
4909 NULL
, 0x0, NULL
, HFILL
}},
4910 { &hf_bgp_mp_unreach_nlri_ipv4_prefix
,
4911 { "MP Unreach NLRI IPv4 prefix", "bgp.mp_unreach_nlri_ipv4_prefix", FT_IPv4
, BASE_NONE
,
4912 NULL
, 0x0, NULL
, HFILL
}},
4913 { &hf_bgp_mp_nlri_tnl_id
,
4914 { "MP Reach NLRI Tunnel Identifier", "bgp.mp_nlri_tnl_id", FT_UINT16
, BASE_HEX
,
4915 NULL
, 0x0, NULL
, HFILL
}},
4916 { &hf_bgp_nlri_prefix
,
4917 { "NLRI prefix", "bgp.nlri_prefix", FT_IPv4
, BASE_NONE
,
4918 NULL
, 0x0, NULL
, HFILL
}},
4919 { &hf_bgp_nlri_path_id
,
4920 { "NLRI path id", "bgp.nlri_path_id", FT_UINT32
, BASE_DEC
,
4921 NULL
, 0x0, NULL
, HFILL
}},
4923 /* mcast vpn nlri and capability */
4924 { &hf_bgp_mcast_vpn_nlri_t
,
4925 { "MCAST-VPN nlri", "bgp.mcast_vpn_nlri", FT_BYTES
, BASE_NONE
,
4926 NULL
, 0x0, NULL
, HFILL
}},
4927 { &hf_bgp_mcast_vpn_nlri_route_type
,
4928 { "Route Type", "bgp.mcast_vpn_nlri_route_type", FT_UINT8
,
4929 BASE_DEC
, VALS(mcast_vpn_route_type
), 0x0, NULL
, HFILL
}},
4930 { &hf_bgp_mcast_vpn_nlri_length
,
4931 { "Length", "bgp.mcast_vpn_nlri_length", FT_UINT8
,
4932 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
4933 { &hf_bgp_mcast_vpn_nlri_rd
,
4934 { "Route Distinguisher", "bgp.mcast_vpn_nlri_rd", FT_BYTES
,
4935 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
4936 { &hf_bgp_mcast_vpn_nlri_origin_router_ipv4
,
4937 { "Originating Router", "bgp.mcast_vpn_nlri_origin_router_ipv4", FT_IPv4
,
4938 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
4939 { &hf_bgp_mcast_vpn_nlri_origin_router_ipv6
,
4940 { "Originating Router", "bgp.mcast_vpn_nlri_origin_router_ipv6", FT_IPv6
,
4941 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
4942 { &hf_bgp_mcast_vpn_nlri_source_as
,
4943 { "Source AS", "bgp.mcast_vpn_nlri_source_as", FT_UINT16
,
4944 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
4945 { &hf_bgp_mcast_vpn_nlri_source_length
,
4946 { "Multicast Source Length", "bgp.mcast_vpn_nlri_source_length", FT_UINT8
,
4947 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
4948 { &hf_bgp_mcast_vpn_nlri_group_length
,
4949 { "Multicast Group Length", "bgp.mcast_vpn_nlri_group_length", FT_UINT8
,
4950 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
4951 { &hf_bgp_mcast_vpn_nlri_source_addr_ipv4
,
4952 { "Multicast Source Address", "bgp.mcast_vpn_nlri_source_addr_ipv4", FT_IPv4
,
4953 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
4954 { &hf_bgp_mcast_vpn_nlri_source_addr_ipv6
,
4955 { "Multicast Source Address", "bgp.mcast_vpn_nlri_source_addr_ipv6", FT_IPv6
,
4956 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
4957 { &hf_bgp_mcast_vpn_nlri_group_addr_ipv4
,
4958 { "Multicast Group Address", "bgp.mcast_vpn_nlri_group_addr_ipv4", FT_IPv4
,
4959 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
4960 { &hf_bgp_mcast_vpn_nlri_group_addr_ipv6
,
4961 { "Group Address", "bgp.mcast_vpn_nlri_group_addr_ipv6", FT_IPv6
,
4962 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
4963 { &hf_bgp_mcast_vpn_nlri_route_key
,
4964 { "Route Key", "bgp.mcast_vpn_nlri_route_key", FT_BYTES
,
4965 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
4966 /* Bgp flow spec nlri and capability */
4967 { &hf_bgp_flowspec_nlri_t
,
4968 { "FLOW-SPEC nlri", "bgp.flowspec_nlri", FT_BYTES
, BASE_NONE
,
4969 NULL
, 0x0, NULL
, HFILL
}},
4970 { &hf_bgp_flowspec_nlri_filter
,
4971 { "Filter", "bgp.flowspec_nlri.filter", FT_NONE
, BASE_NONE
,
4972 NULL
, 0x0, NULL
, HFILL
}},
4973 { &hf_bgp_flowspec_nlri_filter_type
,
4974 { "Filter type", "bgp.flowspec_nlri.filter_type", FT_UINT8
, BASE_DEC
,
4975 VALS(flowspec_nlri_opvaluepair_type
), 0x0, NULL
, HFILL
}},
4976 { &hf_bgp_flowspec_nlri_length
,
4977 { "NRLI length", "bgp.flowspec_nlri.length", FT_UINT32
, BASE_DEC
,
4978 NULL
, 0x0, NULL
, HFILL
}},
4979 { &hf_bgp_flowspec_nlri_op_flags
,
4980 { "Operator flags", "bgp.flowspec_nlri.opflags", FT_UINT8
, BASE_HEX
,
4981 NULL
, 0x0, NULL
, HFILL
}},
4982 { &hf_bgp_flowspec_nlri_dst_pref_ipv4
,
4983 { "Destination IP filter", "bgp.flowspec_nlri.dst_prefix_filter", FT_IPv4
,
4984 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
4985 { &hf_bgp_flowspec_nlri_src_pref_ipv4
,
4986 { "Source IP filter", "bgp.flowspec_nlri.src_prefix_filter", FT_IPv4
,
4987 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
4988 { &hf_bgp_flowspec_nlri_op_eol
,
4989 { "end-of-list", "bgp.flowspec_nlri.op.eol", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), BGPNLRI_FSPEC_END_OF_LST
,
4991 { &hf_bgp_flowspec_nlri_op_and
,
4992 { "and", "bgp.flowspec_nlri.op.and", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), BGPNLRI_FSPEC_AND_BIT
,
4994 { &hf_bgp_flowspec_nlri_op_val_len
,
4995 { "Value length", "bgp.flowspec_nlri.op.val_len", FT_UINT8
, BASE_DEC
, &flow_spec_op_len_val
, BGPNLRI_FSPEC_VAL_LEN
,
4997 { &hf_bgp_flowspec_nlri_op_un_bit4
,
4998 { "Reserved", "bgp.flowspec_nlri.op.un_bit4", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), BGPNLRI_FSPEC_UNUSED_BIT4
,
4999 "Unused (must be zero)",HFILL
}},
5000 { &hf_bgp_flowspec_nlri_op_un_bit5
,
5001 { "Reserved", "bgp.flowspec_nlri.op.un_bit5", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), BGPNLRI_FSPEC_UNUSED_BIT5
,
5002 "Unused (must be zero)", HFILL
}},
5003 { &hf_bgp_flowspec_nlri_dec_val_8
,
5004 { "Decimal value", "bgp.flowspec_nlri.dec_val_8", FT_UINT8
, BASE_DEC
, NULL
, 0X0,
5006 { &hf_bgp_flowspec_nlri_dec_val_16
,
5007 { "Decimal value", "bgp.flowspec_nlri.dec_val_16", FT_UINT16
, BASE_DEC
, NULL
, 0X0,
5009 { &hf_bgp_flowspec_nlri_dec_val_32
,
5010 { "Decimal value", "bgp.flowspec_nlri.dec_val_32", FT_UINT32
, BASE_DEC
, NULL
, 0X0,
5012 { &hf_bgp_flowspec_nlri_dec_val_64
,
5013 { "Decimal value", "bgp.flowspec_nlri.dec_val_64", FT_UINT64
, BASE_DEC
, NULL
, 0X0,
5015 { &hf_bgp_flowspec_nlri_op_lt
,
5016 { "less than", "bgp.flowspec_nlri.op.lt", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), BGPNLRI_FSPEC_LESS_THAN
,
5018 { &hf_bgp_flowspec_nlri_op_gt
,
5019 { "greater than", "bgp.flowspec_nlri.op.gt", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), BGPNLRI_FSPEC_GREATER_THAN
,
5021 { &hf_bgp_flowspec_nlri_op_eq
,
5022 { "equal", "bgp.flowspec_nlri.op.equal", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), BGPNLRI_FSPEC_EQUAL
,
5024 { &hf_bgp_flowspec_nlri_op_flg_not
,
5025 { "logical negation", "bgp.flowspec_nlri.op.flg_not", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), BGPNLRI_FSPEC_TCPF_NOTBIT
,
5027 { &hf_bgp_flowspec_nlri_op_flg_match
,
5028 { "Match bit", "bgp.flowspec_nlri.op.flg_match", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), BGPNLRI_FSPEC_TCPF_MATCHBIT
,
5030 { &hf_bgp_flowspec_nlri_tcp_flags
,
5031 { "TCP flags", "bgp.flowspec_nlri.val_tcp.flags", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
5033 { &hf_bgp_flowspec_nlri_tcp_flags_cwr
,
5034 { "Congestion Window Reduced (CWR)", "bgp.flowspec_nlri.val_tcp.flags.cwr", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), BGPNLRI_FSPEC_TH_CWR
,
5036 { &hf_bgp_flowspec_nlri_tcp_flags_ecn
,
5037 { "ECN-Echo", "bgp.flowspec_nlri.val_tcp.flags.ecn", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), BGPNLRI_FSPEC_TH_ECN
,
5039 { &hf_bgp_flowspec_nlri_tcp_flags_urg
,
5040 { "Urgent", "bgp.flowspec_nlri.val_tcp.flags.urg", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), BGPNLRI_FSPEC_TH_URG
,
5042 { &hf_bgp_flowspec_nlri_tcp_flags_ack
,
5043 { "Acknowledgment", "bgp.flowspec_nlri.val_tcp.flags.ack", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), BGPNLRI_FSPEC_TH_ACK
,
5045 { &hf_bgp_flowspec_nlri_tcp_flags_push
,
5046 { "Push", "bgp.flowspec_nlri.val_tcp.flags.push", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), BGPNLRI_FSPEC_TH_PUSH
,
5048 { &hf_bgp_flowspec_nlri_tcp_flags_reset
,
5049 { "Reset", "bgp.flowspec_nlri.val_tcp.flags.reset", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), BGPNLRI_FSPEC_TH_RST
,
5051 { &hf_bgp_flowspec_nlri_tcp_flags_syn
,
5052 { "Syn", "bgp.flowspec_nlri.val_tcp.flags.syn", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), BGPNLRI_FSPEC_TH_SYN
,
5054 { &hf_bgp_flowspec_nlri_tcp_flags_fin
,
5055 { "Fin", "bgp.flowspec_nlri.val_tcp.flags.fin", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), BGPNLRI_FSPEC_TH_FIN
,
5057 { &hf_bgp_flowspec_nlri_fflag
,
5058 { "Fragment Flag", "bgp.flowspec_nlri.val_frag", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
5060 { &hf_bgp_flowspec_nlri_fflag_lf
,
5061 { "Last fragment", "bgp.flowspec_nlri.val_frag_lf", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), BGPNLRI_FSPEC_FG_LF
,
5063 { &hf_bgp_flowspec_nlri_fflag_ff
,
5064 { "First fragment", "bgp.flowspec_nlri.val_frag_ff", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), BGPNLRI_FSPEC_FG_FF
,
5066 { &hf_bgp_flowspec_nlri_fflag_isf
,
5067 { "Is a fragment", "bgp.flowspec_nlri.val_frag_isf", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), BGPNLRI_FSPEC_FG_ISF
,
5069 { &hf_bgp_flowspec_nlri_fflag_df
,
5070 { "Don't fragment", "bgp.flowspec_nlri.val_frag_df", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), BGPNLRI_FSPEC_FG_DF
,
5072 { &hf_bgp_flowspec_nlri_dscp
,
5073 { "Differentiated Services Codepoint", "bgp.flowspec_nlri.val_dsfield", FT_UINT8
, BASE_HEX
| BASE_EXT_STRING
,
5074 &dscp_vals_ext
, BGPNLRI_FSPEC_DSCP_BITMASK
, NULL
, HFILL
}},
5075 /* end of bgp flow spec */
5076 /* BGP update safi ndt nlri draft-nalawade-idr-mdt-safi-03 */
5077 { &hf_bgp_mdt_nlri_safi_rd
,
5078 { "Route Distinguisher", "bgp.mdt_safi_rd", FT_BYTES
,
5079 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
5080 { &hf_bgp_mdt_nlri_safi_ipv4_addr
,
5081 { "IPv4 Address", "bgp.mdt_safi_ipv4_addr", FT_IPv4
,
5082 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
5083 { &hf_bgp_mdt_nlri_safi_group_addr
,
5084 { "Group Address", "bgp.mdt_safi_group_addr", FT_IPv4
,
5085 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
5086 /* BGP update extended community header field */
5087 /* BGP update extended community flow spec RFC 5575 */
5088 { &hf_bgp_ext_com_flow_act_samp_act
,
5089 { "Sample", "bgp.ext_com_flow.sample", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
),
5090 BGP_EXT_COM_FSPEC_ACT_S
, NULL
, HFILL
}},
5091 { &hf_bgp_ext_com_flow_act_term_act
,
5092 { "Terminal action", "bgp.ext_com_flow.traff_act", FT_BOOLEAN
, 8, TFS(&tfs_set_notset
),BGP_EXT_COM_FSPEC_ACT_T
,NULL
, HFILL
}},
5093 { &hf_bgp_ext_com_flow_rate_float
,
5094 { "Rate shaper", "bgp.ext_com_flow.rate_limit", FT_FLOAT
, BASE_NONE
,
5095 NULL
, 0x0, NULL
, HFILL
}},
5096 { &hf_bgp_ext_com_flow_act_allset
,
5097 { "5 Bytes", "bgp.flowspec_ext_com.emptybytes", FT_BYTES
, BASE_NONE
,
5098 NULL
, 0x0, "Must be set to all 0", HFILL
}},
5099 { &hf_bgp_ext_com_flow_redir
,
5100 { "Action Traffic redirect", "bgp.ext_com_flow.redirect", FT_NONE
, BASE_NONE
,
5101 NULL
, 0x0, NULL
, HFILL
}},
5102 { &hf_bgp_ext_com_flow_redir_as
,
5103 { "AS", "bgp.ext_com_flow.redirect.as16", FT_UINT16
, BASE_DEC
,
5104 NULL
, 0x0, NULL
, HFILL
}},
5105 { &hf_bgp_ext_com_flow_redir_an
,
5106 { "AN", "bgp.ext_com_flow.redirect.an32", FT_UINT32
, BASE_DEC
,
5107 NULL
, 0x0, NULL
, HFILL
}},
5109 /* BGP QoS propagation draft-knoll-idr-qos-attribute */
5110 { &hf_bgp_ext_com_qos_flags
,
5111 { "Flags", "bgp.ext_com_qos.flags", FT_UINT8
, BASE_HEX
,
5112 NULL
, 0, NULL
, HFILL
}},
5113 { &hf_bgp_ext_com_qos_flags_remarking
,
5114 { "Remarking", "bgp.ext_com_qos.flags.remarking", FT_BOOLEAN
, 8,
5115 TFS(&tfs_yes_no
), 0x10, NULL
, HFILL
}},
5116 { &hf_bgp_ext_com_qos_flags_ignore_remarking
,
5117 { "Ignore remarking", "bgp.ext_com_qos.flags.ignore_remarking", FT_BOOLEAN
, 8,
5118 TFS(&tfs_yes_no
), 0x08, NULL
, HFILL
}},
5119 { &hf_bgp_ext_com_qos_flags_agg_marking
,
5120 { "Aggegation of markins", "bgp.ext_com_qos.flags.agg_marking", FT_BOOLEAN
, 8,
5121 TFS(&tfs_yes_no
), 0x04, NULL
, HFILL
}},
5122 { &hf_bgp_ext_com_cos_flags
,
5123 { "Flags byte 1", "bgp.ext_com_cos.flags", FT_UINT8
, BASE_HEX
,
5124 NULL
, 0, NULL
, HFILL
}},
5125 { &hf_bgp_ext_com_cos_flags_be
,
5126 { "BE class", "bgp.ext_com_cos.flags.be", FT_BOOLEAN
, 8,
5127 TFS(&tfs_supported_not_supported
), 0x80, NULL
, HFILL
}},
5128 { &hf_bgp_ext_com_cos_flags_ef
,
5129 { "EF class", "bgp.ext_com_cos.flags.ef", FT_BOOLEAN
, 8,
5130 TFS(&tfs_supported_not_supported
), 0x40, NULL
, HFILL
}},
5131 { &hf_bgp_ext_com_cos_flags_af
,
5132 { "AF class", "bgp.ext_com_cos.flags.af", FT_BOOLEAN
, 8,
5133 TFS(&tfs_supported_not_supported
), 0x20, NULL
, HFILL
}},
5134 { &hf_bgp_ext_com_cos_flags_le
,
5135 { "LE class", "bgp.ext_com_cos.flags.le", FT_BOOLEAN
, 8,
5136 TFS(&tfs_supported_not_supported
), 0x10, NULL
, HFILL
}},
5137 { &hf_bgp_ext_com_qos_set_number
,
5138 { "QoS Set Number", "bgp.ext_com_qos.set_number", FT_UINT8
, BASE_HEX
,
5139 NULL
, 0, NULL
, HFILL
}},
5140 { &hf_bgp_ext_com_qos_tech_type
,
5141 { "Technology Type", "bgp.ext_com_qos.tech_type", FT_UINT8
, BASE_HEX
,
5142 VALS(qos_tech_type
), 0, NULL
, HFILL
}},
5143 { &hf_bgp_ext_com_qos_marking_o
,
5144 { "QoS Marking O", "bgp.ext_com_qos.marking_o", FT_UINT16
, BASE_HEX
,
5145 NULL
, 0, NULL
, HFILL
}},
5146 { &hf_bgp_ext_com_qos_marking_a
,
5147 { "QoS Marking A", "bgp.ext_com_qos.marking_a", FT_UINT8
, BASE_HEX_DEC
,
5148 NULL
, 0, NULL
, HFILL
}},
5149 { &hf_bgp_ext_com_qos_default_to_zero
,
5150 { "Defaults to zero", "bgp.ext_com_qos.default_to_zero", FT_UINT8
, BASE_HEX
,
5151 NULL
, 0, NULL
, HFILL
}},
5152 /* BGP L2 extended community RFC 4761, RFC 6624 */
5153 /* draft-ietf-l2vpn-vpls-multihoming */
5154 { &hf_bgp_ext_com_l2_encaps
,
5155 { "Encaps Type", "bgp.ext_com_l2.encaps_type", FT_UINT8
, BASE_DEC
,
5156 VALS(bgp_l2vpn_encaps
), 0, NULL
, HFILL
}},
5157 { &hf_bgp_ext_com_l2_c_flags
,
5158 { "Control Flags", "bgp.ext_com_l2.c_flags", FT_UINT8
, BASE_HEX
,
5159 NULL
, 0x0, NULL
, HFILL
}},
5160 { &hf_bgp_ext_com_l2_flag_d
,
5161 { "Down flag", "bgp.ext_com_l2.flag_d",FT_BOOLEAN
, 8,
5162 TFS(&tfs_set_notset
), BGP_EXT_COM_L2_FLAG_D
, NULL
, HFILL
}},
5163 { &hf_bgp_ext_com_l2_flag_z1
,
5164 { "Unassigned", "bgp.ext_com_l2.flag_z1",FT_UINT8
, BASE_DEC
,
5165 NULL
, BGP_EXT_COM_L2_FLAG_Z1
, "Must be Zero", HFILL
}},
5166 { &hf_bgp_ext_com_l2_flag_f
,
5167 { "Flush flag", "bgp.ext_com_l2.flag_f",FT_BOOLEAN
, 8,
5168 TFS(&tfs_set_notset
), BGP_EXT_COM_L2_FLAG_F
, NULL
, HFILL
}},
5169 { &hf_bgp_ext_com_l2_flag_z345
,
5170 { "Unassigned", "bgp.ext_com_l2.flag_z345",FT_UINT8
, BASE_DEC
,
5171 NULL
, BGP_EXT_COM_L2_FLAG_Z345
, "Must be Zero", HFILL
}},
5172 { &hf_bgp_ext_com_l2_flag_c
,
5173 { "C flag", "bgp.ext_com_l2.flag_c",FT_BOOLEAN
, 8,
5174 TFS(&tfs_set_notset
), BGP_EXT_COM_L2_FLAG_C
, NULL
, HFILL
}},
5175 { &hf_bgp_ext_com_l2_flag_s
,
5176 { "S flag", "bgp.ext_com_l2.flag_s",FT_BOOLEAN
, 8,
5177 TFS(&tfs_set_notset
), BGP_EXT_COM_L2_FLAG_S
, NULL
, HFILL
}},
5178 { &hf_bgp_ext_com_l2_mtu
,
5179 { "Layer-2 MTU", "bgp.ext_com_l2.l2_mtu", FT_UINT16
, BASE_DEC
,
5180 NULL
, 0x0, NULL
, HFILL
}},
5183 static gint
*ett
[] = {
5189 &ett_bgp_attr_flags
,
5191 &ett_bgp_mp_reach_nlri
,
5192 &ett_bgp_mp_unreach_nlri
,
5197 &ett_bgp_notification
,
5198 &ett_bgp_route_refresh
,
5199 &ett_bgp_capability
,
5201 &ett_bgp_as_path_segments
,
5202 &ett_bgp_communities
,
5203 &ett_bgp_cluster_list
,
5207 &ett_bgp_extended_communities
,
5208 &ett_bgp_extended_com_fspec_redir
,
5209 &ett_bgp_ext_com_flags
,
5210 &ett_bgp_ext_com_l2_flags
,
5212 &ett_bgp_ssa_subtree
,
5215 &ett_bgp_mcast_vpn_nlri
,
5216 &ett_bgp_flow_spec_nlri
,
5217 &ett_bgp_flow_spec_nlri_filter
,
5218 &ett_bgp_flow_spec_nlri_op_flags
,
5219 &ett_bgp_flow_spec_nlri_tcp
,
5220 &ett_bgp_flow_spec_nlri_ff
,
5221 &ett_bgp_tunnel_tlv
,
5222 &ett_bgp_tunnel_tlv_subtree
,
5223 &ett_bgp_tunnel_subtlv
,
5224 &ett_bgp_tunnel_subtlv_subtree
,
5226 static ei_register_info ei
[] = {
5227 { &ei_bgp_cap_len_bad
, { "bgp.cap.length.bad", PI_MALFORMED
, PI_ERROR
, "Capability length is wrong", EXPFILL
}},
5228 { &ei_bgp_cap_gr_helper_mode_only
, { "bgp.cap.gr.helper_mode_only", PI_REQUEST_CODE
, PI_CHAT
, "Graceful Restart Capability supported in Helper mode only", EXPFILL
}},
5229 { &ei_bgp_notify_minor_unknown
, { "bgp.notify.minor_error.unknown", PI_UNDECODED
, PI_NOTE
, "Unknown notification error", EXPFILL
}},
5230 { &ei_bgp_route_refresh_orf_type_unknown
, { "bgp.route_refresh.orf.type.unknown", PI_CHAT
, PI_ERROR
, "ORFEntry-Unknown", EXPFILL
}},
5231 { &ei_bgp_length_invalid
, { "bgp.length.invalid", PI_MALFORMED
, PI_ERROR
, "Length is invalid", EXPFILL
}},
5232 { &ei_bgp_afi_type_not_supported
, { "bgp.afi_type_not_supported", PI_PROTOCOL
, PI_ERROR
, "AFI Type not supported", EXPFILL
}},
5235 module_t
*bgp_module
;
5236 expert_module_t
* expert_bgp
;
5238 static const enum_val_t asn_len
[] = {
5239 {"auto-detect", "Auto-detect", 0},
5240 {"2", "2 octet", 2},
5241 {"4", "4 octet", 4},
5245 proto_bgp
= proto_register_protocol("Border Gateway Protocol",
5247 proto_register_field_array(proto_bgp
, hf
, array_length(hf
));
5248 proto_register_subtree_array(ett
, array_length(ett
));
5249 expert_bgp
= expert_register_protocol(proto_bgp
);
5250 expert_register_field_array(expert_bgp
, ei
, array_length(ei
));
5252 bgp_module
= prefs_register_protocol(proto_bgp
, NULL
);
5253 prefs_register_bool_preference(bgp_module
, "desegment",
5254 "Reassemble BGP messages spanning multiple TCP segments",
5255 "Whether the BGP dissector should reassemble messages spanning multiple TCP segments."
5256 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
5258 prefs_register_enum_preference(bgp_module
, "asn_len",
5259 "Length of the AS number",
5260 "BGP dissector detect the length of the AS number in AS_PATH attributes automatically or manually (NOTE: Automatic detection is not 100% accurate)",
5261 &bgp_asn_len
, asn_len
, FALSE
);
5265 proto_reg_handoff_bgp(void)
5267 dissector_handle_t bgp_handle
;
5269 bgp_handle
= create_dissector_handle(dissect_bgp
, proto_bgp
);
5270 dissector_add_uint("tcp.port", BGP_TCP_PORT
, bgp_handle
);
5273 * Editor modelines - http://www.wireshark.org/tools/modelines.html
5278 * indent-tabs-mode: nil
5281 * ex: set shiftwidth=4 tabstop=8 expandtab:
5282 * :indentSize=4:tabSize=8:noTabs=true: