tcpdump  4.99.1
About: tcpdump is a tool for network monitoring and data acquisition.
  Fossies Dox: tcpdump-4.99.1.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

print-bgp.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1999 WIDE Project.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the project nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * Extensively modified by Hannes Gredler (hannes@gredler.at) for more
30  * complete BGP support.
31  */
32 
33 /* \summary: Border Gateway Protocol (BGP) printer */
34 
35 /* specification: RFC 4271 */
36 
37 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #endif
40 
41 #include "netdissect-stdinc.h"
42 
43 #include <stdio.h>
44 #include <string.h>
45 
46 #include "netdissect.h"
47 #include "addrtoname.h"
48 #include "extract.h"
49 #include "af.h"
50 #include "l2vpn.h"
51 
52 struct bgp {
56 };
57 #define BGP_SIZE 19 /* unaligned */
58 
59 #define BGP_OPEN 1
60 #define BGP_UPDATE 2
61 #define BGP_NOTIFICATION 3
62 #define BGP_KEEPALIVE 4
63 #define BGP_ROUTE_REFRESH 5
64 
65 static const struct tok bgp_msg_values[] = {
66  { BGP_OPEN, "Open"},
67  { BGP_UPDATE, "Update"},
68  { BGP_NOTIFICATION, "Notification"},
69  { BGP_KEEPALIVE, "Keepalive"},
70  { BGP_ROUTE_REFRESH, "Route Refresh"},
71  { 0, NULL}
72 };
73 
74 struct bgp_open {
83  /* options should follow */
84 };
85 #define BGP_OPEN_SIZE 29 /* unaligned */
86 
87 struct bgp_opt {
90  /* variable length */
91 };
92 #define BGP_OPT_SIZE 2 /* some compilers may pad to 4 bytes */
93 #define BGP_CAP_HEADER_SIZE 2 /* some compilers may pad to 4 bytes */
94 
101 };
102 #define BGP_NOTIFICATION_SIZE 21 /* unaligned */
103 
107  nd_uint8_t type; /* No padding after this; afi is, in fact, not aligned */
111 };
112 #define BGP_ROUTE_REFRESH_SIZE 23
113 
114 #define bgp_attr_lenlen(flags, p) \
115  (((flags) & 0x10) ? 2U : 1U)
116 #define bgp_attr_len(flags, p) \
117  (((flags) & 0x10) ? GET_BE_U_2(p) : GET_U_1(p))
118 
119 #define BGPTYPE_ORIGIN 1
120 #define BGPTYPE_AS_PATH 2
121 #define BGPTYPE_NEXT_HOP 3
122 #define BGPTYPE_MULTI_EXIT_DISC 4
123 #define BGPTYPE_LOCAL_PREF 5
124 #define BGPTYPE_ATOMIC_AGGREGATE 6
125 #define BGPTYPE_AGGREGATOR 7
126 #define BGPTYPE_COMMUNITIES 8 /* RFC1997 */
127 #define BGPTYPE_ORIGINATOR_ID 9 /* RFC4456 */
128 #define BGPTYPE_CLUSTER_LIST 10 /* RFC4456 */
129 #define BGPTYPE_DPA 11 /* deprecated, draft-ietf-idr-bgp-dpa */
130 #define BGPTYPE_ADVERTISERS 12 /* deprecated RFC1863 */
131 #define BGPTYPE_RCID_PATH 13 /* deprecated RFC1863 */
132 #define BGPTYPE_MP_REACH_NLRI 14 /* RFC4760 */
133 #define BGPTYPE_MP_UNREACH_NLRI 15 /* RFC4760 */
134 #define BGPTYPE_EXTD_COMMUNITIES 16 /* RFC4360 */
135 #define BGPTYPE_AS4_PATH 17 /* RFC6793 */
136 #define BGPTYPE_AGGREGATOR4 18 /* RFC6793 */
137 #define BGPTYPE_PMSI_TUNNEL 22 /* RFC6514 */
138 #define BGPTYPE_TUNNEL_ENCAP 23 /* RFC5512 */
139 #define BGPTYPE_TRAFFIC_ENG 24 /* RFC5543 */
140 #define BGPTYPE_IPV6_EXTD_COMMUNITIES 25 /* RFC5701 */
141 #define BGPTYPE_AIGP 26 /* RFC7311 */
142 #define BGPTYPE_PE_DISTINGUISHER_LABEL 27 /* RFC6514 */
143 #define BGPTYPE_ENTROPY_LABEL 28 /* RFC6790 */
144 #define BGPTYPE_LARGE_COMMUNITY 32 /* draft-ietf-idr-large-community-05 */
145 #define BGPTYPE_ATTR_SET 128 /* RFC6368 */
146 
147 #define BGP_MP_NLRI_MINSIZE 3 /* End of RIB Marker detection */
148 
149 static const struct tok bgp_attr_values[] = {
150  { BGPTYPE_ORIGIN, "Origin"},
151  { BGPTYPE_AS_PATH, "AS Path"},
152  { BGPTYPE_AS4_PATH, "AS4 Path"},
153  { BGPTYPE_NEXT_HOP, "Next Hop"},
154  { BGPTYPE_MULTI_EXIT_DISC, "Multi Exit Discriminator"},
155  { BGPTYPE_LOCAL_PREF, "Local Preference"},
156  { BGPTYPE_ATOMIC_AGGREGATE, "Atomic Aggregate"},
157  { BGPTYPE_AGGREGATOR, "Aggregator"},
158  { BGPTYPE_AGGREGATOR4, "Aggregator4"},
159  { BGPTYPE_COMMUNITIES, "Community"},
160  { BGPTYPE_ORIGINATOR_ID, "Originator ID"},
161  { BGPTYPE_CLUSTER_LIST, "Cluster List"},
162  { BGPTYPE_DPA, "DPA"},
163  { BGPTYPE_ADVERTISERS, "Advertisers"},
164  { BGPTYPE_RCID_PATH, "RCID Path / Cluster ID"},
165  { BGPTYPE_MP_REACH_NLRI, "Multi-Protocol Reach NLRI"},
166  { BGPTYPE_MP_UNREACH_NLRI, "Multi-Protocol Unreach NLRI"},
167  { BGPTYPE_EXTD_COMMUNITIES, "Extended Community"},
168  { BGPTYPE_PMSI_TUNNEL, "PMSI Tunnel"},
169  { BGPTYPE_TUNNEL_ENCAP, "Tunnel Encapsulation"},
170  { BGPTYPE_TRAFFIC_ENG, "Traffic Engineering"},
171  { BGPTYPE_IPV6_EXTD_COMMUNITIES, "IPv6 Extended Community"},
172  { BGPTYPE_AIGP, "Accumulated IGP Metric"},
173  { BGPTYPE_PE_DISTINGUISHER_LABEL, "PE Distinguisher Label"},
174  { BGPTYPE_ENTROPY_LABEL, "Entropy Label"},
175  { BGPTYPE_LARGE_COMMUNITY, "Large Community"},
176  { BGPTYPE_ATTR_SET, "Attribute Set"},
177  { 255, "Reserved for development"},
178  { 0, NULL}
179 };
180 
181 #define BGP_AS_SET 1
182 #define BGP_AS_SEQUENCE 2
183 #define BGP_CONFED_AS_SEQUENCE 3 /* draft-ietf-idr-rfc3065bis-01 */
184 #define BGP_CONFED_AS_SET 4 /* draft-ietf-idr-rfc3065bis-01 */
185 
186 #define BGP_AS_SEG_TYPE_MIN BGP_AS_SET
187 #define BGP_AS_SEG_TYPE_MAX BGP_CONFED_AS_SET
188 
189 static const struct tok bgp_as_path_segment_open_values[] = {
190  { BGP_AS_SEQUENCE, ""},
191  { BGP_AS_SET, "{ "},
192  { BGP_CONFED_AS_SEQUENCE, "( "},
193  { BGP_CONFED_AS_SET, "({ "},
194  { 0, NULL}
195 };
196 
197 static const struct tok bgp_as_path_segment_close_values[] = {
198  { BGP_AS_SEQUENCE, ""},
199  { BGP_AS_SET, "}"},
200  { BGP_CONFED_AS_SEQUENCE, ")"},
201  { BGP_CONFED_AS_SET, "})"},
202  { 0, NULL}
203 };
204 
205 #define BGP_OPT_AUTH 1
206 #define BGP_OPT_CAP 2
207 
208 static const struct tok bgp_opt_values[] = {
209  { BGP_OPT_AUTH, "Authentication Information"},
210  { BGP_OPT_CAP, "Capabilities Advertisement"},
211  { 0, NULL}
212 };
213 
214 #define BGP_CAPCODE_MP 1 /* RFC2858 */
215 #define BGP_CAPCODE_RR 2 /* RFC2918 */
216 #define BGP_CAPCODE_ORF 3 /* RFC5291 */
217 #define BGP_CAPCODE_MR 4 /* RFC3107 */
218 #define BGP_CAPCODE_EXT_NH 5 /* RFC5549 */
219 #define BGP_CAPCODE_ML 8 /* RFC8277 */
220 #define BGP_CAPCODE_RESTART 64 /* RFC4724 */
221 #define BGP_CAPCODE_AS_NEW 65 /* RFC6793 */
222 #define BGP_CAPCODE_DYN_CAP 67 /* draft-ietf-idr-dynamic-cap */
223 #define BGP_CAPCODE_MULTISESS 68 /* draft-ietf-idr-bgp-multisession */
224 #define BGP_CAPCODE_ADD_PATH 69 /* RFC7911 */
225 #define BGP_CAPCODE_ENH_RR 70 /* draft-keyur-bgp-enhanced-route-refresh */
226 #define BGP_CAPCODE_LLGR 71 /* draft-uttaro-idr-bgp-persistence-05 */
227 #define BGP_CAPCODE_RR_CISCO 128
228 
229 static const struct tok bgp_capcode_values[] = {
230  { BGP_CAPCODE_MP, "Multiprotocol Extensions"},
231  { BGP_CAPCODE_RR, "Route Refresh"},
232  { BGP_CAPCODE_ORF, "Cooperative Route Filtering"},
233  { BGP_CAPCODE_MR, "Multiple Routes to a Destination"},
234  { BGP_CAPCODE_EXT_NH, "Extended Next Hop Encoding"},
235  { BGP_CAPCODE_ML, "Multiple Labels"},
236  { BGP_CAPCODE_RESTART, "Graceful Restart"},
237  { BGP_CAPCODE_AS_NEW, "32-Bit AS Number"},
238  { BGP_CAPCODE_DYN_CAP, "Dynamic Capability"},
239  { BGP_CAPCODE_MULTISESS, "Multisession BGP"},
240  { BGP_CAPCODE_ADD_PATH, "Multiple Paths"},
241  { BGP_CAPCODE_ENH_RR, "Enhanced Route Refresh"},
242  { BGP_CAPCODE_LLGR, "Long-lived Graceful Restart"},
243  { BGP_CAPCODE_RR_CISCO, "Route Refresh (Cisco)"},
244  { 0, NULL}
245 };
246 
247 #define BGP_NOTIFY_MAJOR_MSG 1
248 #define BGP_NOTIFY_MAJOR_OPEN 2
249 #define BGP_NOTIFY_MAJOR_UPDATE 3
250 #define BGP_NOTIFY_MAJOR_HOLDTIME 4
251 #define BGP_NOTIFY_MAJOR_FSM 5
252 #define BGP_NOTIFY_MAJOR_CEASE 6
253 #define BGP_NOTIFY_MAJOR_CAP 7
254 
255 static const struct tok bgp_notify_major_values[] = {
256  { BGP_NOTIFY_MAJOR_MSG, "Message Header Error"},
257  { BGP_NOTIFY_MAJOR_OPEN, "OPEN Message Error"},
258  { BGP_NOTIFY_MAJOR_UPDATE, "UPDATE Message Error"},
259  { BGP_NOTIFY_MAJOR_HOLDTIME,"Hold Timer Expired"},
260  { BGP_NOTIFY_MAJOR_FSM, "Finite State Machine Error"},
261  { BGP_NOTIFY_MAJOR_CEASE, "Cease"},
262  { BGP_NOTIFY_MAJOR_CAP, "Capability Message Error"},
263  { 0, NULL}
264 };
265 
266 /* draft-ietf-idr-cease-subcode-02 */
267 #define BGP_NOTIFY_MINOR_CEASE_MAXPRFX 1
268 /* draft-ietf-idr-shutdown-07 */
269 #define BGP_NOTIFY_MINOR_CEASE_SHUT 2
270 #define BGP_NOTIFY_MINOR_CEASE_RESET 4
271 #define BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN 128
272 static const struct tok bgp_notify_minor_cease_values[] = {
273  { BGP_NOTIFY_MINOR_CEASE_MAXPRFX, "Maximum Number of Prefixes Reached"},
274  { BGP_NOTIFY_MINOR_CEASE_SHUT, "Administrative Shutdown"},
275  { 3, "Peer Unconfigured"},
276  { BGP_NOTIFY_MINOR_CEASE_RESET, "Administrative Reset"},
277  { 5, "Connection Rejected"},
278  { 6, "Other Configuration Change"},
279  { 7, "Connection Collision Resolution"},
280  { 0, NULL}
281 };
282 
283 static const struct tok bgp_notify_minor_msg_values[] = {
284  { 1, "Connection Not Synchronized"},
285  { 2, "Bad Message Length"},
286  { 3, "Bad Message Type"},
287  { 0, NULL}
288 };
289 
290 static const struct tok bgp_notify_minor_open_values[] = {
291  { 1, "Unsupported Version Number"},
292  { 2, "Bad Peer AS"},
293  { 3, "Bad BGP Identifier"},
294  { 4, "Unsupported Optional Parameter"},
295  { 5, "Authentication Failure"},
296  { 6, "Unacceptable Hold Time"},
297  { 7, "Capability Message Error"},
298  { 0, NULL}
299 };
300 
301 static const struct tok bgp_notify_minor_update_values[] = {
302  { 1, "Malformed Attribute List"},
303  { 2, "Unrecognized Well-known Attribute"},
304  { 3, "Missing Well-known Attribute"},
305  { 4, "Attribute Flags Error"},
306  { 5, "Attribute Length Error"},
307  { 6, "Invalid ORIGIN Attribute"},
308  { 7, "AS Routing Loop"},
309  { 8, "Invalid NEXT_HOP Attribute"},
310  { 9, "Optional Attribute Error"},
311  { 10, "Invalid Network Field"},
312  { 11, "Malformed AS_PATH"},
313  { 0, NULL}
314 };
315 
316 static const struct tok bgp_notify_minor_fsm_values[] = {
317  { 0, "Unspecified Error"},
318  { 1, "In OpenSent State"},
319  { 2, "In OpenConfirm State"},
320  { 3, "In Established State"},
321  { 0, NULL }
322 };
323 
324 static const struct tok bgp_notify_minor_cap_values[] = {
325  { 1, "Invalid Action Value" },
326  { 2, "Invalid Capability Length" },
327  { 3, "Malformed Capability Value" },
328  { 4, "Unsupported Capability Code" },
329  { 0, NULL }
330 };
331 
332 static const struct tok bgp_origin_values[] = {
333  { 0, "IGP"},
334  { 1, "EGP"},
335  { 2, "Incomplete"},
336  { 0, NULL}
337 };
338 
339 #define BGP_PMSI_TUNNEL_RSVP_P2MP 1
340 #define BGP_PMSI_TUNNEL_LDP_P2MP 2
341 #define BGP_PMSI_TUNNEL_PIM_SSM 3
342 #define BGP_PMSI_TUNNEL_PIM_SM 4
343 #define BGP_PMSI_TUNNEL_PIM_BIDIR 5
344 #define BGP_PMSI_TUNNEL_INGRESS 6
345 #define BGP_PMSI_TUNNEL_LDP_MP2MP 7
346 
347 static const struct tok bgp_pmsi_tunnel_values[] = {
348  { BGP_PMSI_TUNNEL_RSVP_P2MP, "RSVP-TE P2MP LSP"},
349  { BGP_PMSI_TUNNEL_LDP_P2MP, "LDP P2MP LSP"},
350  { BGP_PMSI_TUNNEL_PIM_SSM, "PIM-SSM Tree"},
351  { BGP_PMSI_TUNNEL_PIM_SM, "PIM-SM Tree"},
352  { BGP_PMSI_TUNNEL_PIM_BIDIR, "PIM-Bidir Tree"},
353  { BGP_PMSI_TUNNEL_INGRESS, "Ingress Replication"},
354  { BGP_PMSI_TUNNEL_LDP_MP2MP, "LDP MP2MP LSP"},
355  { 0, NULL}
356 };
357 
358 static const struct tok bgp_pmsi_flag_values[] = {
359  { 0x01, "Leaf Information required"},
360  { 0, NULL}
361 };
362 
363 #define BGP_AIGP_TLV 1
364 
365 static const struct tok bgp_aigp_values[] = {
366  { BGP_AIGP_TLV, "AIGP"},
367  { 0, NULL}
368 };
369 
370 /* Subsequent address family identifier, RFC2283 section 7 */
371 #define SAFNUM_RES 0
372 #define SAFNUM_UNICAST 1
373 #define SAFNUM_MULTICAST 2
374 #define SAFNUM_UNIMULTICAST 3 /* deprecated now */
375 /* labeled BGP RFC3107 */
376 #define SAFNUM_LABUNICAST 4
377 /* RFC6514 */
378 #define SAFNUM_MULTICAST_VPN 5
379 /* draft-nalawade-kapoor-tunnel-safi */
380 #define SAFNUM_TUNNEL 64
381 /* RFC4761 */
382 #define SAFNUM_VPLS 65
383 /* RFC6037 */
384 #define SAFNUM_MDT 66
385 /* RFC7432 */
386 #define SAFNUM_EVPN 70
387 /* RFC4364 */
388 #define SAFNUM_VPNUNICAST 128
389 /* RFC6513 */
390 #define SAFNUM_VPNMULTICAST 129
391 #define SAFNUM_VPNUNIMULTICAST 130 /* deprecated now */
392 /* RFC4684 */
393 #define SAFNUM_RT_ROUTING_INFO 132
394 
395 #define BGP_VPN_RD_LEN 8
396 
397 static const struct tok bgp_safi_values[] = {
398  { SAFNUM_RES, "Reserved"},
399  { SAFNUM_UNICAST, "Unicast"},
400  { SAFNUM_MULTICAST, "Multicast"},
401  { SAFNUM_UNIMULTICAST, "Unicast+Multicast"},
402  { SAFNUM_LABUNICAST, "labeled Unicast"},
403  { SAFNUM_TUNNEL, "Tunnel"},
404  { SAFNUM_VPLS, "VPLS"},
405  { SAFNUM_MDT, "MDT"},
406  { SAFNUM_EVPN, "EVPN"},
407  { SAFNUM_VPNUNICAST, "labeled VPN Unicast"},
408  { SAFNUM_VPNMULTICAST, "labeled VPN Multicast"},
409  { SAFNUM_VPNUNIMULTICAST, "labeled VPN Unicast+Multicast"},
410  { SAFNUM_RT_ROUTING_INFO, "Route Target Routing Information"},
411  { SAFNUM_MULTICAST_VPN, "Multicast VPN"},
412  { 0, NULL }
413 };
414 
415 /* well-known community */
416 #define BGP_COMMUNITY_NO_EXPORT 0xffffff01
417 #define BGP_COMMUNITY_NO_ADVERT 0xffffff02
418 #define BGP_COMMUNITY_NO_EXPORT_SUBCONFED 0xffffff03
419 
420 /* Extended community type - RFC 4360 */
421 #define BGP_EXT_COM_RT_0 0x0002 /* Route Target,Format AS(2bytes):AN(4bytes) */
422 #define BGP_EXT_COM_RT_1 0x0102 /* Route Target,Format IP address:AN(2bytes) */
423 #define BGP_EXT_COM_RT_2 0x0202 /* Route Target,Format AN(4bytes):local(2bytes) */
424 #define BGP_EXT_COM_RO_0 0x0003 /* Route Origin,Format AS(2bytes):AN(4bytes) */
425 #define BGP_EXT_COM_RO_1 0x0103 /* Route Origin,Format IP address:AN(2bytes) */
426 #define BGP_EXT_COM_RO_2 0x0203 /* Route Origin,Format AN(4bytes):local(2bytes) */
427 #define BGP_EXT_COM_LINKBAND 0x4004 /* Link Bandwidth,Format AS(2B):Bandwidth(4B) */
428  /* rfc2547 bgp-mpls-vpns */
429 #define BGP_EXT_COM_VPN_ORIGIN 0x0005 /* OSPF Domain ID / VPN of Origin - draft-rosen-vpns-ospf-bgp-mpls */
430 #define BGP_EXT_COM_VPN_ORIGIN2 0x0105 /* duplicate - keep for backwards compatibility */
431 #define BGP_EXT_COM_VPN_ORIGIN3 0x0205 /* duplicate - keep for backwards compatibility */
432 #define BGP_EXT_COM_VPN_ORIGIN4 0x8005 /* duplicate - keep for backwards compatibility */
433 
434 #define BGP_EXT_COM_OSPF_RTYPE 0x0306 /* OSPF Route Type,Format Area(4B):RouteType(1B):Options(1B) */
435 #define BGP_EXT_COM_OSPF_RTYPE2 0x8000 /* duplicate - keep for backwards compatibility */
436 #define BGP_EXT_COM_ENCAP 0x030c /* rfc5512 */
437 
438 #define BGP_EXT_COM_OSPF_RID 0x0107 /* OSPF Router ID,Format RouterID(4B):Unused(2B) */
439 #define BGP_EXT_COM_OSPF_RID2 0x8001 /* duplicate - keep for backwards compatibility */
440 
441 #define BGP_EXT_COM_L2INFO 0x800a /* draft-kompella-ppvpn-l2vpn */
442 
443 #define BGP_EXT_COM_SOURCE_AS 0x0009 /* RFC-ietf-l3vpn-2547bis-mcast-bgp-08.txt */
444 #define BGP_EXT_COM_VRF_RT_IMP 0x010b /* RFC-ietf-l3vpn-2547bis-mcast-bgp-08.txt */
445 #define BGP_EXT_COM_L2VPN_RT_0 0x000a /* L2VPN Identifier,Format AS(2bytes):AN(4bytes) */
446 #define BGP_EXT_COM_L2VPN_RT_1 0xF10a /* L2VPN Identifier,Format IP address:AN(2bytes) */
447 
448 /* https://www.cisco.com/en/US/tech/tk436/tk428/technologies_tech_note09186a00801eb09a.shtml */
449 #define BGP_EXT_COM_EIGRP_GEN 0x8800
450 #define BGP_EXT_COM_EIGRP_METRIC_AS_DELAY 0x8801
451 #define BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW 0x8802
452 #define BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU 0x8803
453 #define BGP_EXT_COM_EIGRP_EXT_REMAS_REMID 0x8804
454 #define BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC 0x8805
455 
456 static const struct tok bgp_extd_comm_flag_values[] = {
457  { 0x8000, "vendor-specific"},
458  { 0x4000, "non-transitive"},
459  { 0, NULL},
460 };
461 
462 static const struct tok bgp_extd_comm_subtype_values[] = {
463  { BGP_EXT_COM_RT_0, "target"},
464  { BGP_EXT_COM_RT_1, "target"},
465  { BGP_EXT_COM_RT_2, "target"},
466  { BGP_EXT_COM_RO_0, "origin"},
467  { BGP_EXT_COM_RO_1, "origin"},
468  { BGP_EXT_COM_RO_2, "origin"},
469  { BGP_EXT_COM_LINKBAND, "link-BW"},
470  { BGP_EXT_COM_VPN_ORIGIN, "ospf-domain"},
471  { BGP_EXT_COM_VPN_ORIGIN2, "ospf-domain"},
472  { BGP_EXT_COM_VPN_ORIGIN3, "ospf-domain"},
473  { BGP_EXT_COM_VPN_ORIGIN4, "ospf-domain"},
474  { BGP_EXT_COM_OSPF_RTYPE, "ospf-route-type"},
475  { BGP_EXT_COM_OSPF_RTYPE2, "ospf-route-type"},
476  { BGP_EXT_COM_ENCAP, "encapsulation"},
477  { BGP_EXT_COM_OSPF_RID, "ospf-router-id"},
478  { BGP_EXT_COM_OSPF_RID2, "ospf-router-id"},
479  { BGP_EXT_COM_L2INFO, "layer2-info"},
480  { BGP_EXT_COM_EIGRP_GEN, "eigrp-general-route (flag, tag)" },
481  { BGP_EXT_COM_EIGRP_METRIC_AS_DELAY, "eigrp-route-metric (AS, delay)" },
482  { BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW, "eigrp-route-metric (reliability, nexthop, bandwidth)" },
483  { BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU, "eigrp-route-metric (load, MTU)" },
484  { BGP_EXT_COM_EIGRP_EXT_REMAS_REMID, "eigrp-external-route (remote-AS, remote-ID)" },
485  { BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC, "eigrp-external-route (remote-proto, remote-metric)" },
486  { BGP_EXT_COM_SOURCE_AS, "source-AS" },
487  { BGP_EXT_COM_VRF_RT_IMP, "vrf-route-import"},
488  { BGP_EXT_COM_L2VPN_RT_0, "l2vpn-id"},
489  { BGP_EXT_COM_L2VPN_RT_1, "l2vpn-id"},
490  { 0, NULL},
491 };
492 
493 /* RFC RFC5512 BGP Tunnel Encapsulation Attribute Tunnel Types */
494 #define BGP_ENCAP_TUNNEL_L2TPV3_IP 1
495 #define BGP_ENCAP_TUNNEL_GRE 2
496 #define BGP_ENCAP_TUNNEL_TRANSMIT 3
497 #define BGP_ENCAP_TUNNEL_IPSEC 4
498 #define BGP_ENCAP_TUNNEL_IP_IPSEC 5
499 #define BGP_ENCAP_TUNNEL_MPLS_IP 6
500 #define BGP_ENCAP_TUNNEL_IP_IP 7
501 #define BGP_ENCAP_TUNNEL_VXLAN 8
502 #define BGP_ENCAP_TUNNEL_NVGRE 9
503 #define BGP_ENCAP_TUNNEL_MPLS 10
504 #define BGP_ENCAP_TUNNEL_MPLS_GRE 11
505 #define BGP_ENCAP_TUNNEL_VXLAN_GPE 12
506 #define BGP_ENCAP_TUNNEL_MPLS_UDP 13
507 #define BGP_ENCAP_TUNNEL_IPV6 14
508 #define BGP_ENCAP_TUNNEL_SR_TE 15
509 #define BGP_ENCAP_TUNNEL_BARE 16
510 #define BGP_ENCAP_TUNNEL_SR 17
511 
512 static const struct tok bgp_extd_comm_encap_tunnel_values[] = {
513  { BGP_ENCAP_TUNNEL_L2TPV3_IP, "L2TPv3 over IP"},
514  { BGP_ENCAP_TUNNEL_GRE, "GRE"},
515  { BGP_ENCAP_TUNNEL_TRANSMIT, "Transmit Tunnel"},
516  { BGP_ENCAP_TUNNEL_IPSEC, "IPsec"},
517  { BGP_ENCAP_TUNNEL_IP_IPSEC, "IP in IP with IPsec"},
518  { BGP_ENCAP_TUNNEL_MPLS_IP, "MPLS in IP with IPsec"},
519  { BGP_ENCAP_TUNNEL_IP_IP, "IP in IP"},
520  { BGP_ENCAP_TUNNEL_VXLAN, "VXLAN"},
521  { BGP_ENCAP_TUNNEL_NVGRE, "NVGRE"},
522  { BGP_ENCAP_TUNNEL_MPLS, "MPLS"},
523  { BGP_ENCAP_TUNNEL_MPLS_GRE, "MPLS in GRE"},
524  { BGP_ENCAP_TUNNEL_VXLAN_GPE, "VXLAN GPE"},
525  { BGP_ENCAP_TUNNEL_MPLS_UDP, "MPLS in UDP"},
526  { BGP_ENCAP_TUNNEL_IPV6, "IPv6"},
527  { BGP_ENCAP_TUNNEL_SR_TE, "SR TE"},
528  { BGP_ENCAP_TUNNEL_BARE, "Bare"},
529  { BGP_ENCAP_TUNNEL_SR, "SR"},
530  { 0, NULL},
531 };
532 
533 /* OSPF codes for BGP_EXT_COM_OSPF_RTYPE draft-rosen-vpns-ospf-bgp-mpls */
534 #define BGP_OSPF_RTYPE_RTR 1 /* OSPF Router LSA */
535 #define BGP_OSPF_RTYPE_NET 2 /* OSPF Network LSA */
536 #define BGP_OSPF_RTYPE_SUM 3 /* OSPF Summary LSA */
537 #define BGP_OSPF_RTYPE_EXT 5 /* OSPF External LSA, note that ASBR doesn't apply to MPLS-VPN */
538 #define BGP_OSPF_RTYPE_NSSA 7 /* OSPF NSSA External*/
539 #define BGP_OSPF_RTYPE_SHAM 129 /* OSPF-MPLS-VPN Sham link */
540 #define BGP_OSPF_RTYPE_METRIC_TYPE 0x1 /* LSB of RTYPE Options Field */
541 
542 static const struct tok bgp_extd_comm_ospf_rtype_values[] = {
543  { BGP_OSPF_RTYPE_RTR, "Router" },
544  { BGP_OSPF_RTYPE_NET, "Network" },
545  { BGP_OSPF_RTYPE_SUM, "Summary" },
546  { BGP_OSPF_RTYPE_EXT, "External" },
547  { BGP_OSPF_RTYPE_NSSA,"NSSA External" },
548  { BGP_OSPF_RTYPE_SHAM,"MPLS-VPN Sham" },
549  { 0, NULL },
550 };
551 
552 /* ADD-PATH Send/Receive field values */
553 static const struct tok bgp_add_path_recvsend[] = {
554  { 1, "Receive" },
555  { 2, "Send" },
556  { 3, "Both" },
557  { 0, NULL },
558 };
559 
560 #define AS_STR_SIZE sizeof("xxxxx.xxxxx")
561 
562 /*
563  * as_printf
564  *
565  * Convert an AS number into a string and return string pointer.
566  *
567  * Depending on bflag is set or not, AS number is converted into ASDOT notation
568  * or plain number notation.
569  *
570  */
571 static char *
573  char *str, size_t size, u_int asnum)
574 {
575  if (!ndo->ndo_bflag || asnum <= 0xFFFF) {
576  snprintf(str, size, "%u", asnum);
577  } else {
578  snprintf(str, size, "%u.%u", asnum >> 16, asnum & 0xFFFF);
579  }
580  return str;
581 }
582 
583 #define ITEMCHECK(minlen) if (itemlen < minlen) goto badtlv;
584 
585 int
587  const u_char *pptr, u_int itemlen, char *buf, size_t buflen)
588 {
589  nd_ipv4 addr;
590  u_int plen, plenbytes;
591 
592  ITEMCHECK(1);
593  plen = GET_U_1(pptr);
594  if (32 < plen)
595  return -1;
596  itemlen -= 1;
597 
598  memset(&addr, 0, sizeof(addr));
599  plenbytes = (plen + 7) / 8;
600  ITEMCHECK(plenbytes);
601  GET_CPY_BYTES(&addr, pptr + 1, plenbytes);
602  if (plen % 8) {
603  ((u_char *)&addr)[plenbytes - 1] &= ((0xff00 >> (plen % 8)) & 0xff);
604  }
605  snprintf(buf, buflen, "%s/%u", ipaddr_string(ndo, (const u_char *)&addr), plen);
606  return 1 + plenbytes;
607 
608 badtlv:
609  return -2;
610 }
611 
612 static int
614  const u_char *pptr, u_int itemlen, char *buf,
615  size_t buflen)
616 {
617  nd_ipv4 addr;
618  u_int plen, plenbytes;
619 
620  /* prefix length and label = 4 bytes */
621  ND_TCHECK_4(pptr);
622  ITEMCHECK(4);
623  plen = GET_U_1(pptr); /* get prefix length */
624 
625  /* this is one of the weirdnesses of rfc3107
626  the label length (actually the label + COS bits)
627  is added to the prefix length;
628  we also do only read out just one label -
629  there is no real application for advertisement of
630  stacked labels in a single BGP message
631  */
632 
633  if (24 > plen)
634  return -1;
635 
636  plen-=24; /* adjust prefixlen - labellength */
637 
638  if (32 < plen)
639  return -1;
640  itemlen -= 4;
641 
642  memset(&addr, 0, sizeof(addr));
643  plenbytes = (plen + 7) / 8;
644  ITEMCHECK(plenbytes);
645  GET_CPY_BYTES(&addr, pptr + 4, plenbytes);
646  if (plen % 8) {
647  ((u_char *)&addr)[plenbytes - 1] &= ((0xff00 >> (plen % 8)) & 0xff);
648  }
649  /* the label may get offsetted by 4 bits so lets shift it right */
650  snprintf(buf, buflen, "%s/%u, label:%u %s",
651  ipaddr_string(ndo, (const u_char *)&addr),
652  plen,
653  GET_BE_U_3(pptr + 1)>>4,
654  ((GET_U_1(pptr + 3) & 1) == 0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
655 
656  return 4 + plenbytes;
657 
658 trunc:
659  return -2;
660 
661 badtlv:
662  return -3;
663 }
664 
665 /*
666  * bgp_vpn_ip_print
667  *
668  * print an ipv4 or ipv6 address into a buffer dependent on address length.
669  */
670 static char *
672  const u_char *pptr, u_int addr_length)
673 {
674 
675  /* worst case string is s fully formatted v6 address */
676  static char addr[sizeof("1234:5678:89ab:cdef:1234:5678:89ab:cdef")];
677  char *pos = addr;
678 
679  switch(addr_length) {
680  case (sizeof(nd_ipv4) << 3): /* 32 */
681  snprintf(pos, sizeof(addr), "%s", GET_IPADDR_STRING(pptr));
682  break;
683  case (sizeof(nd_ipv6) << 3): /* 128 */
684  snprintf(pos, sizeof(addr), "%s", GET_IP6ADDR_STRING(pptr));
685  break;
686  default:
687  snprintf(pos, sizeof(addr), "bogus address length %u", addr_length);
688  break;
689  }
690  pos += strlen(pos);
691 
692  *(pos) = '\0';
693  return (addr);
694 }
695 
696 /*
697  * bgp_vpn_sg_print
698  *
699  * print an multicast s,g entry into a buffer.
700  * the s,g entry is encoded like this.
701  *
702  * +-----------------------------------+
703  * | Multicast Source Length (1 octet) |
704  * +-----------------------------------+
705  * | Multicast Source (Variable) |
706  * +-----------------------------------+
707  * | Multicast Group Length (1 octet) |
708  * +-----------------------------------+
709  * | Multicast Group (Variable) |
710  * +-----------------------------------+
711  *
712  * return the number of bytes read from the wire.
713  */
714 static u_int
716  const u_char *pptr, char *buf, size_t buflen)
717 {
718  uint8_t addr_length;
719  u_int total_length, offset;
720 
721  total_length = 0;
722 
723  /* Source address length, encoded in bits */
724  addr_length = GET_U_1(pptr);
725  pptr++;
726 
727  /* Source address */
728  ND_TCHECK_LEN(pptr, (addr_length >> 3));
729  total_length += (addr_length >> 3) + 1;
730  offset = (u_int)strlen(buf);
731  if (addr_length) {
732  snprintf(buf + offset, buflen - offset, ", Source %s",
733  bgp_vpn_ip_print(ndo, pptr, addr_length));
734  pptr += (addr_length >> 3);
735  }
736 
737  /* Group address length, encoded in bits */
738  addr_length = GET_U_1(pptr);
739  pptr++;
740 
741  /* Group address */
742  ND_TCHECK_LEN(pptr, (addr_length >> 3));
743  total_length += (addr_length >> 3) + 1;
744  offset = (u_int)strlen(buf);
745  if (addr_length) {
746  snprintf(buf + offset, buflen - offset, ", Group %s",
747  bgp_vpn_ip_print(ndo, pptr, addr_length));
748  pptr += (addr_length >> 3);
749  }
750 
751 trunc:
752  return (total_length);
753 }
754 
755 /* Print an RFC 4364 Route Distinguisher */
756 const char *
758  const u_char *pptr)
759 {
760  /* allocate space for the largest possible string */
761  static char rd[sizeof("xxxxx.xxxxx:xxxxx (xxx.xxx.xxx.xxx:xxxxx)")];
762  char *pos = rd;
763  /* allocate space for the largest possible string */
764  char astostr[AS_STR_SIZE];
765 
766  /* ok lets load the RD format */
767  switch (GET_BE_U_2(pptr)) {
768 
769  case 0:
770  /* 2-byte-AS:number fmt */
771  snprintf(pos, sizeof(rd) - (pos - rd), "%u:%u (= %u.%u.%u.%u)",
772  GET_BE_U_2(pptr + 2),
773  GET_BE_U_4(pptr + 4),
774  GET_U_1(pptr + 4), GET_U_1(pptr + 5),
775  GET_U_1(pptr + 6), GET_U_1(pptr + 7));
776  break;
777 
778  case 1:
779  /* IP-address:AS fmt */
780  snprintf(pos, sizeof(rd) - (pos - rd), "%u.%u.%u.%u:%u",
781  GET_U_1(pptr + 2), GET_U_1(pptr + 3),
782  GET_U_1(pptr + 4), GET_U_1(pptr + 5),
783  GET_BE_U_2(pptr + 6));
784  break;
785 
786  case 2:
787  /* 4-byte-AS:number fmt */
788  snprintf(pos, sizeof(rd) - (pos - rd), "%s:%u (%u.%u.%u.%u:%u)",
789  as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_4(pptr + 2)),
790  GET_BE_U_2(pptr + 6), GET_U_1(pptr + 2),
791  GET_U_1(pptr + 3), GET_U_1(pptr + 4),
792  GET_U_1(pptr + 5), GET_BE_U_2(pptr + 6));
793  break;
794  default:
795  snprintf(pos, sizeof(rd) - (pos - rd), "unknown RD format");
796  break;
797  }
798  pos += strlen(pos);
799  *(pos) = '\0';
800  return (rd);
801 }
802 
803 /*
804  * Print an RFC 4360 Extended Community.
805  */
806 static void
808  const u_char *pptr)
809 {
810  union { /* copy buffer for bandwidth values */
811  float f;
812  uint32_t i;
813  } bw;
814  /* allocate space for the largest possible string */
815  char astostr[AS_STR_SIZE];
816 
817  switch (GET_BE_U_2(pptr)) {
818 
819  case BGP_EXT_COM_RT_0:
820  case BGP_EXT_COM_RO_0:
822  ND_PRINT("%u:%u (= %s)",
823  GET_BE_U_2(pptr + 2),
824  GET_BE_U_4(pptr + 4),
825  GET_IPADDR_STRING(pptr+4));
826  break;
827 
828  case BGP_EXT_COM_RT_1:
829  case BGP_EXT_COM_RO_1:
832  ND_PRINT("%s:%u",
833  GET_IPADDR_STRING(pptr+2),
834  GET_BE_U_2(pptr + 6));
835  break;
836 
837  case BGP_EXT_COM_RT_2:
838  case BGP_EXT_COM_RO_2:
839  ND_PRINT("%s:%u",
840  as_printf(ndo, astostr, sizeof(astostr),
841  GET_BE_U_4(pptr + 2)), GET_BE_U_2(pptr + 6));
842  break;
843 
845  bw.i = GET_BE_U_4(pptr + 2);
846  ND_PRINT("bandwidth: %.3f Mbps",
847  bw.f*8/1000000);
848  break;
849 
856  ND_PRINT("%s", GET_IPADDR_STRING(pptr+2));
857  break;
858 
861  ND_PRINT("area:%s, router-type:%s, metric-type:%s%s",
862  GET_IPADDR_STRING(pptr+2),
864  "unknown (0x%02x)",
865  GET_U_1((pptr + 6))),
866  (GET_U_1(pptr + 7) & BGP_OSPF_RTYPE_METRIC_TYPE) ? "E2" : "",
867  ((GET_U_1(pptr + 6) == BGP_OSPF_RTYPE_EXT) || (GET_U_1(pptr + 6) == BGP_OSPF_RTYPE_NSSA)) ? "E1" : "");
868  break;
869 
870  case BGP_EXT_COM_L2INFO:
871  ND_PRINT("%s Control Flags [0x%02x]:MTU %u",
873  "unknown encaps",
874  GET_U_1((pptr + 2))),
875  GET_U_1((pptr + 3)),
876  GET_BE_U_2(pptr + 4));
877  break;
878 
880  ND_PRINT("AS %u", GET_BE_U_2(pptr + 2));
881  break;
882 
883  case BGP_EXT_COM_ENCAP:
885  "unknown encaps",
886  GET_BE_U_2(pptr + 6)));
887  break;
888 
889  default:
890  ND_PRINT("%02x%02x%02x%02x%02x%02x",
891  GET_U_1(pptr + 2),
892  GET_U_1(pptr + 3),
893  GET_U_1(pptr + 4),
894  GET_U_1(pptr + 5),
895  GET_U_1(pptr + 6),
896  GET_U_1(pptr + 7));
897  break;
898  }
899 }
900 
901 /*
902  * RFC4684 (Section 4)/RFC2858 (Section 4).
903  * RTC membership prefix is structured as follows
904  * [prefix-len] [origin-as] [route-target]
905  * The route-target is encoded as RT ext-comms.
906  * Prefix-len may be 0, 32..96
907  *
908  * Note that pptr is not packet data - it is
909  * a buffer owned by our caller - therefore GET_*
910  * macros can not be used.
911  */
912 static char *
914  const u_char *pptr,
915  u_int plen)
916 {
917  /* allocate space for the largest possible string */
918  char rtc_prefix_in_hex[20] = "";
919  u_int rtc_prefix_in_hex_len = 0;
920  static char output[61]; /* max response string */
921  /* allocate space for the largest possible string */
922  char astostr[AS_STR_SIZE];
923  uint16_t ec_type = 0;
924  u_int octet_count;
925  u_int i;
926 
927  if (plen == 0) {
928  snprintf(output, sizeof(output), "route-target: 0:0/0");
929  return (output);
930  }
931 
932  /* hex representation of the prefix */
933  octet_count = (plen+7)/8;
934  for (i=0; i<octet_count; i++) {
935  rtc_prefix_in_hex_len += snprintf(rtc_prefix_in_hex+rtc_prefix_in_hex_len,
936  sizeof(rtc_prefix_in_hex)-rtc_prefix_in_hex_len,
937  "%02x%s", *(pptr+i),
938  ((i%2 == 1) && (i<octet_count-1)) ? " " : "");
939  }
940 
941  if (plen < 16) {
942  /*
943  * The prefix is too short to include the full ext-comm type,
944  * so we have no way to parse it further.
945  */
946  snprintf(output, sizeof(output), "route-target: partial-type: (%s/%d)",
947  rtc_prefix_in_hex, plen);
948  return (output);
949  }
950 
951  /*
952  * get the ext-comm type
953  * Note: pptr references a static 8 octet buffer with unused bits set to 0,
954  * hense EXTRACT_*() macros are safe.
955  */
956  ec_type = EXTRACT_BE_U_2(pptr);
957  switch (ec_type) {
958  case BGP_EXT_COM_RT_0:
959  /* 2-byte-AS:number fmt */
960  snprintf(output, sizeof(output), "route-target: %u:%u/%d (%s)",
961  EXTRACT_BE_U_2(pptr+2),
962  EXTRACT_BE_U_4(pptr+4),
963  plen, rtc_prefix_in_hex);
964  break;
965 
966  case BGP_EXT_COM_RT_1:
967  /* IP-address:AS fmt */
968  snprintf(output, sizeof(output), "route-target: %u.%u.%u.%u:%u/%d (%s)",
969  *(pptr+2), *(pptr+3), *(pptr+4), *(pptr+5),
970  EXTRACT_BE_U_2(pptr+6), plen, rtc_prefix_in_hex);
971  break;
972 
973  case BGP_EXT_COM_RT_2:
974  /* 4-byte-AS:number fmt */
975  snprintf(output, sizeof(output), "route-target: %s:%u/%d (%s)",
976  as_printf(ndo, astostr, sizeof(astostr), EXTRACT_BE_U_4(pptr+2)),
977  EXTRACT_BE_U_2(pptr+6), plen, rtc_prefix_in_hex);
978  break;
979 
980  default:
981  snprintf(output, sizeof(output), "route target: unknown-type(%04x) (%s/%d)",
982  ec_type,
983  rtc_prefix_in_hex, plen);
984  break;
985  }
986  return (output);
987 }
988 
989 /* RFC 4684 */
990 static int
992  const u_char *pptr)
993 {
994  uint8_t route_target[8];
995  u_int plen;
996  /* allocate space for the largest possible string */
997  char astostr[AS_STR_SIZE];
998  u_int num_octets;
999 
1000  /* NLRI "prefix length" from RFC 2858 Section 4. */
1001  plen = GET_U_1(pptr); /* get prefix length */
1002 
1003  /* NLRI "prefix" (ibid), valid lengths are { 0, 32, 33, ..., 96 } bits.
1004  * RFC 4684 Section 4 defines the layout of "origin AS" and "route
1005  * target" fields inside the "prefix" depending on its length.
1006  */
1007  if (0 == plen) {
1008  /* Without "origin AS", without "route target". */
1009  ND_PRINT("\n\t default route target");
1010  return 1;
1011  }
1012 
1013  if (32 > plen) {
1014  ND_PRINT("\n\t (illegal prefix length)");
1015  return -1;
1016  }
1017 
1018  /* With at least "origin AS", possibly with "route target". */
1019  as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_4(pptr + 1));
1020 
1021  plen -= 32; /* adjust prefix length */
1022 
1023  if (64 < plen) {
1024  ND_PRINT("\n\t (illegal prefix length)");
1025  return -1;
1026  }
1027 
1028  /* From now on (plen + 7) / 8 evaluates to { 0, 1, 2, ..., 8 }
1029  * and gives the number of octets in the variable-length "route
1030  * target" field inside this NLRI "prefix". Look for it.
1031  */
1032  memset(&route_target, 0, sizeof(route_target));
1033  num_octets = (plen + 7) / 8;
1034  GET_CPY_BYTES(&route_target, pptr + 5, num_octets);
1035  /* If mask-len is not on octet boundary, ensure all extra bits are 0 */
1036  if (plen % 8) {
1037  ((u_char *)&route_target)[num_octets - 1] &=
1038  ((0xff00 >> (plen % 8)) & 0xff);
1039  }
1040  ND_PRINT("\n\t origin AS: %s, %s",
1041  astostr,
1042  bgp_rt_prefix_print(ndo, (u_char *)&route_target, plen));
1043 
1044  return 5 + num_octets;
1045 }
1046 
1047 static int
1049  const u_char *pptr, char *buf, size_t buflen)
1050 {
1051  nd_ipv4 addr;
1052  u_int plen;
1053 
1054  plen = GET_U_1(pptr); /* get prefix length */
1055 
1056  if ((24+64) > plen)
1057  return -1;
1058 
1059  plen -= (24+64); /* adjust prefixlen - labellength - RD len*/
1060 
1061  if (32 < plen)
1062  return -1;
1063 
1064  memset(&addr, 0, sizeof(addr));
1065  GET_CPY_BYTES(&addr, pptr + 12, (plen + 7) / 8);
1066  if (plen % 8) {
1067  ((u_char *)&addr)[(plen + 7) / 8 - 1] &=
1068  ((0xff00 >> (plen % 8)) & 0xff);
1069  }
1070  /* the label may get offsetted by 4 bits so lets shift it right */
1071  snprintf(buf, buflen, "RD: %s, %s/%u, label:%u %s",
1072  bgp_vpn_rd_print(ndo, pptr+4),
1073  ipaddr_string(ndo, (const u_char *)&addr),
1074  plen,
1075  GET_BE_U_3(pptr + 1)>>4,
1076  ((GET_U_1(pptr + 3) & 1) == 0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
1077 
1078  return 12 + (plen + 7) / 8;
1079 }
1080 
1081 /*
1082  * +-------------------------------+
1083  * | |
1084  * | RD:IPv4-address (12 octets) |
1085  * | |
1086  * +-------------------------------+
1087  * | MDT Group-address (4 octets) |
1088  * +-------------------------------+
1089  */
1090 
1091 #define MDT_VPN_NLRI_LEN 16
1092 
1093 static int
1095  const u_char *pptr, char *buf, size_t buflen)
1096 {
1097  const u_char *rd;
1098  const u_char *vpn_ip;
1099 
1100  /* if the NLRI is not predefined length, quit.*/
1101  if (GET_U_1(pptr) != MDT_VPN_NLRI_LEN * 8)
1102  return -1;
1103  pptr++;
1104 
1105  /* RD */
1106  ND_TCHECK_8(pptr);
1107  rd = pptr;
1108  pptr += 8;
1109 
1110  /* IPv4 address */
1111  vpn_ip = pptr;
1112  pptr += sizeof(nd_ipv4);
1113 
1114  /* MDT Group Address */
1115  snprintf(buf, buflen, "RD: %s, VPN IP Address: %s, MC Group Address: %s",
1116  bgp_vpn_rd_print(ndo, rd), GET_IPADDR_STRING(vpn_ip), GET_IPADDR_STRING(pptr));
1117 
1118  return MDT_VPN_NLRI_LEN + 1;
1119 
1120  trunc:
1121  return -2;
1122 }
1123 
1124 #define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI 1
1125 #define BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI 2
1126 #define BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI 3
1127 #define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF 4
1128 #define BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE 5
1129 #define BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN 6
1130 #define BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN 7
1131 
1132 static const struct tok bgp_multicast_vpn_route_type_values[] = {
1133  { BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI, "Intra-AS I-PMSI"},
1134  { BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI, "Inter-AS I-PMSI"},
1136  { BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF, "Intra-AS Segment-Leaf"},
1137  { BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE, "Source-Active"},
1138  { BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN, "Shared Tree Join"},
1139  { BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN, "Source Tree Join"},
1140  { 0, NULL}
1141 };
1142 
1143 static int
1145  const u_char *pptr, char *buf, size_t buflen)
1146 {
1147  /* allocate space for the largest possible string */
1148  char astostr[AS_STR_SIZE];
1149  uint8_t route_type, route_length;
1150  u_int addr_length, sg_length;
1151  u_int offset;
1152 
1153  route_type = GET_U_1(pptr);
1154  pptr++;
1155  route_length = GET_U_1(pptr);
1156  pptr++;
1157 
1158  snprintf(buf, buflen, "Route-Type: %s (%u), length: %u",
1160  "Unknown", route_type),
1161  route_type, route_length);
1162 
1163  switch(route_type) {
1166  offset = (u_int)strlen(buf);
1167  snprintf(buf + offset, buflen - offset, ", RD: %s, Originator %s",
1168  bgp_vpn_rd_print(ndo, pptr),
1169  bgp_vpn_ip_print(ndo, pptr + BGP_VPN_RD_LEN,
1170  (route_length - BGP_VPN_RD_LEN) << 3));
1171  break;
1173  ND_TCHECK_LEN(pptr, BGP_VPN_RD_LEN + 4);
1174  offset = (u_int)strlen(buf);
1175  snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s",
1176  bgp_vpn_rd_print(ndo, pptr),
1177  as_printf(ndo, astostr, sizeof(astostr),
1178  GET_BE_U_4(pptr + BGP_VPN_RD_LEN)));
1179  break;
1180 
1183  offset = (u_int)strlen(buf);
1184  snprintf(buf + offset, buflen - offset, ", RD: %s",
1185  bgp_vpn_rd_print(ndo, pptr));
1186  pptr += BGP_VPN_RD_LEN;
1187 
1188  sg_length = bgp_vpn_sg_print(ndo, pptr, buf, buflen);
1189  addr_length = route_length - sg_length;
1190 
1191  ND_TCHECK_LEN(pptr, addr_length);
1192  offset = (u_int)strlen(buf);
1193  snprintf(buf + offset, buflen - offset, ", Originator %s",
1194  bgp_vpn_ip_print(ndo, pptr, addr_length << 3));
1195  break;
1196 
1199  offset = (u_int)strlen(buf);
1200  snprintf(buf + offset, buflen - offset, ", RD: %s",
1201  bgp_vpn_rd_print(ndo, pptr));
1202  pptr += BGP_VPN_RD_LEN;
1203 
1204  bgp_vpn_sg_print(ndo, pptr, buf, buflen);
1205  break;
1206 
1207  case BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN: /* fall through */
1209  ND_TCHECK_LEN(pptr, BGP_VPN_RD_LEN + 4);
1210  offset = (u_int)strlen(buf);
1211  snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s",
1212  bgp_vpn_rd_print(ndo, pptr),
1213  as_printf(ndo, astostr, sizeof(astostr),
1214  GET_BE_U_4(pptr + BGP_VPN_RD_LEN)));
1215  pptr += BGP_VPN_RD_LEN + 4;
1216 
1217  bgp_vpn_sg_print(ndo, pptr, buf, buflen);
1218  break;
1219 
1220  /*
1221  * no per route-type printing yet.
1222  */
1224  default:
1225  break;
1226  }
1227 
1228  return route_length + 2;
1229 
1230 trunc:
1231  return -2;
1232 }
1233 
1234 /*
1235  * As I remember, some versions of systems have an snprintf() that
1236  * returns -1 if the buffer would have overflowed. If the return
1237  * value is negative, set buflen to 0, to indicate that we've filled
1238  * the buffer up.
1239  *
1240  * If the return value is greater than buflen, that means that
1241  * the buffer would have overflowed; again, set buflen to 0 in
1242  * that case.
1243  */
1244 #define UPDATE_BUF_BUFLEN(buf, buflen, stringlen) \
1245  if (stringlen<0) \
1246  buflen=0; \
1247  else if ((u_int)stringlen>buflen) \
1248  buflen=0; \
1249  else { \
1250  buflen-=stringlen; \
1251  buf+=stringlen; \
1252  }
1253 
1254 static int
1256  const u_char *pptr, char *buf, size_t buflen)
1257 {
1258  u_int plen, tlen, tlv_type, tlv_len, ttlv_len;
1259  int stringlen;
1260 
1261  plen = GET_BE_U_2(pptr);
1262  tlen = plen;
1263  pptr += 2;
1264  /* Old and new L2VPN NLRI share AFI/SAFI
1265  * -> Assume a 12 Byte-length NLRI is auto-discovery-only
1266  * and > 17 as old format. Complain for the middle case
1267  */
1268  if (plen == 12) {
1269  /* assume AD-only with RD, BGPNH */
1270  ND_TCHECK_LEN(pptr, 12);
1271  buf[0] = '\0';
1272  stringlen = snprintf(buf, buflen, "RD: %s, BGPNH: %s",
1273  bgp_vpn_rd_print(ndo, pptr),
1274  GET_IPADDR_STRING(pptr+8));
1275  UPDATE_BUF_BUFLEN(buf, buflen, stringlen);
1276  pptr += 12;
1277  tlen -= 12;
1278  return plen + 2;
1279  } else if (plen > 17) {
1280  /* assume old format */
1281  /* RD, ID, LBLKOFF, LBLBASE */
1282 
1283  ND_TCHECK_LEN(pptr, 15);
1284  buf[0] = '\0';
1285  stringlen = snprintf(buf, buflen, "RD: %s, CE-ID: %u, Label-Block Offset: %u, Label Base %u",
1286  bgp_vpn_rd_print(ndo, pptr),
1287  GET_BE_U_2(pptr + 8),
1288  GET_BE_U_2(pptr + 10),
1289  GET_BE_U_3(pptr + 12)>>4); /* the label is offsetted by 4 bits so lets shift it right */
1290  UPDATE_BUF_BUFLEN(buf, buflen, stringlen);
1291  pptr += 15;
1292  tlen -= 15;
1293 
1294  /* ok now the variable part - lets read out TLVs*/
1295  while (tlen != 0) {
1296  if (tlen < 3) {
1297  if (buflen != 0) {
1298  stringlen=snprintf(buf,buflen, "\n\t\tran past the end");
1299  UPDATE_BUF_BUFLEN(buf, buflen, stringlen);
1300  }
1301  return plen + 2;
1302  }
1303  tlv_type = GET_U_1(pptr);
1304  pptr++;
1305  tlv_len = GET_BE_U_2(pptr); /* length, in *bits* */
1306  ttlv_len = (tlv_len + 7)/8; /* length, in *bytes* */
1307  pptr += 2;
1308 
1309  switch(tlv_type) {
1310  case 1:
1311  if (buflen != 0) {
1312  stringlen=snprintf(buf,buflen, "\n\t\tcircuit status vector (%u) length: %u: 0x",
1313  tlv_type,
1314  tlv_len);
1315  UPDATE_BUF_BUFLEN(buf, buflen, stringlen);
1316  }
1317  while (ttlv_len != 0) {
1318  if (tlen < 1) {
1319  if (buflen != 0) {
1320  stringlen=snprintf(buf,buflen, " (ran past the end)");
1321  UPDATE_BUF_BUFLEN(buf, buflen, stringlen);
1322  }
1323  return plen + 2;
1324  }
1325  ND_TCHECK_1(pptr);
1326  if (buflen != 0) {
1327  stringlen=snprintf(buf,buflen, "%02x",
1328  GET_U_1(pptr));
1329  pptr++;
1330  UPDATE_BUF_BUFLEN(buf, buflen, stringlen);
1331  }
1332  ttlv_len--;
1333  tlen--;
1334  }
1335  break;
1336  default:
1337  if (buflen != 0) {
1338  stringlen=snprintf(buf,buflen, "\n\t\tunknown TLV #%u, length: %u",
1339  tlv_type,
1340  tlv_len);
1341  UPDATE_BUF_BUFLEN(buf, buflen, stringlen);
1342  }
1343  if (tlen < ttlv_len) {
1344  if (buflen != 0) {
1345  stringlen=snprintf(buf,buflen, " (ran past the end)");
1346  UPDATE_BUF_BUFLEN(buf, buflen, stringlen);
1347  }
1348  return plen + 2;
1349  }
1350  tlen -= ttlv_len;
1351  break;
1352  }
1353  }
1354  return plen + 2;
1355  } else {
1356  /* complain bitterly ? */
1357  /* fall through */
1358  goto trunc;
1359  }
1360 
1361 trunc:
1362  return -2;
1363 }
1364 
1365 int
1367  const u_char *pd, u_int itemlen, char *buf, size_t buflen)
1368 {
1369  nd_ipv6 addr;
1370  u_int plen, plenbytes;
1371 
1372  ITEMCHECK(1);
1373  plen = GET_U_1(pd);
1374  if (128 < plen)
1375  return -1;
1376  itemlen -= 1;
1377 
1378  memset(&addr, 0, sizeof(addr));
1379  plenbytes = (plen + 7) / 8;
1380  ITEMCHECK(plenbytes);
1381  GET_CPY_BYTES(&addr, pd + 1, plenbytes);
1382  if (plen % 8) {
1383  addr[plenbytes - 1] &=
1384  ((0xff00 >> (plen % 8)) & 0xff);
1385  }
1386  snprintf(buf, buflen, "%s/%u", ip6addr_string(ndo, (const u_char *)&addr), plen);
1387  return 1 + plenbytes;
1388 
1389 badtlv:
1390  return -2;
1391 }
1392 
1393 static int
1395  const u_char *pptr, u_int itemlen, char *buf, size_t buflen)
1396 {
1397  nd_ipv6 addr;
1398  u_int plen, plenbytes;
1399 
1400  /* prefix length and label = 4 bytes */
1401  ND_TCHECK_4(pptr);
1402  ITEMCHECK(4);
1403  plen = GET_U_1(pptr); /* get prefix length */
1404 
1405  if (24 > plen)
1406  return -1;
1407 
1408  plen -= 24; /* adjust prefixlen - labellength */
1409 
1410  if (128 < plen)
1411  return -1;
1412  itemlen -= 4;
1413 
1414  memset(&addr, 0, sizeof(addr));
1415  plenbytes = (plen + 7) / 8;
1416  GET_CPY_BYTES(&addr, pptr + 4, plenbytes);
1417  if (plen % 8) {
1418  addr[plenbytes - 1] &=
1419  ((0xff00 >> (plen % 8)) & 0xff);
1420  }
1421  /* the label may get offsetted by 4 bits so lets shift it right */
1422  snprintf(buf, buflen, "%s/%u, label:%u %s",
1423  ip6addr_string(ndo, (const u_char *)&addr),
1424  plen,
1425  GET_BE_U_3(pptr + 1)>>4,
1426  ((GET_U_1(pptr + 3) & 1) == 0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
1427 
1428  return 4 + plenbytes;
1429 
1430 trunc:
1431  return -2;
1432 
1433 badtlv:
1434  return -3;
1435 }
1436 
1437 static int
1439  const u_char *pptr, char *buf, size_t buflen)
1440 {
1441  nd_ipv6 addr;
1442  u_int plen;
1443 
1444  plen = GET_U_1(pptr); /* get prefix length */
1445 
1446  if ((24+64) > plen)
1447  return -1;
1448 
1449  plen -= (24+64); /* adjust prefixlen - labellength - RD len*/
1450 
1451  if (128 < plen)
1452  return -1;
1453 
1454  memset(&addr, 0, sizeof(addr));
1455  GET_CPY_BYTES(&addr, pptr + 12, (plen + 7) / 8);
1456  if (plen % 8) {
1457  addr[(plen + 7) / 8 - 1] &=
1458  ((0xff00 >> (plen % 8)) & 0xff);
1459  }
1460  /* the label may get offsetted by 4 bits so lets shift it right */
1461  snprintf(buf, buflen, "RD: %s, %s/%u, label:%u %s",
1462  bgp_vpn_rd_print(ndo, pptr+4),
1463  ip6addr_string(ndo, (const u_char *)&addr),
1464  plen,
1465  GET_BE_U_3(pptr + 1)>>4,
1466  ((GET_U_1(pptr + 3) & 1) == 0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
1467 
1468  return 12 + (plen + 7) / 8;
1469 }
1470 
1471 static int
1473  const u_char *pptr, char *buf, size_t buflen)
1474 {
1475  uint8_t addr[19];
1476  u_int plen;
1477 
1478  plen = GET_U_1(pptr); /* get prefix length */
1479 
1480  if (152 < plen)
1481  return -1;
1482 
1483  memset(&addr, 0, sizeof(addr));
1484  GET_CPY_BYTES(&addr, pptr + 4, (plen + 7) / 8);
1485  if (plen % 8) {
1486  addr[(plen + 7) / 8 - 1] &=
1487  ((0xff00 >> (plen % 8)) & 0xff);
1488  }
1489  /* Cannot use GET_ISONSAP_STRING (not packet buffer pointer) */
1490  snprintf(buf, buflen, "%s/%u",
1491  isonsap_string(ndo, addr,(plen + 7) / 8),
1492  plen);
1493 
1494  return 1 + (plen + 7) / 8;
1495 }
1496 
1497 static int
1499  const u_char *pptr, char *buf, size_t buflen)
1500 {
1501  uint8_t addr[19];
1502  u_int plen;
1503 
1504  plen = GET_U_1(pptr); /* get prefix length */
1505 
1506  if ((24+64) > plen)
1507  return -1;
1508 
1509  plen -= (24+64); /* adjust prefixlen - labellength - RD len*/
1510 
1511  if (152 < plen)
1512  return -1;
1513 
1514  memset(&addr, 0, sizeof(addr));
1515  GET_CPY_BYTES(&addr, pptr + 12, (plen + 7) / 8);
1516  if (plen % 8) {
1517  addr[(plen + 7) / 8 - 1] &= ((0xff00 >> (plen % 8)) & 0xff);
1518  }
1519  /* the label may get offsetted by 4 bits so lets shift it right */
1520  /* Cannot use GET_ISONSAP_STRING (not packet buffer pointer) */
1521  snprintf(buf, buflen, "RD: %s, %s/%u, label:%u %s",
1522  bgp_vpn_rd_print(ndo, pptr+4),
1523  isonsap_string(ndo, addr,(plen + 7) / 8),
1524  plen,
1525  GET_BE_U_3(pptr + 1)>>4,
1526  ((GET_U_1(pptr + 3) & 1) == 0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
1527 
1528  return 12 + (plen + 7) / 8;
1529 }
1530 
1531 /*
1532  * bgp_attr_get_as_size
1533  *
1534  * Try to find the size of the ASs encoded in an as-path. It is not obvious, as
1535  * both Old speakers that do not support 4 byte AS, and the new speakers that do
1536  * support, exchange AS-Path with the same path-attribute type value 0x02.
1537  */
1538 static u_int
1540  uint8_t bgpa_type, const u_char *pptr, u_int len)
1541 {
1542  const u_char *tptr = pptr;
1543 
1544  /*
1545  * If the path attribute is the optional AS4 path type, then we already
1546  * know, that ASs must be encoded in 4 byte format.
1547  */
1548  if (bgpa_type == BGPTYPE_AS4_PATH) {
1549  return 4;
1550  }
1551 
1552  /*
1553  * Let us assume that ASs are of 2 bytes in size, and check if the AS-Path
1554  * TLV is good. If not, ask the caller to try with AS encoded as 4 bytes
1555  * each.
1556  */
1557  while (tptr < pptr + len) {
1558  /*
1559  * If we do not find a valid segment type, our guess might be wrong.
1560  */
1561  if (GET_U_1(tptr) < BGP_AS_SEG_TYPE_MIN || GET_U_1(tptr) > BGP_AS_SEG_TYPE_MAX) {
1562  goto trunc;
1563  }
1564  tptr += 2 + GET_U_1(tptr + 1) * 2;
1565  }
1566 
1567  /*
1568  * If we correctly reached end of the AS path attribute data content,
1569  * then most likely ASs were indeed encoded as 2 bytes.
1570  */
1571  if (tptr == pptr + len) {
1572  return 2;
1573  }
1574 
1575 trunc:
1576 
1577  /*
1578  * We can come here, either we did not have enough data, or if we
1579  * try to decode 4 byte ASs in 2 byte format. Either way, return 4,
1580  * so that calller can try to decode each AS as of 4 bytes. If indeed
1581  * there was not enough data, it will crib and end the parse anyways.
1582  */
1583  return 4;
1584 }
1585 
1586 /*
1587  * The only way to know that a BGP UPDATE message is using add path is
1588  * by checking if the capability is in the OPEN message which we may have missed.
1589  * So this function checks if it is possible that the update could contain add path
1590  * and if so it checks that standard BGP doesn't make sense.
1591  */
1592 static int
1593 check_add_path(netdissect_options *ndo, const u_char *pptr, u_int length,
1594  u_int max_prefix_length)
1595 {
1596  u_int offset, prefix_length;
1597 
1598  if (length < 5) {
1599  return 0;
1600  }
1601 
1602  /*
1603  * Scan through the NLRI information under the assumpetion that
1604  * it doesn't have path IDs.
1605  */
1606  for (offset = 0; offset < length;) {
1607  offset += 4;
1608  if (!ND_TTEST_1(pptr + offset)) {
1609  /* We ran out of captured data; quit scanning. */
1610  break;
1611  }
1612  prefix_length = GET_U_1(pptr + offset);
1613  /*
1614  * Add 4 to cover the path id
1615  * and check the prefix length isn't greater than 32/128.
1616  */
1617  if (prefix_length > max_prefix_length) {
1618  return 0;
1619  }
1620  /* Add 1 for the prefix_length byte and prefix_length to cover the address */
1621  offset += 1 + ((prefix_length + 7) / 8);
1622  }
1623  /* check we haven't gone past the end of the section */
1624  if (offset > length) {
1625  return 0;
1626  }
1627 
1628  /* check it's not standard BGP */
1629  for (offset = 0; offset < length; ) {
1630  if (!ND_TTEST_1(pptr + offset)) {
1631  /* We ran out of captured data; quit scanning. */
1632  break;
1633  }
1634  prefix_length = GET_U_1(pptr + offset);
1635  /*
1636  * If the prefix_length is zero (0.0.0.0/0)
1637  * and since it's not the only address (length >= 5)
1638  * then it is add-path
1639  */
1640  if (prefix_length < 1 || prefix_length > max_prefix_length) {
1641  return 1;
1642  }
1643  offset += 1 + ((prefix_length + 7) / 8);
1644  }
1645  if (offset > length) {
1646  return 1;
1647  }
1648 
1649  /* assume not add-path by default */
1650  return 0;
1651 }
1652 
1653 static int
1655  const u_char *tptr, u_int tlen,
1656  uint16_t *afp, uint8_t *safip)
1657 {
1658  uint16_t af;
1659  uint8_t safi;
1660 
1661  af = GET_BE_U_2(tptr);
1662  *afp = af;
1663  safi = GET_U_1(tptr + 2);
1664  *safip = safi;
1665 
1666  ND_PRINT("\n\t AFI: %s (%u), %sSAFI: %s (%u)",
1667  tok2str(af_values, "Unknown AFI", af),
1668  af,
1669  (safi>128) ? "vendor specific " : "", /* 128 is meanwhile wellknown */
1670  tok2str(bgp_safi_values, "Unknown SAFI", safi),
1671  safi);
1672 
1673  switch(af<<8 | safi) {
1674  case (AFNUM_INET<<8 | SAFNUM_UNICAST):
1675  case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
1676  case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
1677  case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
1678  case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO):
1679  case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST):
1680  case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST):
1681  case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST):
1682  case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN):
1683  case (AFNUM_INET<<8 | SAFNUM_MDT):
1684  case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
1685  case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
1686  case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
1687  case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
1688  case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST):
1689  case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST):
1690  case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST):
1691  case (AFNUM_NSAP<<8 | SAFNUM_UNICAST):
1692  case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST):
1693  case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST):
1694  case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST):
1695  case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST):
1696  case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST):
1697  case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST):
1698  case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST):
1699  case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST):
1700  case (AFNUM_VPLS<<8 | SAFNUM_VPLS):
1701  break;
1702  default:
1703  ND_TCHECK_LEN(tptr, tlen);
1704  ND_PRINT("\n\t no AFI %u / SAFI %u decoder", af, safi);
1705  if (ndo->ndo_vflag <= 1)
1706  print_unknown_data(ndo, tptr, "\n\t ", tlen);
1707  return -1;
1708  }
1709  return 0;
1710 trunc:
1711  return -2;
1712 }
1713 
1714 static int
1715 bgp_nlri_print(netdissect_options *ndo, uint16_t af, uint8_t safi,
1716  const u_char *tptr, u_int len,
1717  char *buf, size_t buflen,
1718  int add_path4, int add_path6)
1719 {
1720  int advance;
1721  u_int path_id = 0;
1722 
1723  switch (af<<8 | safi) {
1724  case (AFNUM_INET<<8 | SAFNUM_UNICAST):
1725  case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
1726  case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
1727  if (add_path4) {
1728  path_id = GET_BE_U_4(tptr);
1729  tptr += 4;
1730  }
1731  advance = decode_prefix4(ndo, tptr, len, buf, buflen);
1732  if (advance == -1)
1733  ND_PRINT("\n\t (illegal prefix length)");
1734  else if (advance == -2)
1735  break; /* bytes left, but not enough */
1736  else
1737  ND_PRINT("\n\t %s", buf);
1738  if (add_path4) {
1739  ND_PRINT(" Path Id: %u", path_id);
1740  advance += 4;
1741  }
1742  break;
1743  case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
1744  advance = decode_labeled_prefix4(ndo, tptr, len, buf, buflen);
1745  if (advance == -1)
1746  ND_PRINT("\n\t (illegal prefix length)");
1747  else if (advance == -2)
1748  goto trunc;
1749  else if (advance == -3)
1750  break; /* bytes left, but not enough */
1751  else
1752  ND_PRINT("\n\t %s", buf);
1753  break;
1754  case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST):
1755  case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST):
1756  case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST):
1757  advance = decode_labeled_vpn_prefix4(ndo, tptr, buf, buflen);
1758  if (advance == -1)
1759  ND_PRINT("\n\t (illegal prefix length)");
1760  else
1761  ND_PRINT("\n\t %s", buf);
1762  break;
1763  case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO):
1764  advance = decode_rt_routing_info(ndo, tptr);
1765  break;
1766  case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): /* fall through */
1767  case (AFNUM_INET6<<8 | SAFNUM_MULTICAST_VPN):
1768  advance = decode_multicast_vpn(ndo, tptr, buf, buflen);
1769  if (advance == -1)
1770  ND_PRINT("\n\t (illegal prefix length)");
1771  else if (advance == -2)
1772  goto trunc;
1773  else
1774  ND_PRINT("\n\t %s", buf);
1775  break;
1776 
1777  case (AFNUM_INET<<8 | SAFNUM_MDT):
1778  advance = decode_mdt_vpn_nlri(ndo, tptr, buf, buflen);
1779  if (advance == -1)
1780  ND_PRINT("\n\t (illegal prefix length)");
1781  else if (advance == -2)
1782  goto trunc;
1783  else
1784  ND_PRINT("\n\t %s", buf);
1785  break;
1786  case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
1787  case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
1788  case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
1789  if (add_path6) {
1790  path_id = GET_BE_U_4(tptr);
1791  tptr += 4;
1792  }
1793  advance = decode_prefix6(ndo, tptr, len, buf, buflen);
1794  if (advance == -1)
1795  ND_PRINT("\n\t (illegal prefix length)");
1796  else if (advance == -2)
1797  break; /* bytes left, but not enough */
1798  else
1799  ND_PRINT("\n\t %s", buf);
1800  if (add_path6) {
1801  ND_PRINT(" Path Id: %u", path_id);
1802  advance += 4;
1803  }
1804  break;
1805  case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
1806  advance = decode_labeled_prefix6(ndo, tptr, len, buf, buflen);
1807  if (advance == -1)
1808  ND_PRINT("\n\t (illegal prefix length)");
1809  else if (advance == -2)
1810  goto trunc;
1811  else if (advance == -3)
1812  break; /* bytes left, but not enough */
1813  else
1814  ND_PRINT("\n\t %s", buf);
1815  break;
1816  case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST):
1817  case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST):
1818  case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST):
1819  advance = decode_labeled_vpn_prefix6(ndo, tptr, buf, buflen);
1820  if (advance == -1)
1821  ND_PRINT("\n\t (illegal prefix length)");
1822  else
1823  ND_PRINT("\n\t %s", buf);
1824  break;
1825  case (AFNUM_VPLS<<8 | SAFNUM_VPLS):
1826  case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST):
1827  case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST):
1828  case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST):
1829  advance = decode_labeled_vpn_l2(ndo, tptr, buf, buflen);
1830  if (advance == -1)
1831  ND_PRINT("\n\t (illegal length)");
1832  else if (advance == -2)
1833  goto trunc;
1834  else
1835  ND_PRINT("\n\t %s", buf);
1836  break;
1837  case (AFNUM_NSAP<<8 | SAFNUM_UNICAST):
1838  case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST):
1839  case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST):
1840  advance = decode_clnp_prefix(ndo, tptr, buf, buflen);
1841  if (advance == -1)
1842  ND_PRINT("\n\t (illegal prefix length)");
1843  else
1844  ND_PRINT("\n\t %s", buf);
1845  break;
1846  case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST):
1847  case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST):
1848  case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST):
1849  advance = decode_labeled_vpn_clnp_prefix(ndo, tptr, buf, buflen);
1850  if (advance == -1)
1851  ND_PRINT("\n\t (illegal prefix length)");
1852  else
1853  ND_PRINT("\n\t %s", buf);
1854  break;
1855  default:
1856  /*
1857  * This should not happen, we should have been protected
1858  * by bgp_mp_af_print()'s return value.
1859  */
1860  ND_PRINT("\n\t ERROR: no AFI %u / SAFI %u decoder", af, safi);
1861  advance = -4;
1862  break;
1863  }
1864  return advance;
1865 trunc: /* we rely on the caller to recognize -2 return value */
1866  return -2;
1867 }
1868 
1869 static int
1871  uint8_t atype, const u_char *pptr, u_int len,
1872  const unsigned attr_set_level)
1873 {
1874  /* allocate space for the largest possible string */
1875  char astostr[AS_STR_SIZE];
1876  u_int i;
1877  uint16_t af;
1878  uint8_t safi, snpa, nhlen;
1879  int advance;
1880  u_int tlen;
1881  const u_char *tptr;
1882  char buf[MAXHOSTNAMELEN + 100];
1883  u_int as_size;
1884  int add_path4, add_path6;
1885  int ret;
1886 
1887  tptr = pptr;
1888  tlen = len;
1889 
1890  switch (atype) {
1891  case BGPTYPE_ORIGIN:
1892  if (len != 1)
1893  ND_PRINT("invalid len");
1894  else {
1896  "Unknown Origin Typecode",
1897  GET_U_1(tptr)));
1898  }
1899  break;
1900 
1901  /*
1902  * Process AS4 byte path and AS2 byte path attributes here.
1903  */
1904  case BGPTYPE_AS4_PATH:
1905  case BGPTYPE_AS_PATH:
1906  if (len % 2) {
1907  ND_PRINT("invalid len");
1908  break;
1909  }
1910  if (!len) {
1911  ND_PRINT("empty");
1912  break;
1913  }
1914 
1915  /*
1916  * BGP updates exchanged between New speakers that support 4
1917  * byte AS, ASs are always encoded in 4 bytes. There is no
1918  * definitive way to find this, just by the packet's
1919  * contents. So, check for packet's TLV's sanity assuming
1920  * 2 bytes first, and it does not pass, assume that ASs are
1921  * encoded in 4 bytes format and move on.
1922  */
1923  as_size = bgp_attr_get_as_size(ndo, atype, pptr, len);
1924 
1925  while (tptr < pptr + len) {
1927  "?", GET_U_1(tptr)));
1928  for (i = 0; i < GET_U_1(tptr + 1) * as_size; i += as_size) {
1929  ND_TCHECK_LEN(tptr + 2 + i, as_size);
1930  ND_PRINT("%s ",
1931  as_printf(ndo, astostr, sizeof(astostr),
1932  as_size == 2 ?
1933  GET_BE_U_2(tptr + i + 2) :
1934  GET_BE_U_4(tptr + i + 2)));
1935  }
1937  "?", GET_U_1(tptr)));
1938  tptr += 2 + GET_U_1(tptr + 1) * as_size;
1939  }
1940  break;
1941  case BGPTYPE_NEXT_HOP:
1942  if (len != 4)
1943  ND_PRINT("invalid len");
1944  else {
1945  ND_PRINT("%s", GET_IPADDR_STRING(tptr));
1946  }
1947  break;
1949  case BGPTYPE_LOCAL_PREF:
1950  if (len != 4)
1951  ND_PRINT("invalid len");
1952  else {
1953  ND_PRINT("%u", GET_BE_U_4(tptr));
1954  }
1955  break;
1957  if (len != 0)
1958  ND_PRINT("invalid len");
1959  break;
1960  case BGPTYPE_AGGREGATOR:
1961 
1962  /*
1963  * Depending on the AS encoded is of 2 bytes or of 4 bytes,
1964  * the length of this PA can be either 6 bytes or 8 bytes.
1965  */
1966  if (len != 6 && len != 8) {
1967  ND_PRINT("invalid len");
1968  break;
1969  }
1970  ND_TCHECK_LEN(tptr, len);
1971  if (len == 6) {
1972  ND_PRINT(" AS #%s, origin %s",
1973  as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_2(tptr)),
1974  GET_IPADDR_STRING(tptr + 2));
1975  } else {
1976  ND_PRINT(" AS #%s, origin %s",
1977  as_printf(ndo, astostr, sizeof(astostr),
1978  GET_BE_U_4(tptr)), GET_IPADDR_STRING(tptr + 4));
1979  }
1980  break;
1981  case BGPTYPE_AGGREGATOR4:
1982  if (len != 8) {
1983  ND_PRINT("invalid len");
1984  break;
1985  }
1986  ND_PRINT(" AS #%s, origin %s",
1987  as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_4(tptr)),
1988  GET_IPADDR_STRING(tptr + 4));
1989  break;
1990  case BGPTYPE_COMMUNITIES:
1991  if (len % 4) {
1992  ND_PRINT("invalid len");
1993  break;
1994  }
1995  while (tlen != 0) {
1996  uint32_t comm;
1997  ND_TCHECK_4(tptr);
1998  if (tlen < 4)
1999  goto trunc;
2000  comm = GET_BE_U_4(tptr);
2001  switch (comm) {
2003  ND_PRINT(" NO_EXPORT");
2004  break;
2006  ND_PRINT(" NO_ADVERTISE");
2007  break;
2009  ND_PRINT(" NO_EXPORT_SUBCONFED");
2010  break;
2011  default:
2012  ND_PRINT("%u:%u%s",
2013  (comm >> 16) & 0xffff,
2014  comm & 0xffff,
2015  (tlen>4) ? ", " : "");
2016  break;
2017  }
2018  tlen -=4;
2019  tptr +=4;
2020  }
2021  break;
2022  case BGPTYPE_ORIGINATOR_ID:
2023  if (len != 4) {
2024  ND_PRINT("invalid len");
2025  break;
2026  }
2027  ND_PRINT("%s",GET_IPADDR_STRING(tptr));
2028  break;
2029  case BGPTYPE_CLUSTER_LIST:
2030  if (len % 4) {
2031  ND_PRINT("invalid len");
2032  break;
2033  }
2034  while (tlen != 0) {
2035  if (tlen < 4)
2036  goto trunc;
2037  ND_PRINT("%s%s",
2038  GET_IPADDR_STRING(tptr),
2039  (tlen>4) ? ", " : "");
2040  tlen -=4;
2041  tptr +=4;
2042  }
2043  break;
2044  case BGPTYPE_MP_REACH_NLRI:
2045  ND_TCHECK_3(tptr);
2046  if (tlen < 3)
2047  goto trunc;
2048  ret = bgp_mp_af_print(ndo, tptr, tlen, &af, &safi);
2049  if (ret == -2)
2050  goto trunc;
2051  if (ret < 0)
2052  break;
2053 
2054  tptr += 3;
2055  tlen -= 3;
2056 
2057  ND_TCHECK_1(tptr);
2058  if (tlen < 1)
2059  goto trunc;
2060  nhlen = GET_U_1(tptr);
2061  tptr++;
2062  tlen--;
2063 
2064  if (nhlen) {
2065  u_int nnh = 0;
2066  uint8_t tnhlen = nhlen;
2067  if (tlen < tnhlen)
2068  goto trunc;
2069  ND_PRINT("\n\t nexthop: ");
2070  while (tnhlen != 0) {
2071  if (nnh++ > 0) {
2072  ND_PRINT(", " );
2073  }
2074  switch(af<<8 | safi) {
2075  case (AFNUM_INET<<8 | SAFNUM_UNICAST):
2076  case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
2077  case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
2078  case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
2079  case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO):
2080  case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN):
2081  case (AFNUM_INET<<8 | SAFNUM_MDT):
2082  if (tnhlen < sizeof(nd_ipv4)) {
2083  ND_PRINT("invalid len");
2084  tptr += tnhlen;
2085  tlen -= tnhlen;
2086  tnhlen = 0;
2087  } else {
2088  ND_PRINT("%s",GET_IPADDR_STRING(tptr));
2089  tptr += sizeof(nd_ipv4);
2090  tnhlen -= sizeof(nd_ipv4);
2091  tlen -= sizeof(nd_ipv4);
2092  }
2093  break;
2094  case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST):
2095  case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST):
2096  case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST):
2097  if (tnhlen < sizeof(nd_ipv4)+BGP_VPN_RD_LEN) {
2098  ND_PRINT("invalid len");
2099  tptr += tnhlen;
2100  tlen -= tnhlen;
2101  tnhlen = 0;
2102  } else {
2103  ND_PRINT("RD: %s, %s",
2104  bgp_vpn_rd_print(ndo, tptr),
2106  tptr += (sizeof(nd_ipv4)+BGP_VPN_RD_LEN);
2107  tlen -= (sizeof(nd_ipv4)+BGP_VPN_RD_LEN);
2108  tnhlen -= (sizeof(nd_ipv4)+BGP_VPN_RD_LEN);
2109  }
2110  break;
2111  case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
2112  case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
2113  case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
2114  case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
2115  if (tnhlen < sizeof(nd_ipv6)) {
2116  ND_PRINT("invalid len");
2117  tptr += tnhlen;
2118  tlen -= tnhlen;
2119  tnhlen = 0;
2120  } else {
2121  ND_PRINT("%s", GET_IP6ADDR_STRING(tptr));
2122  tptr += sizeof(nd_ipv6);
2123  tlen -= sizeof(nd_ipv6);
2124  tnhlen -= sizeof(nd_ipv6);
2125  }
2126  break;
2127  case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST):
2128  case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST):
2129  case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST):
2130  if (tnhlen < sizeof(nd_ipv6)+BGP_VPN_RD_LEN) {
2131  ND_PRINT("invalid len");
2132  tptr += tnhlen;
2133  tlen -= tnhlen;
2134  tnhlen = 0;
2135  } else {
2136  ND_PRINT("RD: %s, %s",
2137  bgp_vpn_rd_print(ndo, tptr),
2139  tptr += (sizeof(nd_ipv6)+BGP_VPN_RD_LEN);
2140  tlen -= (sizeof(nd_ipv6)+BGP_VPN_RD_LEN);
2141  tnhlen -= (sizeof(nd_ipv6)+BGP_VPN_RD_LEN);
2142  }
2143  break;
2144  case (AFNUM_VPLS<<8 | SAFNUM_VPLS):
2145  case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST):
2146  case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST):
2147  case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST):
2148  if (tnhlen < sizeof(nd_ipv4)) {
2149  ND_PRINT("invalid len");
2150  tptr += tnhlen;
2151  tlen -= tnhlen;
2152  tnhlen = 0;
2153  } else {
2154  ND_PRINT("%s", GET_IPADDR_STRING(tptr));
2155  tptr += (sizeof(nd_ipv4));
2156  tlen -= (sizeof(nd_ipv4));
2157  tnhlen -= (sizeof(nd_ipv4));
2158  }
2159  break;
2160  case (AFNUM_NSAP<<8 | SAFNUM_UNICAST):
2161  case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST):
2162  case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST):
2163  ND_PRINT("%s", GET_ISONSAP_STRING(tptr, tnhlen));
2164  tptr += tnhlen;
2165  tlen -= tnhlen;
2166  tnhlen = 0;
2167  break;
2168 
2169  case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST):
2170  case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST):
2171  case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST):
2172  if (tnhlen < BGP_VPN_RD_LEN+1) {
2173  ND_PRINT("invalid len");
2174  tptr += tnhlen;
2175  tlen -= tnhlen;
2176  tnhlen = 0;
2177  } else {
2178  ND_TCHECK_LEN(tptr, tnhlen);
2179  ND_PRINT("RD: %s, %s",
2180  bgp_vpn_rd_print(ndo, tptr),
2182  /* rfc986 mapped IPv4 address ? */
2183  if (GET_BE_U_4(tptr + BGP_VPN_RD_LEN) == 0x47000601)
2184  ND_PRINT(" = %s", GET_IPADDR_STRING(tptr+BGP_VPN_RD_LEN+4));
2185  /* rfc1888 mapped IPv6 address ? */
2186  else if (GET_BE_U_3(tptr + BGP_VPN_RD_LEN) == 0x350000)
2187  ND_PRINT(" = %s", GET_IP6ADDR_STRING(tptr+BGP_VPN_RD_LEN+3));
2188  tptr += tnhlen;
2189  tlen -= tnhlen;
2190  tnhlen = 0;
2191  }
2192  break;
2193  default:
2194  /*
2195  * bgp_mp_af_print() should have saved us from
2196  * an unsupported AFI/SAFI.
2197  */
2198  ND_PRINT("ERROR: no AFI %u/SAFI %u nexthop decoder", af, safi);
2199  tptr += tnhlen;
2200  tlen -= tnhlen;
2201  tnhlen = 0;
2202  goto done;
2203  break;
2204  }
2205  }
2206  }
2207  ND_PRINT(", nh-length: %u", nhlen);
2208 
2209  /* As per RFC 2858; this is reserved in RFC 4760 */
2210  if (tlen < 1)
2211  goto trunc;
2212  snpa = GET_U_1(tptr);
2213  tptr++;
2214  tlen--;
2215 
2216  if (snpa) {
2217  ND_PRINT("\n\t %u SNPA", snpa);
2218  for (/*nothing*/; snpa != 0; snpa--) {
2219  uint8_t snpalen;
2220  if (tlen < 1)
2221  goto trunc;
2222  snpalen = GET_U_1(tptr);
2223  ND_PRINT("\n\t %u bytes", snpalen);
2224  tptr++;
2225  tlen--;
2226  if (tlen < snpalen)
2227  goto trunc;
2228  ND_TCHECK_LEN(tptr, snpalen);
2229  tptr += snpalen;
2230  tlen -= snpalen;
2231  }
2232  } else {
2233  ND_PRINT(", no SNPA");
2234  }
2235 
2236  add_path4 = check_add_path(ndo, tptr, (len-ND_BYTES_BETWEEN(tptr, pptr)), 32);
2237  add_path6 = check_add_path(ndo, tptr, (len-ND_BYTES_BETWEEN(tptr, pptr)), 128);
2238 
2239  while (tptr < pptr + len) {
2240  advance = bgp_nlri_print(ndo, af, safi, tptr, len, buf, sizeof(buf),
2241  add_path4, add_path6);
2242  if (advance == -2)
2243  goto trunc;
2244  if (advance < 0)
2245  break;
2246  tptr += advance;
2247  }
2248  break;
2249 
2252  ret = bgp_mp_af_print(ndo, tptr, tlen, &af, &safi);
2253  if (ret == -2)
2254  goto trunc;
2255  if (ret < 0)
2256  break;
2257 
2258  if (len == BGP_MP_NLRI_MINSIZE)
2259  ND_PRINT("\n\t End-of-Rib Marker (empty NLRI)");
2260 
2261  tptr += 3;
2262 
2263  add_path4 = check_add_path(ndo, tptr, (len-ND_BYTES_BETWEEN(tptr, pptr)), 32);
2264  add_path6 = check_add_path(ndo, tptr, (len-ND_BYTES_BETWEEN(tptr, pptr)), 128);
2265 
2266  while (tptr < pptr + len) {
2267  advance = bgp_nlri_print(ndo, af, safi, tptr, len, buf, sizeof(buf),
2268  add_path4, add_path6);
2269  if (advance == -2)
2270  goto trunc;
2271  if (advance < 0)
2272  break;
2273  tptr += advance;
2274  }
2275  break;
2277  if (len % 8) {
2278  ND_PRINT("invalid len");
2279  break;
2280  }
2281  while (tlen != 0) {
2282  uint16_t extd_comm;
2283 
2284  ND_TCHECK_2(tptr);
2285  if (tlen < 2)
2286  goto trunc;
2287  extd_comm=GET_BE_U_2(tptr);
2288 
2289  ND_PRINT("\n\t %s (0x%04x), Flags [%s]",
2291  "unknown extd community typecode",
2292  extd_comm),
2293  extd_comm,
2294  bittok2str(bgp_extd_comm_flag_values, "none", extd_comm));
2295 
2296  ND_TCHECK_8(tptr);
2297  if (tlen < 8)
2298  goto trunc;
2299  ND_PRINT(": ");
2300  bgp_extended_community_print(ndo, tptr);
2301  tlen -= 8;
2302  tptr += 8;
2303  }
2304  break;
2305 
2306  case BGPTYPE_PMSI_TUNNEL:
2307  {
2308  uint8_t tunnel_type, flags;
2309 
2310  ND_TCHECK_5(tptr);
2311  if (tlen < 5)
2312  goto trunc;
2313  flags = GET_U_1(tptr);
2314  tunnel_type = GET_U_1(tptr + 1);
2315 
2316  ND_PRINT("\n\t Tunnel-type %s (%u), Flags [%s], MPLS Label %u",
2318  tunnel_type,
2319  bittok2str(bgp_pmsi_flag_values, "none", flags),
2320  GET_BE_U_3(tptr + 2)>>4);
2321 
2322  tptr +=5;
2323  tlen -= 5;
2324 
2325  switch (tunnel_type) {
2326  case BGP_PMSI_TUNNEL_PIM_SM: /* fall through */
2328  ND_PRINT("\n\t Sender %s, P-Group %s",
2329  GET_IPADDR_STRING(tptr),
2330  GET_IPADDR_STRING(tptr+4));
2331  break;
2332 
2334  ND_PRINT("\n\t Root-Node %s, P-Group %s",
2335  GET_IPADDR_STRING(tptr),
2336  GET_IPADDR_STRING(tptr+4));
2337  break;
2339  ND_PRINT("\n\t Tunnel-Endpoint %s",
2340  GET_IPADDR_STRING(tptr));
2341  break;
2342  case BGP_PMSI_TUNNEL_LDP_P2MP: /* fall through */
2344  ND_PRINT("\n\t Root-Node %s, LSP-ID 0x%08x",
2345  GET_IPADDR_STRING(tptr),
2346  GET_BE_U_4(tptr + 4));
2347  break;
2349  ND_PRINT("\n\t Extended-Tunnel-ID %s, P2MP-ID 0x%08x",
2350  GET_IPADDR_STRING(tptr),
2351  GET_BE_U_4(tptr + 4));
2352  break;
2353  default:
2354  if (ndo->ndo_vflag <= 1) {
2355  print_unknown_data(ndo, tptr, "\n\t ", tlen);
2356  }
2357  }
2358  break;
2359  }
2360  case BGPTYPE_AIGP:
2361  {
2362  uint8_t type;
2363  uint16_t length;
2364 
2365  while (tlen >= 3) {
2366  type = GET_U_1(tptr);
2367  length = GET_BE_U_2(tptr + 1);
2368  tptr += 3;
2369  tlen -= 3;
2370 
2371  ND_PRINT("\n\t %s TLV (%u), length %u",
2372  tok2str(bgp_aigp_values, "Unknown", type),
2373  type, length);
2374 
2375  if (length < 3)
2376  goto trunc;
2377  length -= 3;
2378 
2379  /*
2380  * Check if we can read the TLV data.
2381  */
2382  ND_TCHECK_LEN(tptr + 3, length);
2383  if (tlen < length)
2384  goto trunc;
2385 
2386  switch (type) {
2387 
2388  case BGP_AIGP_TLV:
2389  if (length < 8)
2390  goto trunc;
2391  ND_PRINT(", metric %" PRIu64,
2392  GET_BE_U_8(tptr));
2393  break;
2394 
2395  default:
2396  if (ndo->ndo_vflag <= 1) {
2397  print_unknown_data(ndo, tptr,"\n\t ", length);
2398  }
2399  }
2400 
2401  tptr += length;
2402  tlen -= length;
2403  }
2404  break;
2405  }
2406  case BGPTYPE_ATTR_SET:
2407  ND_TCHECK_4(tptr);
2408  if (len < 4)
2409  goto trunc;
2410  ND_PRINT("\n\t Origin AS: %s",
2411  as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_4(tptr)));
2412  tptr += 4;
2413  len -= 4;
2414 
2415  while (len) {
2416  u_int aflags, alenlen, alen;
2417 
2418  ND_TCHECK_2(tptr);
2419  if (len < 2) {
2420  ND_PRINT(" [path attr too short]");
2421  tptr += len;
2422  break;
2423  }
2424  aflags = GET_U_1(tptr);
2425  atype = GET_U_1(tptr + 1);
2426  tptr += 2;
2427  len -= 2;
2428  alenlen = bgp_attr_lenlen(aflags, tptr);
2429  ND_TCHECK_LEN(tptr, alenlen);
2430  if (len < alenlen) {
2431  ND_PRINT(" [path attr too short]");
2432  tptr += len;
2433  break;
2434  }
2435  alen = bgp_attr_len(aflags, tptr);
2436  tptr += alenlen;
2437  len -= alenlen;
2438 
2439  ND_PRINT("\n\t %s (%u), length: %u",
2441  "Unknown Attribute", atype),
2442  atype,
2443  alen);
2444 
2445  if (aflags) {
2446  ND_PRINT(", Flags [%s%s%s%s",
2447  aflags & 0x80 ? "O" : "",
2448  aflags & 0x40 ? "T" : "",
2449  aflags & 0x20 ? "P" : "",
2450  aflags & 0x10 ? "E" : "");
2451  if (aflags & 0xf)
2452  ND_PRINT("+%x", aflags & 0xf);
2453  ND_PRINT("]");
2454  }
2455  ND_PRINT(": ");
2456  if (len < alen) {
2457  ND_PRINT(" [path attr too short]");
2458  tptr += len;
2459  break;
2460  }
2461  /*
2462  * The protocol encoding per se allows ATTR_SET to be nested
2463  * as many times as the message can accommodate. This printer
2464  * used to be able to recurse into ATTR_SET contents until the
2465  * stack exhaustion, but now there is a limit on that (if live
2466  * protocol exchange goes that many levels deep, something is
2467  * probably wrong anyway). Feel free to refine this value if
2468  * you can find the spec with respective normative text.
2469  */
2470  if (attr_set_level == 10)
2471  ND_PRINT("(too many nested levels, not recursing)");
2472  else if (!bgp_attr_print(ndo, atype, tptr, alen, attr_set_level + 1))
2473  return 0;
2474  tptr += alen;
2475  len -= alen;
2476  }
2477  break;
2478 
2480  if (len == 0 || len % 12) {
2481  ND_PRINT("invalid len");
2482  break;
2483  }
2484  ND_PRINT("\n\t ");
2485  while (len != 0) {
2486  ND_PRINT("%u:%u:%u%s",
2487  GET_BE_U_4(tptr),
2488  GET_BE_U_4(tptr + 4),
2489  GET_BE_U_4(tptr + 8),
2490  (len > 12) ? ", " : "");
2491  tptr += 12;
2492  /*
2493  * len will always be a multiple of 12, as per the above,
2494  * so this will never underflow.
2495  */
2496  len -= 12;
2497  }
2498  break;
2499  default:
2500  ND_TCHECK_LEN(pptr, len);
2501  ND_PRINT("\n\t no Attribute %u decoder", atype); /* we have no decoder for the attribute */
2502  if (ndo->ndo_vflag <= 1)
2503  print_unknown_data(ndo, pptr, "\n\t ", len);
2504  break;
2505  }
2506 done:
2507  if (ndo->ndo_vflag > 1 && len) { /* omit zero length attributes*/
2508  ND_TCHECK_LEN(pptr, len);
2509  print_unknown_data(ndo, pptr, "\n\t ", len);
2510  }
2511  return 1;
2512 
2513 trunc:
2514  return 0;
2515 }
2516 
2517 static void
2519  const u_char *opt, u_int caps_len)
2520 {
2521  /* allocate space for the largest possible string */
2522  char astostr[AS_STR_SIZE];
2523  u_int cap_type, cap_len, tcap_len, cap_offset;
2524  u_int i = 0;
2525 
2526  while (i < caps_len) {
2528  cap_type=GET_U_1(opt + i);
2529  cap_len=GET_U_1(opt + i + 1);
2530  ND_PRINT("\n\t %s (%u), length: %u",
2531  tok2str(bgp_capcode_values, "Unknown", cap_type),
2532  cap_type,
2533  cap_len);
2534  ND_TCHECK_LEN(opt + 2 + i, cap_len);
2535  switch (cap_type) {
2536  case BGP_CAPCODE_MP:
2537  /* AFI (16 bits), Reserved (8 bits), SAFI (8 bits) */
2538  if (cap_len < 4) {
2539  ND_PRINT(" (too short, < 4)");
2540  return;
2541  }
2542  ND_PRINT("\n\t\tAFI %s (%u), SAFI %s (%u)",
2543  tok2str(af_values, "Unknown", GET_BE_U_2(opt + i + 2)),
2544  GET_BE_U_2(opt + i + 2),
2545  tok2str(bgp_safi_values, "Unknown", GET_U_1(opt + i + 5)),
2546  GET_U_1(opt + i + 5));
2547  break;
2548  case BGP_CAPCODE_ML:
2549  cap_offset = 2;
2550  tcap_len = cap_len;
2551  while (tcap_len >= 4) {
2552  ND_PRINT( "\n\t\tAFI %s (%u), SAFI %s (%u), Count: %u",
2553  tok2str(af_values, "Unknown",
2554  GET_BE_U_2(opt + i + cap_offset)),
2555  GET_BE_U_2(opt + i + cap_offset),
2556  tok2str(bgp_safi_values, "Unknown",
2557  GET_U_1(opt + i + cap_offset + 2)),
2558  GET_U_1(opt + i + cap_offset + 2),
2559  GET_U_1(opt + i + cap_offset + 3));
2560  tcap_len -= 4;
2561  cap_offset += 4;
2562  }
2563  break;
2564  case BGP_CAPCODE_RESTART:
2565  /* Restart Flags (4 bits), Restart Time in seconds (12 bits) */
2566  if (cap_len < 2) {
2567  ND_PRINT(" (too short, < 2)");
2568  return;
2569  }
2570  tcap_len=cap_len;
2571  ND_PRINT("\n\t\tRestart Flags: [%s], Restart Time %us",
2572  ((GET_U_1(opt + i + 2))&0x80) ? "R" : "none",
2573  GET_BE_U_2(opt + i + 2)&0xfff);
2574  tcap_len-=2;
2575  cap_offset=4;
2576  while(tcap_len>=4) {
2577  ND_PRINT("\n\t\t AFI %s (%u), SAFI %s (%u), Forwarding state preserved: %s",
2578  tok2str(af_values,"Unknown",
2579  GET_BE_U_2(opt + i + cap_offset)),
2580  GET_BE_U_2(opt + i + cap_offset),
2581  tok2str(bgp_safi_values,"Unknown",
2582  GET_U_1(opt + i + cap_offset + 2)),
2583  GET_U_1(opt + (i + cap_offset + 2)),
2584  ((GET_U_1(opt + (i + cap_offset + 3)))&0x80) ? "yes" : "no" );
2585  tcap_len -= 4;
2586  cap_offset += 4;
2587  }
2588  break;
2589  case BGP_CAPCODE_RR:
2590  case BGP_CAPCODE_LLGR:
2591  case BGP_CAPCODE_RR_CISCO:
2592  break;
2593  case BGP_CAPCODE_AS_NEW:
2594  /*
2595  * Extract the 4 byte AS number encoded.
2596  */
2597  if (cap_len < 4) {
2598  ND_PRINT(" (too short, < 4)");
2599  return;
2600  }
2601  ND_PRINT("\n\t\t 4 Byte AS %s",
2602  as_printf(ndo, astostr, sizeof(astostr),
2603  GET_BE_U_4(opt + i + 2)));
2604  break;
2605  case BGP_CAPCODE_ADD_PATH:
2606  if (cap_len == 0) {
2607  ND_PRINT(" (bogus)"); /* length */
2608  break;
2609  }
2610  tcap_len=cap_len;
2611  cap_offset=2;
2612  while (tcap_len != 0) {
2613  if (tcap_len < 4) {
2614  nd_print_invalid(ndo);
2615  break;
2616  }
2617  ND_PRINT("\n\t\tAFI %s (%u), SAFI %s (%u), Send/Receive: %s",
2618  tok2str(af_values,"Unknown",GET_BE_U_2(opt + i + cap_offset)),
2619  GET_BE_U_2(opt + i + cap_offset),
2620  tok2str(bgp_safi_values,"Unknown",GET_U_1(opt + i + cap_offset + 2)),
2621  GET_U_1(opt + (i + cap_offset + 2)),
2622  tok2str(bgp_add_path_recvsend,"Bogus (0x%02x)",GET_U_1(opt + i + cap_offset + 3))
2623  );
2624  tcap_len -= 4;
2625  cap_offset += 4;
2626  }
2627  break;
2628  default:
2629  ND_PRINT("\n\t\tno decoder for Capability %u",
2630  cap_type);
2631  if (ndo->ndo_vflag <= 1)
2632  print_unknown_data(ndo, opt + i + 2, "\n\t\t",
2633  cap_len);
2634  break;
2635  }
2636  if (ndo->ndo_vflag > 1 && cap_len != 0) {
2637  print_unknown_data(ndo, opt + i + 2, "\n\t\t", cap_len);
2638  }
2639  i += BGP_CAP_HEADER_SIZE + cap_len;
2640  }
2641  return;
2642 
2643 trunc:
2644  nd_print_trunc(ndo);
2645 }
2646 
2647 static void
2649  const u_char *dat, u_int length)
2650 {
2651  /* allocate space for the largest possible string */
2652  char astostr[AS_STR_SIZE];
2653  const struct bgp_open *bgp_open_header;
2654  u_int optslen;
2655  const struct bgp_opt *bgpopt;
2656  const u_char *opt;
2657  u_int i;
2658 
2660  if (length < BGP_OPEN_SIZE)
2661  goto trunc;
2662 
2663  bgp_open_header = (const struct bgp_open *)dat;
2664 
2665  ND_PRINT("\n\t Version %u, ",
2666  GET_U_1(bgp_open_header->bgpo_version));
2667  ND_PRINT("my AS %s, ",
2668  as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_2(bgp_open_header->bgpo_myas)));
2669  ND_PRINT("Holdtime %us, ",
2670  GET_BE_U_2(bgp_open_header->bgpo_holdtime));
2671  ND_PRINT("ID %s", GET_IPADDR_STRING(bgp_open_header->bgpo_id));
2672  optslen = GET_U_1(bgp_open_header->bgpo_optlen);
2673  ND_PRINT("\n\t Optional parameters, length: %u", optslen);
2674 
2675  opt = dat + BGP_OPEN_SIZE;
2676  length -= BGP_OPEN_SIZE;
2677 
2678  i = 0;
2679  while (i < optslen) {
2680  uint8_t opt_type, opt_len;
2681 
2682  ND_TCHECK_LEN(opt + i, BGP_OPT_SIZE);
2683  if (length < BGP_OPT_SIZE + i)
2684  goto trunc;
2685  bgpopt = (const struct bgp_opt *)(opt + i);
2686  opt_type = GET_U_1(bgpopt->bgpopt_type);
2687  opt_len = GET_U_1(bgpopt->bgpopt_len);
2688  if (BGP_OPT_SIZE + i + opt_len > optslen) {
2689  ND_PRINT("\n\t Option %u, length: %u, goes past the end of the options",
2690  opt_type, opt_len);
2691  break;
2692  }
2693 
2694  ND_PRINT("\n\t Option %s (%u), length: %u",
2695  tok2str(bgp_opt_values,"Unknown",opt_type),
2696  opt_type,
2697  opt_len);
2698 
2699  /* now let's decode the options we know*/
2700  switch(opt_type) {
2701 
2702  case BGP_OPT_CAP:
2703  bgp_capabilities_print(ndo, opt + BGP_OPT_SIZE + i,
2704  opt_len);
2705  break;
2706 
2707  case BGP_OPT_AUTH:
2708  default:
2709  ND_PRINT("\n\t no decoder for option %u",
2710  opt_type);
2711  break;
2712  }
2713  i += BGP_OPT_SIZE + opt_len;
2714  }
2715  return;
2716 trunc:
2717  nd_print_trunc(ndo);
2718 }
2719 
2720 static void
2722  const u_char *dat, u_int length)
2723 {
2724  const u_char *p;
2725  u_int withdrawn_routes_len;
2726  char buf[MAXHOSTNAMELEN + 100];
2727  int wpfx;
2728  u_int len;
2729  int i;
2730  int add_path;
2731  u_int path_id = 0;
2732 
2733  ND_TCHECK_LEN(dat, BGP_SIZE);
2734  if (length < BGP_SIZE)
2735  goto trunc;
2736  p = dat + BGP_SIZE;
2737  length -= BGP_SIZE;
2738 
2739  /* Unfeasible routes */
2740  ND_TCHECK_2(p);
2741  if (length < 2)
2742  goto trunc;
2743  withdrawn_routes_len = GET_BE_U_2(p);
2744  p += 2;
2745  length -= 2;
2746  if (withdrawn_routes_len > 1) {
2747  /*
2748  * Without keeping state from the original NLRI message,
2749  * it's not possible to tell if this a v4 or v6 route,
2750  * so only try to decode it if we're not v6 enabled.
2751  */
2752  ND_TCHECK_LEN(p, withdrawn_routes_len);
2753  if (length < withdrawn_routes_len)
2754  goto trunc;
2755  ND_PRINT("\n\t Withdrawn routes:");
2756  add_path = check_add_path(ndo, p, withdrawn_routes_len, 32);
2757  while (withdrawn_routes_len != 0) {
2758  if (add_path) {
2759  if (withdrawn_routes_len < 4) {
2760  p += withdrawn_routes_len;
2761  length -= withdrawn_routes_len;
2762  break;
2763  }
2764  path_id = GET_BE_U_4(p);
2765  p += 4;
2766  length -= 4;
2767  withdrawn_routes_len -= 4;
2768  }
2769  wpfx = decode_prefix4(ndo, p, withdrawn_routes_len, buf, sizeof(buf));
2770  if (wpfx == -1) {
2771  ND_PRINT("\n\t (illegal prefix length)");
2772  break;
2773  } else if (wpfx == -2)
2774  goto trunc; /* bytes left, but not enough */
2775  else {
2776  ND_PRINT("\n\t %s", buf);
2777  if (add_path) {
2778  ND_PRINT(" Path Id: %u", path_id);
2779  }
2780  p += wpfx;
2781  length -= wpfx;
2782  withdrawn_routes_len -= wpfx;
2783  }
2784  }
2785  } else {
2786  ND_TCHECK_LEN(p, withdrawn_routes_len);
2787  if (length < withdrawn_routes_len)
2788  goto trunc;
2789  p += withdrawn_routes_len;
2790  length -= withdrawn_routes_len;
2791  }
2792 
2793  ND_TCHECK_2(p);
2794  if (length < 2)
2795  goto trunc;
2796  len = GET_BE_U_2(p);
2797  p += 2;
2798  length -= 2;
2799 
2800  if (withdrawn_routes_len == 0 && len == 0 && length == 0) {
2801  /* No withdrawn routes, no path attributes, no NLRI */
2802  ND_PRINT("\n\t End-of-Rib Marker (empty NLRI)");
2803  return;
2804  }
2805 
2806  if (len) {
2807  /* do something more useful!*/
2808  while (len) {
2809  uint8_t aflags, atype, alenlen;
2810  uint16_t alen;
2811 
2812  ND_TCHECK_2(p);
2813  if (length < 2)
2814  goto trunc;
2815  if (len < 2) {
2816  ND_PRINT("\n\t [path attrs too short]");
2817  p += len;
2818  length -= len;
2819  break;
2820  }
2821  aflags = GET_U_1(p);
2822  atype = GET_U_1(p + 1);
2823  p += 2;
2824  len -= 2;
2825  length -= 2;
2826  alenlen = bgp_attr_lenlen(aflags, p);
2827  ND_TCHECK_LEN(p, alenlen);
2828  if (length < alenlen)
2829  goto trunc;
2830  if (len < alenlen) {
2831  ND_PRINT("\n\t [path attrs too short]");
2832  p += len;
2833  length -= len;
2834  break;
2835  }
2836  alen = bgp_attr_len(aflags, p);
2837  p += alenlen;
2838  len -= alenlen;
2839  length -= alenlen;
2840 
2841  ND_PRINT("\n\t %s (%u), length: %u",
2842  tok2str(bgp_attr_values, "Unknown Attribute", atype),
2843  atype,
2844  alen);
2845 
2846  if (aflags) {
2847  ND_PRINT(", Flags [%s%s%s%s",
2848  aflags & 0x80 ? "O" : "",
2849  aflags & 0x40 ? "T" : "",
2850  aflags & 0x20 ? "P" : "",
2851  aflags & 0x10 ? "E" : "");
2852  if (aflags & 0xf)
2853  ND_PRINT("+%x", aflags & 0xf);
2854  ND_PRINT("]: ");
2855  }
2856  if (len < alen) {
2857  ND_PRINT(" [path attrs too short]");
2858  p += len;
2859  length -= len;
2860  break;
2861  }
2862  if (length < alen)
2863  goto trunc;
2864  if (!bgp_attr_print(ndo, atype, p, alen, 0))
2865  goto trunc;
2866  p += alen;
2867  len -= alen;
2868  length -= alen;
2869  }
2870  }
2871 
2872  if (length) {
2873  add_path = check_add_path(ndo, p, length, 32);
2874  ND_PRINT("\n\t Updated routes:");
2875  while (length != 0) {
2876  if (add_path) {
2877  ND_TCHECK_4(p);
2878  if (length < 4)
2879  goto trunc;
2880  path_id = GET_BE_U_4(p);
2881  p += 4;
2882  length -= 4;
2883  }
2884  i = decode_prefix4(ndo, p, length, buf, sizeof(buf));
2885  if (i == -1) {
2886  ND_PRINT("\n\t (illegal prefix length)");
2887  break;
2888  } else if (i == -2)
2889  goto trunc; /* bytes left, but not enough */
2890  else {
2891  ND_PRINT("\n\t %s", buf);
2892  if (add_path) {
2893  ND_PRINT(" Path Id: %u", path_id);
2894  }
2895  p += i;
2896  length -= i;
2897  }
2898  }
2899  }
2900  return;
2901 trunc:
2902  nd_print_trunc(ndo);
2903 }
2904 
2905 static void
2907  const u_char *dat, u_int length)
2908 {
2909  const struct bgp_notification *bgp_notification_header;
2910  const u_char *tptr;
2911  uint8_t bgpn_major, bgpn_minor;
2912  uint8_t shutdown_comm_length;
2913  uint8_t remainder_offset;
2914 
2916  if (length<BGP_NOTIFICATION_SIZE)
2917  return;
2918 
2919  bgp_notification_header = (const struct bgp_notification *)dat;
2920  bgpn_major = GET_U_1(bgp_notification_header->bgpn_major);
2921  bgpn_minor = GET_U_1(bgp_notification_header->bgpn_minor);
2922 
2923  ND_PRINT(", %s (%u)",
2924  tok2str(bgp_notify_major_values, "Unknown Error",
2925  bgpn_major),
2926  bgpn_major);
2927 
2928  switch (bgpn_major) {
2929 
2930  case BGP_NOTIFY_MAJOR_MSG:
2931  ND_PRINT(", subcode %s (%u)",
2933  bgpn_minor),
2934  bgpn_minor);
2935  break;
2936  case BGP_NOTIFY_MAJOR_OPEN:
2937  ND_PRINT(", subcode %s (%u)",
2939  bgpn_minor),
2940  bgpn_minor);
2941  break;
2943  ND_PRINT(", subcode %s (%u)",
2945  bgpn_minor),
2946  bgpn_minor);
2947  break;
2948  case BGP_NOTIFY_MAJOR_FSM:
2949  ND_PRINT(" subcode %s (%u)",
2951  bgpn_minor),
2952  bgpn_minor);
2953  break;
2954  case BGP_NOTIFY_MAJOR_CAP:
2955  ND_PRINT(" subcode %s (%u)",
2957  bgpn_minor),
2958  bgpn_minor);
2959  break;
2961  ND_PRINT(", subcode %s (%u)",
2963  bgpn_minor),
2964  bgpn_minor);
2965 
2966  /* draft-ietf-idr-cease-subcode-02 mentions optionally 7 bytes
2967  * for the maxprefix subtype, which may contain AFI, SAFI and MAXPREFIXES
2968  */
2970  tptr = dat + BGP_NOTIFICATION_SIZE;
2971  ND_PRINT(", AFI %s (%u), SAFI %s (%u), Max Prefixes: %u",
2972  tok2str(af_values, "Unknown", GET_BE_U_2(tptr)),
2973  GET_BE_U_2(tptr),
2974  tok2str(bgp_safi_values, "Unknown", GET_U_1((tptr + 2))),
2975  GET_U_1((tptr + 2)),
2976  GET_BE_U_4(tptr + 3));
2977  }
2978  /*
2979  * draft-ietf-idr-shutdown describes a method to send a communication
2980  * intended for human consumption regarding the Administrative Shutdown
2981  */
2984  length >= BGP_NOTIFICATION_SIZE + 1) {
2985  tptr = dat + BGP_NOTIFICATION_SIZE;
2986  shutdown_comm_length = GET_U_1(tptr);
2987  remainder_offset = 0;
2988  /* garbage, hexdump it all */
2989  if (shutdown_comm_length > BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN ||
2990  shutdown_comm_length > length - (BGP_NOTIFICATION_SIZE + 1)) {
2991  ND_PRINT(", invalid Shutdown Communication length");
2992  }
2993  else if (shutdown_comm_length == 0) {
2994  ND_PRINT(", empty Shutdown Communication");
2995  remainder_offset += 1;
2996  }
2997  /* a proper shutdown communication */
2998  else {
2999  ND_TCHECK_LEN(tptr + 1, shutdown_comm_length);
3000  ND_PRINT(", Shutdown Communication (length: %u): \"", shutdown_comm_length);
3001  (void)nd_printn(ndo, tptr+1, shutdown_comm_length, NULL);
3002  ND_PRINT("\"");
3003  remainder_offset += shutdown_comm_length + 1;
3004  }
3005  /* if there is trailing data, hexdump it */
3006  if(length - (remainder_offset + BGP_NOTIFICATION_SIZE) > 0) {
3007  ND_PRINT(", Data: (length: %u)", length - (remainder_offset + BGP_NOTIFICATION_SIZE));
3008  hex_print(ndo, "\n\t\t", tptr + remainder_offset, length - (remainder_offset + BGP_NOTIFICATION_SIZE));
3009  }
3010  }
3011  break;
3012  default:
3013  break;
3014  }
3015 
3016  return;
3017 trunc:
3018  nd_print_trunc(ndo);
3019 }
3020 
3021 static void
3023  const u_char *pptr, u_int len)
3024 {
3025  const struct bgp_route_refresh *bgp_route_refresh_header;
3026 
3028 
3029  /* some little sanity checking */
3031  return;
3032 
3033  bgp_route_refresh_header = (const struct bgp_route_refresh *)pptr;
3034 
3035  ND_PRINT("\n\t AFI %s (%u), SAFI %s (%u)",
3036  tok2str(af_values,"Unknown",
3037  GET_BE_U_2(bgp_route_refresh_header->afi)),
3038  GET_BE_U_2(bgp_route_refresh_header->afi),
3039  tok2str(bgp_safi_values,"Unknown",
3040  GET_U_1(bgp_route_refresh_header->safi)),
3041  GET_U_1(bgp_route_refresh_header->safi));
3042 
3043  if (ndo->ndo_vflag > 1) {
3044  ND_TCHECK_LEN(pptr, len);
3045  print_unknown_data(ndo, pptr, "\n\t ", len);
3046  }
3047 
3048  return;
3049 trunc:
3050  nd_print_trunc(ndo);
3051 }
3052 
3053 static int
3055  const u_char *dat, u_int length)
3056 {
3057  const struct bgp *bgp_header;
3058  uint8_t bgp_type;
3059 
3060  ND_TCHECK_LEN(dat, BGP_SIZE);
3061  bgp_header = (const struct bgp *)dat;
3062  bgp_type = GET_U_1(bgp_header->bgp_type);
3063 
3064  ND_PRINT("\n\t%s Message (%u), length: %u",
3065  tok2str(bgp_msg_values, "Unknown", bgp_type),
3066  bgp_type,
3067  length);
3068 
3069  switch (bgp_type) {
3070  case BGP_OPEN:
3071  bgp_open_print(ndo, dat, length);
3072  break;
3073  case BGP_UPDATE:
3074  bgp_update_print(ndo, dat, length);
3075  break;
3076  case BGP_NOTIFICATION:
3077  bgp_notification_print(ndo, dat, length);
3078  break;
3079  case BGP_KEEPALIVE:
3080  break;
3081  case BGP_ROUTE_REFRESH:
3082  bgp_route_refresh_print(ndo, dat, length);
3083  break;
3084  default:
3085  /* we have no decoder for the BGP message */
3086  ND_TCHECK_LEN(dat, length);
3087  ND_PRINT("\n\t no Message %u decoder", bgp_type);
3088  print_unknown_data(ndo, dat, "\n\t ", length);
3089  break;
3090  }
3091  return 1;
3092 trunc:
3093  nd_print_trunc(ndo);
3094  return 0;
3095 }
3096 
3097 void
3099  const u_char *dat, u_int length _U_)
3100 {
3101  const u_char *p;
3102  const u_char *ep = ndo->ndo_snapend;
3103  const u_char *start;
3104  const u_char marker[] = {
3105  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3106  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3107  };
3108  const struct bgp *bgp_header;
3109  uint16_t hlen;
3110 
3111  ndo->ndo_protocol = "bgp";
3112  ND_PRINT(": BGP");
3113 
3114  if (ndo->ndo_vflag < 1) /* lets be less chatty */
3115  return;
3116 
3117  p = dat;
3118  start = p;
3119  while (p < ep) {
3120  if (!ND_TTEST_1(p))
3121  break;
3122  if (GET_U_1(p) != 0xff) {
3123  p++;
3124  continue;
3125  }
3126 
3127  if (!ND_TTEST_LEN(p, sizeof(marker)))
3128  break;
3129  if (memcmp(p, marker, sizeof(marker)) != 0) {
3130  p++;
3131  continue;
3132  }
3133 
3134  /* found BGP header */
3135  ND_TCHECK_LEN(p, BGP_SIZE);
3136  bgp_header = (const struct bgp *)p;
3137 
3138  if (start != p)
3139  nd_print_trunc(ndo);
3140 
3141  hlen = GET_BE_U_2(bgp_header->bgp_len);
3142  if (hlen < BGP_SIZE) {
3143  ND_PRINT("\nmessage length %u < %u", hlen, BGP_SIZE);
3144  nd_print_invalid(ndo);
3145  break;
3146  }
3147 
3148  if (ND_TTEST_LEN(p, hlen)) {
3149  if (!bgp_pdu_print(ndo, p, hlen))
3150  return;
3151  p += hlen;
3152  start = p;
3153  } else {
3154  ND_PRINT("\n[|BGP %s]",
3156  "Unknown Message Type",
3157  GET_U_1(bgp_header->bgp_type)));
3158  break;
3159  }
3160  }
3161 
3162  return;
3163 
3164 trunc:
3165  nd_print_trunc(ndo);
3166 }
const char * ipaddr_string(netdissect_options *ndo, const u_char *ap)
Definition: addrtoname.c:279
const char * isonsap_string(netdissect_options *ndo, const uint8_t *nsap, u_int nsap_length)
Definition: addrtoname.c:708
const char * ip6addr_string(netdissect_options *ndo, const u_char *ap)
Definition: addrtoname.c:338
#define GET_IPADDR_STRING(p)
Definition: addrtoname.h:120
#define GET_IP6ADDR_STRING(p)
Definition: addrtoname.h:121
#define GET_ISONSAP_STRING(nsap, nsap_length)
Definition: addrtoname.h:119
const struct tok af_values[]
Definition: af.c:26
#define AFNUM_NSAP
Definition: af.h:24
#define AFNUM_VPLS
Definition: af.h:37
#define AFNUM_L2VPN
Definition: af.h:39
#define AFNUM_INET6
Definition: af.h:23
#define AFNUM_INET
Definition: af.h:22
#define EXTRACT_BE_U_2(p)
Definition: extract.h:273
#define ND_TCHECK_3(p)
Definition: extract.h:558
#define GET_BE_U_4(p)
Definition: extract.h:877
#define GET_BE_U_8(p)
Definition: extract.h:881
#define EXTRACT_BE_U_4(p)
Definition: extract.h:279
#define GET_BE_U_3(p)
Definition: extract.h:876
#define GET_BE_U_2(p)
Definition: extract.h:875
#define ND_TCHECK_2(p)
Definition: extract.h:555
#define ND_TCHECK_8(p)
Definition: extract.h:573
#define ND_TCHECK_5(p)
Definition: extract.h:564
#define GET_U_1(p)
Definition: extract.h:872
#define ND_TCHECK_4(p)
Definition: extract.h:561
#define ND_TTEST_1(p)
Definition: extract.h:551
#define GET_CPY_BYTES(dst, p, len)
Definition: extract.h:913
#define ND_TCHECK_1(p)
Definition: extract.h:552
const struct tok l2vpn_encaps_values[]
Definition: l2vpn.c:31
unsigned char nd_uint16_t[2]
Definition: netdissect.h:47
#define ND_BYTES_BETWEEN(p1, p2)
Definition: netdissect.h:377
int print_unknown_data(netdissect_options *, const u_char *, const char *, u_int)
Definition: util-print.c:441
#define ND_TCHECK_LEN(p, l)
Definition: netdissect.h:368
const char * tok2str(const struct tok *, const char *, u_int)
Definition: util-print.c:485
#define ND_TTEST_LEN(p, l)
Definition: netdissect.h:356
char * bittok2str(const struct tok *, const char *, u_int)
Definition: util-print.c:558
void nd_print_invalid(netdissect_options *)
Definition: util-print.c:429
unsigned char nd_byte
Definition: netdissect.h:108
void hex_print(netdissect_options *, const char *ident, const u_char *cp, u_int)
Definition: print-ascii.c:212
void nd_print_trunc(netdissect_options *)
Definition: util-print.c:409
unsigned char nd_ipv4[4]
Definition: netdissect.h:92
#define ND_PRINT(...)
Definition: netdissect.h:385
int nd_printn(netdissect_options *, const u_char *, u_int, const u_char *)
Definition: util-print.c:160
unsigned char nd_uint32_t[4]
Definition: netdissect.h:49
unsigned char nd_uint8_t[1]
Definition: netdissect.h:46
unsigned char nd_ipv6[16]
Definition: netdissect.h:97
int snprintf(char *, size_t, const char *,...)
static char * bgp_rt_prefix_print(netdissect_options *ndo, const u_char *pptr, u_int plen)
Definition: print-bgp.c:913
#define BGP_EXT_COM_VPN_ORIGIN4
Definition: print-bgp.c:432
void bgp_print(netdissect_options *ndo, const u_char *dat, u_int length)
Definition: print-bgp.c:3098
#define BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI
Definition: print-bgp.c:1126
#define BGP_AS_SEQUENCE
Definition: print-bgp.c:182
#define BGP_ENCAP_TUNNEL_IPSEC
Definition: print-bgp.c:497
static const struct tok bgp_as_path_segment_open_values[]
Definition: print-bgp.c:189
#define BGP_CAPCODE_ORF
Definition: print-bgp.c:216
#define SAFNUM_VPNUNIMULTICAST
Definition: print-bgp.c:391
#define BGP_CONFED_AS_SET
Definition: print-bgp.c:184
#define BGP_CAPCODE_MR
Definition: print-bgp.c:217
#define bgp_attr_len(flags, p)
Definition: print-bgp.c:116
#define BGP_ENCAP_TUNNEL_VXLAN
Definition: print-bgp.c:501
#define BGP_CAPCODE_RESTART
Definition: print-bgp.c:220
static const struct tok bgp_origin_values[]
Definition: print-bgp.c:332
#define BGPTYPE_LARGE_COMMUNITY
Definition: print-bgp.c:144
#define BGP_OSPF_RTYPE_EXT
Definition: print-bgp.c:537
static const struct tok bgp_notify_minor_msg_values[]
Definition: print-bgp.c:283
static void bgp_capabilities_print(netdissect_options *ndo, const u_char *opt, u_int caps_len)
Definition: print-bgp.c:2518
static int decode_labeled_vpn_prefix4(netdissect_options *ndo, const u_char *pptr, char *buf, size_t buflen)
Definition: print-bgp.c:1048
static const struct tok bgp_notify_minor_open_values[]
Definition: print-bgp.c:290
#define BGP_PMSI_TUNNEL_LDP_MP2MP
Definition: print-bgp.c:345
#define BGPTYPE_ENTROPY_LABEL
Definition: print-bgp.c:143
#define BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN
Definition: print-bgp.c:1130
#define BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW
Definition: print-bgp.c:451
#define BGP_EXT_COM_L2VPN_RT_0
Definition: print-bgp.c:445
#define SAFNUM_RES
Definition: print-bgp.c:371
#define BGP_EXT_COM_SOURCE_AS
Definition: print-bgp.c:443
#define BGP_AS_SEG_TYPE_MIN
Definition: print-bgp.c:186
#define BGPTYPE_AIGP
Definition: print-bgp.c:141
#define SAFNUM_MULTICAST_VPN
Definition: print-bgp.c:378
static int decode_clnp_prefix(netdissect_options *ndo, const u_char *pptr, char *buf, size_t buflen)
Definition: print-bgp.c:1472
#define BGP_ENCAP_TUNNEL_GRE
Definition: print-bgp.c:495
#define BGPTYPE_AS4_PATH
Definition: print-bgp.c:135
const char * bgp_vpn_rd_print(netdissect_options *ndo, const u_char *pptr)
Definition: print-bgp.c:757
static const struct tok bgp_opt_values[]
Definition: print-bgp.c:208
#define BGP_NOTIFICATION_SIZE
Definition: print-bgp.c:102
static char * bgp_vpn_ip_print(netdissect_options *ndo, const u_char *pptr, u_int addr_length)
Definition: print-bgp.c:671
#define BGP_PMSI_TUNNEL_LDP_P2MP
Definition: print-bgp.c:340
#define BGP_EXT_COM_OSPF_RTYPE2
Definition: print-bgp.c:435
#define BGP_CAPCODE_LLGR
Definition: print-bgp.c:226
#define BGP_AS_SET
Definition: print-bgp.c:181
#define BGP_EXT_COM_VPN_ORIGIN2
Definition: print-bgp.c:430
#define BGP_CONFED_AS_SEQUENCE
Definition: print-bgp.c:183
#define BGP_ENCAP_TUNNEL_MPLS_GRE
Definition: print-bgp.c:504
#define BGP_NOTIFY_MAJOR_MSG
Definition: print-bgp.c:247
#define BGP_ENCAP_TUNNEL_IPV6
Definition: print-bgp.c:507
#define BGP_ENCAP_TUNNEL_SR_TE
Definition: print-bgp.c:508
#define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI
Definition: print-bgp.c:1124
#define BGP_COMMUNITY_NO_EXPORT_SUBCONFED
Definition: print-bgp.c:418
#define BGP_NOTIFY_MINOR_CEASE_MAXPRFX
Definition: print-bgp.c:267
#define BGP_CAPCODE_DYN_CAP
Definition: print-bgp.c:222
static const struct tok bgp_pmsi_flag_values[]
Definition: print-bgp.c:358
static const struct tok bgp_msg_values[]
Definition: print-bgp.c:65
#define BGPTYPE_DPA
Definition: print-bgp.c:129
#define BGP_CAPCODE_RR
Definition: print-bgp.c:215
#define BGP_AIGP_TLV
Definition: print-bgp.c:363
#define BGPTYPE_ORIGIN
Definition: print-bgp.c:119
static const struct tok bgp_attr_values[]
Definition: print-bgp.c:149
#define SAFNUM_VPNUNICAST
Definition: print-bgp.c:388
#define BGP_EXT_COM_VPN_ORIGIN
Definition: print-bgp.c:429
#define BGP_CAP_HEADER_SIZE
Definition: print-bgp.c:93
#define AS_STR_SIZE
Definition: print-bgp.c:560
#define BGP_EXT_COM_RT_1
Definition: print-bgp.c:422
#define BGP_PMSI_TUNNEL_PIM_BIDIR
Definition: print-bgp.c:343
#define BGP_NOTIFY_MAJOR_CEASE
Definition: print-bgp.c:252
#define BGP_CAPCODE_ENH_RR
Definition: print-bgp.c:225
#define BGP_ENCAP_TUNNEL_IP_IP
Definition: print-bgp.c:500
#define BGP_MP_NLRI_MINSIZE
Definition: print-bgp.c:147
static const struct tok bgp_notify_minor_fsm_values[]
Definition: print-bgp.c:316
int decode_prefix4(netdissect_options *ndo, const u_char *pptr, u_int itemlen, char *buf, size_t buflen)
Definition: print-bgp.c:586
static u_int bgp_vpn_sg_print(netdissect_options *ndo, const u_char *pptr, char *buf, size_t buflen)
Definition: print-bgp.c:715
#define BGPTYPE_TUNNEL_ENCAP
Definition: print-bgp.c:138
#define SAFNUM_MULTICAST
Definition: print-bgp.c:373
#define SAFNUM_MDT
Definition: print-bgp.c:384
#define BGPTYPE_ATOMIC_AGGREGATE
Definition: print-bgp.c:124
#define BGPTYPE_LOCAL_PREF
Definition: print-bgp.c:123
static const struct tok bgp_multicast_vpn_route_type_values[]
Definition: print-bgp.c:1132
#define BGPTYPE_MP_REACH_NLRI
Definition: print-bgp.c:132
#define BGP_NOTIFY_MAJOR_CAP
Definition: print-bgp.c:253
static void bgp_update_print(netdissect_options *ndo, const u_char *dat, u_int length)
Definition: print-bgp.c:2721
static u_int bgp_attr_get_as_size(netdissect_options *ndo, uint8_t bgpa_type, const u_char *pptr, u_int len)
Definition: print-bgp.c:1539
#define BGP_EXT_COM_EIGRP_METRIC_AS_DELAY
Definition: print-bgp.c:450
#define MDT_VPN_NLRI_LEN
Definition: print-bgp.c:1091
#define ITEMCHECK(minlen)
Definition: print-bgp.c:583
#define BGP_NOTIFY_MINOR_CEASE_SHUT
Definition: print-bgp.c:269
static const struct tok bgp_safi_values[]
Definition: print-bgp.c:397
#define BGP_PMSI_TUNNEL_PIM_SSM
Definition: print-bgp.c:341
#define BGP_EXT_COM_RO_0
Definition: print-bgp.c:424
#define BGP_CAPCODE_RR_CISCO
Definition: print-bgp.c:227
#define SAFNUM_UNIMULTICAST
Definition: print-bgp.c:374
static void bgp_open_print(netdissect_options *ndo, const u_char *dat, u_int length)
Definition: print-bgp.c:2648
#define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF
Definition: print-bgp.c:1127
static const struct tok bgp_pmsi_tunnel_values[]
Definition: print-bgp.c:347
static const struct tok bgp_extd_comm_encap_tunnel_values[]
Definition: print-bgp.c:512
#define BGP_SIZE
Definition: print-bgp.c:57
#define BGP_OPT_AUTH
Definition: print-bgp.c:205
#define BGP_EXT_COM_EIGRP_EXT_REMAS_REMID
Definition: print-bgp.c:453
#define BGP_ENCAP_TUNNEL_SR
Definition: print-bgp.c:510
#define BGP_PMSI_TUNNEL_PIM_SM
Definition: print-bgp.c:342
#define BGP_COMMUNITY_NO_ADVERT
Definition: print-bgp.c:417
#define BGP_EXT_COM_RT_2
Definition: print-bgp.c:423
static void bgp_notification_print(netdissect_options *ndo, const u_char *dat, u_int length)
Definition: print-bgp.c:2906
#define BGPTYPE_CLUSTER_LIST
Definition: print-bgp.c:128
static int decode_multicast_vpn(netdissect_options *ndo, const u_char *pptr, char *buf, size_t buflen)
Definition: print-bgp.c:1144
#define BGPTYPE_ORIGINATOR_ID
Definition: print-bgp.c:127
#define UPDATE_BUF_BUFLEN(buf, buflen, stringlen)
Definition: print-bgp.c:1244
#define BGP_EXT_COM_RO_2
Definition: print-bgp.c:426
#define BGPTYPE_IPV6_EXTD_COMMUNITIES
Definition: print-bgp.c:140
#define BGP_EXT_COM_VPN_ORIGIN3
Definition: print-bgp.c:431
#define BGPTYPE_RCID_PATH
Definition: print-bgp.c:131
static int decode_labeled_prefix4(netdissect_options *ndo, const u_char *pptr, u_int itemlen, char *buf, size_t buflen)
Definition: print-bgp.c:613
#define BGP_EXT_COM_ENCAP
Definition: print-bgp.c:436
#define SAFNUM_VPLS
Definition: print-bgp.c:382
static const struct tok bgp_notify_minor_cap_values[]
Definition: print-bgp.c:324
#define BGP_ENCAP_TUNNEL_MPLS
Definition: print-bgp.c:503
#define BGP_OPT_CAP
Definition: print-bgp.c:206
static int bgp_nlri_print(netdissect_options *ndo, uint16_t af, uint8_t safi, const u_char *tptr, u_int len, char *buf, size_t buflen, int add_path4, int add_path6)
Definition: print-bgp.c:1715
static const struct tok bgp_aigp_values[]
Definition: print-bgp.c:365
#define bgp_attr_lenlen(flags, p)
Definition: print-bgp.c:114
#define BGP_EXT_COM_OSPF_RTYPE
Definition: print-bgp.c:434
#define BGP_PMSI_TUNNEL_RSVP_P2MP
Definition: print-bgp.c:339
#define BGP_NOTIFY_MAJOR_FSM
Definition: print-bgp.c:251
#define BGPTYPE_AS_PATH
Definition: print-bgp.c:120
static int decode_rt_routing_info(netdissect_options *ndo, const u_char *pptr)
Definition: print-bgp.c:991
#define BGPTYPE_EXTD_COMMUNITIES
Definition: print-bgp.c:134
#define SAFNUM_TUNNEL
Definition: print-bgp.c:380
static int bgp_mp_af_print(netdissect_options *ndo, const u_char *tptr, u_int tlen, uint16_t *afp, uint8_t *safip)
Definition: print-bgp.c:1654
#define BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN
Definition: print-bgp.c:271
#define BGP_OPT_SIZE
Definition: print-bgp.c:92
#define BGP_EXT_COM_RO_1
Definition: print-bgp.c:425
#define BGP_EXT_COM_L2VPN_RT_1
Definition: print-bgp.c:446
#define SAFNUM_RT_ROUTING_INFO
Definition: print-bgp.c:393
static const struct tok bgp_extd_comm_ospf_rtype_values[]
Definition: print-bgp.c:542
#define BGP_CAPCODE_AS_NEW
Definition: print-bgp.c:221
static const struct tok bgp_notify_minor_update_values[]
Definition: print-bgp.c:301
static const struct tok bgp_notify_minor_cease_values[]
Definition: print-bgp.c:272
#define BGP_ENCAP_TUNNEL_MPLS_IP
Definition: print-bgp.c:499
static void bgp_route_refresh_print(netdissect_options *ndo, const u_char *pptr, u_int len)
Definition: print-bgp.c:3022
#define BGP_NOTIFICATION
Definition: print-bgp.c:61
#define BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC
Definition: print-bgp.c:454
#define BGPTYPE_ADVERTISERS
Definition: print-bgp.c:130
static char * as_printf(netdissect_options *ndo, char *str, size_t size, u_int asnum)
Definition: print-bgp.c:572
#define BGP_EXT_COM_LINKBAND
Definition: print-bgp.c:427
static const struct tok bgp_extd_comm_subtype_values[]
Definition: print-bgp.c:462
#define BGP_OSPF_RTYPE_METRIC_TYPE
Definition: print-bgp.c:540
#define BGP_OSPF_RTYPE_NET
Definition: print-bgp.c:535
#define BGP_ENCAP_TUNNEL_TRANSMIT
Definition: print-bgp.c:496
#define BGPTYPE_PE_DISTINGUISHER_LABEL
Definition: print-bgp.c:142
#define BGP_ENCAP_TUNNEL_MPLS_UDP
Definition: print-bgp.c:506
#define BGP_EXT_COM_VRF_RT_IMP
Definition: print-bgp.c:444
static int decode_labeled_vpn_prefix6(netdissect_options *ndo, const u_char *pptr, char *buf, size_t buflen)
Definition: print-bgp.c:1438
static void bgp_extended_community_print(netdissect_options *ndo, const u_char *pptr)
Definition: print-bgp.c:807
#define SAFNUM_VPNMULTICAST
Definition: print-bgp.c:390
#define BGP_EXT_COM_EIGRP_GEN
Definition: print-bgp.c:449
#define BGP_NOTIFY_MAJOR_HOLDTIME
Definition: print-bgp.c:250
static int bgp_pdu_print(netdissect_options *ndo, const u_char *dat, u_int length)
Definition: print-bgp.c:3054
#define BGPTYPE_ATTR_SET
Definition: print-bgp.c:145
static const struct tok bgp_capcode_values[]
Definition: print-bgp.c:229
#define BGPTYPE_MULTI_EXIT_DISC
Definition: print-bgp.c:122
static int decode_mdt_vpn_nlri(netdissect_options *ndo, const u_char *pptr, char *buf, size_t buflen)
Definition: print-bgp.c:1094
#define BGP_ENCAP_TUNNEL_VXLAN_GPE
Definition: print-bgp.c:505
#define BGP_NOTIFY_MAJOR_UPDATE
Definition: print-bgp.c:249
static const struct tok bgp_as_path_segment_close_values[]
Definition: print-bgp.c:197
#define BGP_EXT_COM_RT_0
Definition: print-bgp.c:421
#define BGP_OSPF_RTYPE_NSSA
Definition: print-bgp.c:538
#define BGP_PMSI_TUNNEL_INGRESS
Definition: print-bgp.c:344
#define BGP_OSPF_RTYPE_SUM
Definition: print-bgp.c:536
#define BGP_CAPCODE_MP
Definition: print-bgp.c:214
#define SAFNUM_UNICAST
Definition: print-bgp.c:372
#define BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN
Definition: print-bgp.c:1129
#define BGPTYPE_NEXT_HOP
Definition: print-bgp.c:121
#define BGP_AS_SEG_TYPE_MAX
Definition: print-bgp.c:187
#define BGPTYPE_AGGREGATOR
Definition: print-bgp.c:125
#define BGP_ROUTE_REFRESH
Definition: print-bgp.c:63
#define BGP_UPDATE
Definition: print-bgp.c:60
static int decode_labeled_vpn_l2(netdissect_options *ndo, const u_char *pptr, char *buf, size_t buflen)
Definition: print-bgp.c:1255
static const struct tok bgp_notify_major_values[]
Definition: print-bgp.c:255
#define BGP_CAPCODE_ADD_PATH
Definition: print-bgp.c:224
static int bgp_attr_print(netdissect_options *ndo, uint8_t atype, const u_char *pptr, u_int len, const unsigned attr_set_level)
Definition: print-bgp.c:1870
#define BGP_NOTIFY_MAJOR_OPEN
Definition: print-bgp.c:248
static const struct tok bgp_extd_comm_flag_values[]
Definition: print-bgp.c:456
static int decode_labeled_prefix6(netdissect_options *ndo, const u_char *pptr, u_int itemlen, char *buf, size_t buflen)
Definition: print-bgp.c:1394
#define BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU
Definition: print-bgp.c:452
static int decode_labeled_vpn_clnp_prefix(netdissect_options *ndo, const u_char *pptr, char *buf, size_t buflen)
Definition: print-bgp.c:1498
#define BGP_KEEPALIVE
Definition: print-bgp.c:62
#define BGP_EXT_COM_L2INFO
Definition: print-bgp.c:441
#define SAFNUM_LABUNICAST
Definition: print-bgp.c:376
#define BGP_ENCAP_TUNNEL_IP_IPSEC
Definition: print-bgp.c:498
int decode_prefix6(netdissect_options *ndo, const u_char *pd, u_int itemlen, char *buf, size_t buflen)
Definition: print-bgp.c:1366
#define BGPTYPE_COMMUNITIES
Definition: print-bgp.c:126
#define BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE
Definition: print-bgp.c:1128
#define BGP_VPN_RD_LEN
Definition: print-bgp.c:395
#define BGP_ENCAP_TUNNEL_BARE
Definition: print-bgp.c:509
#define BGPTYPE_PMSI_TUNNEL
Definition: print-bgp.c:137
#define BGP_ENCAP_TUNNEL_NVGRE
Definition: print-bgp.c:502
#define BGPTYPE_MP_UNREACH_NLRI
Definition: print-bgp.c:133
#define BGP_CAPCODE_EXT_NH
Definition: print-bgp.c:218
#define BGP_ENCAP_TUNNEL_L2TPV3_IP
Definition: print-bgp.c:494
#define BGP_NOTIFY_MINOR_CEASE_RESET
Definition: print-bgp.c:270
#define BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI
Definition: print-bgp.c:1125
#define SAFNUM_EVPN
Definition: print-bgp.c:386
#define BGP_OPEN
Definition: print-bgp.c:59
#define BGP_COMMUNITY_NO_EXPORT
Definition: print-bgp.c:416
#define BGP_CAPCODE_MULTISESS
Definition: print-bgp.c:223
static const struct tok bgp_add_path_recvsend[]
Definition: print-bgp.c:553
#define BGP_OSPF_RTYPE_RTR
Definition: print-bgp.c:534
static int check_add_path(netdissect_options *ndo, const u_char *pptr, u_int length, u_int max_prefix_length)
Definition: print-bgp.c:1593
#define BGPTYPE_TRAFFIC_ENG
Definition: print-bgp.c:139
#define BGP_OPEN_SIZE
Definition: print-bgp.c:85
#define BGP_CAPCODE_ML
Definition: print-bgp.c:219
#define BGP_EXT_COM_OSPF_RID2
Definition: print-bgp.c:439
#define BGP_ROUTE_REFRESH_SIZE
Definition: print-bgp.c:112
#define BGP_OSPF_RTYPE_SHAM
Definition: print-bgp.c:539
#define BGPTYPE_AGGREGATOR4
Definition: print-bgp.c:136
#define BGP_EXT_COM_OSPF_RID
Definition: print-bgp.c:438
static const char * tunnel_type[]
Definition: print-radius.c:428
static uint32_t stringlen
Definition: smbutil.c:26
nd_byte bgpn_marker[16]
Definition: print-bgp.c:96
nd_uint8_t bgpn_type
Definition: print-bgp.c:98
nd_uint8_t bgpn_major
Definition: print-bgp.c:99
nd_uint16_t bgpn_len
Definition: print-bgp.c:97
nd_uint8_t bgpn_minor
Definition: print-bgp.c:100
nd_uint8_t bgpo_type
Definition: print-bgp.c:77
nd_uint16_t bgpo_myas
Definition: print-bgp.c:79
nd_uint8_t bgpo_version
Definition: print-bgp.c:78
nd_uint32_t bgpo_id
Definition: print-bgp.c:81
nd_uint16_t bgpo_holdtime
Definition: print-bgp.c:80
nd_uint16_t bgpo_len
Definition: print-bgp.c:76
nd_byte bgpo_marker[16]
Definition: print-bgp.c:75
nd_uint8_t bgpo_optlen
Definition: print-bgp.c:82
nd_uint8_t bgpopt_len
Definition: print-bgp.c:89
nd_uint8_t bgpopt_type
Definition: print-bgp.c:88
nd_uint8_t safi
Definition: print-bgp.c:110
nd_byte bgp_marker[16]
Definition: print-bgp.c:105
nd_uint16_t len
Definition: print-bgp.c:106
nd_uint8_t type
Definition: print-bgp.c:107
nd_uint16_t afi
Definition: print-bgp.c:108
nd_uint8_t res
Definition: print-bgp.c:109
Definition: print-bgp.c:52
nd_byte bgp_marker[16]
Definition: print-bgp.c:53
nd_uint16_t bgp_len
Definition: print-bgp.c:54
nd_uint8_t bgp_type
Definition: print-bgp.c:55
const u_char * ndo_snapend
Definition: netdissect.h:239
const char * ndo_protocol
Definition: netdissect.h:218
static pcap_t * pd
Definition: tcpdump.c:304
#define _U_
Definition: varattrs.h:56