xref: /openbsd-src/usr.sbin/tcpdump/print-bgp.c (revision 1ad61ae0a79a724d2d3ec69e69c8e1d1ff6b53a0)
1 /*	$OpenBSD: print-bgp.c,v 1.32 2022/05/25 16:21:11 claudio Exp $	*/
2 
3 /*
4  * Copyright (C) 1999 WIDE Project.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the project nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 #include <sys/time.h>
33 #include <sys/types.h>
34 #include <sys/socket.h>
35 
36 #include <netinet/in.h>
37 
38 #include <errno.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <netdb.h>
42 #include <limits.h>
43 
44 #include "interface.h"
45 #include "addrtoname.h"
46 #include "extract.h"
47 #include "afnum.h"
48 
49 struct bgp {
50 	u_int8_t bgp_marker[16];
51 	u_int16_t bgp_len;
52 	u_int8_t bgp_type;
53 };
54 #define BGP_SIZE		19	/* unaligned */
55 
56 #define BGP_OPEN		1
57 #define BGP_UPDATE		2
58 #define BGP_NOTIFICATION	3
59 #define BGP_KEEPALIVE		4
60 #define BGP_ROUTE_REFRESH	5
61 
62 struct bgp_open {
63 	u_int8_t bgpo_marker[16];
64 	u_int16_t bgpo_len;
65 	u_int8_t bgpo_type;
66 	u_int8_t bgpo_version;
67 	u_int16_t bgpo_myas;
68 	u_int16_t bgpo_holdtime;
69 	u_int32_t bgpo_id;
70 	u_int8_t bgpo_optlen;
71 	/* options should follow */
72 };
73 #define BGP_OPEN_SIZE		29	/* unaligned */
74 
75 struct bgp_opt {
76 	u_int8_t bgpopt_type;
77 	u_int8_t bgpopt_len;
78 	/* variable length */
79 };
80 #define BGP_OPT_CAP		2
81 #define BGP_OPT_SIZE		2	/* some compilers may pad to 4 bytes */
82 
83 #define BGP_UPDATE_MINSIZE	23
84 
85 struct bgp_notification {
86 	u_int8_t bgpn_marker[16];
87 	u_int16_t bgpn_len;
88 	u_int8_t bgpn_type;
89 	u_int8_t bgpn_major;
90 	u_int8_t bgpn_minor;
91 	/* data should follow */
92 };
93 #define BGP_NOTIFICATION_SIZE		21	/* unaligned */
94 
95 struct bgp_route_refresh {
96 	u_int8_t bgp_marker[16];
97 	u_int16_t len;
98 	u_int8_t type;
99 	u_int8_t afi[2]; /* unaligned; should be u_int16_t */
100 	u_int8_t subtype;
101 	u_int8_t safi;
102 };
103 #define BGP_ROUTE_REFRESH_SIZE          23
104 
105 struct bgp_attr {
106 	u_int8_t bgpa_flags;
107 	u_int8_t bgpa_type;
108 	union {
109 		u_int8_t len;
110 		u_int16_t elen;
111 	} bgpa_len;
112 #define bgp_attr_len(p) \
113 	(((p)->bgpa_flags & 0x10) ? \
114 		ntohs((p)->bgpa_len.elen) : (p)->bgpa_len.len)
115 #define bgp_attr_off(p) \
116 	(((p)->bgpa_flags & 0x10) ? 4 : 3)
117 };
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	/* RFC1998 */
128 #define	BGPTYPE_CLUSTER_LIST		10	/* RFC1998 */
129 #define	BGPTYPE_DPA			11	/* draft-ietf-idr-bgp-dpa */
130 #define	BGPTYPE_ADVERTISERS		12	/* RFC1863 */
131 #define	BGPTYPE_RCID_PATH		13	/* RFC1863 */
132 #define BGPTYPE_MP_REACH_NLRI		14	/* RFC2283 */
133 #define BGPTYPE_MP_UNREACH_NLRI		15	/* RFC2283 */
134 #define BGPTYPE_EXTD_COMMUNITIES	16	/* RFC4360 */
135 #define BGPTYPE_AS4_PATH		17	/* RFC4893 */
136 #define BGPTYPE_AGGREGATOR4		18	/* RFC4893 */
137 #define BGPTYPE_LARGE_COMMUNITIES	32	/* RFC8092 */
138 #define BGPTYPE_ONLY_TO_CUSTOMER	35	/* RFC9234 */
139 
140 #define BGP_AS_SET             1
141 #define BGP_AS_SEQUENCE        2
142 #define BGP_CONFED_AS_SEQUENCE 3 /* draft-ietf-idr-rfc3065bis-01 */
143 #define BGP_CONFED_AS_SET      4 /* draft-ietf-idr-rfc3065bis-01  */
144 
145 static struct tok bgp_as_path_segment_open_values[] = {
146 	{ BGP_AS_SET,			" {" },
147 	{ BGP_AS_SEQUENCE,		" " },
148 	{ BGP_CONFED_AS_SEQUENCE,	" (" },
149 	{ BGP_CONFED_AS_SET,		" ({" },
150 	{ 0, NULL},
151 };
152 
153 static struct tok bgp_as_path_segment_close_values[] = {
154 	{ BGP_AS_SET,			"}" },
155 	{ BGP_AS_SEQUENCE,		"" },
156 	{ BGP_CONFED_AS_SEQUENCE,	")" },
157 	{ BGP_CONFED_AS_SET,		"})" },
158 	{ 0, NULL},
159 };
160 
161 #define BGP_MP_NLRI_MINSIZE		3
162 
163 static const char *bgptype[] = {
164 	NULL, "OPEN", "UPDATE", "NOTIFICATION", "KEEPALIVE", "ROUTE-REFRESH",
165 };
166 #define bgp_type(x) num_or_str(bgptype, sizeof(bgptype)/sizeof(bgptype[0]), (x))
167 
168 static const char *bgpopt_type[] = {
169 	NULL, "Authentication Information", "Capabilities Advertisement",
170 };
171 #define bgp_opttype(x) \
172 	num_or_str(bgpopt_type, sizeof(bgpopt_type)/sizeof(bgpopt_type[0]), (x))
173 
174 #define BGP_CAPCODE_MP			1
175 #define BGP_CAPCODE_REFRESH		2
176 #define BGP_CAPCODE_BGPROLE		9 /* RFC9234 */
177 #define BGP_CAPCODE_RESTART		64 /* RFC4724 */
178 #define BGP_CAPCODE_AS4			65 /* RFC4893 */
179 
180 static const char *bgp_capcode[] = {
181 	NULL, "MULTI_PROTOCOL", "ROUTE_REFRESH",
182 	/* 3: RFC5291 */ "OUTBOUND_ROUTE_FILTERING",
183 	/* 4: RFC3107 */ "MULTIPLE_ROUTES",
184 	/* 5: RFC5549 */ "EXTENDED_NEXTHOP_ENCODING",
185 	0, 0, 0,
186 	/* 9: RFC9234 */ "BGP_ROLE",
187 	0, 0, 0, 0, 0, 0,
188 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
189 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
190 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
191 	/* 64: RFC4724 */ "GRACEFUL_RESTART",
192 	/* 65: RFC4893 */ "AS4", 0,
193 	/* 67: [Chen] */ "DYNAMIC_CAPABILITY",
194 	/* 68: [Appanna] */ "MULTISESSION",
195 	/* 69: RFC7911 */ "ADD-PATH",
196 	/* 70: RFC7313 */ "ENHANCED_ROUTE_REFRESH"
197 };
198 #define bgp_capcode(x) \
199 	num_or_str(bgp_capcode, sizeof(bgp_capcode)/sizeof(bgp_capcode[0]), (x))
200 
201 static const char *bgp_roletype[] = {
202 	"Provider", "Route Server", "RS Client", "Customer", "Lateral Peer"
203 };
204 #define bgp_roletype(x) \
205 	num_or_str(bgp_roletype, \
206 		sizeof(bgp_roletype)/sizeof(bgp_roletype[0]), (x))
207 
208 #define BGP_NOTIFY_MAJOR_CEASE		6
209 static const char *bgpnotify_major[] = {
210 	NULL, "Message Header Error",
211 	"OPEN Message Error", "UPDATE Message Error",
212 	"Hold Timer Expired", "Finite State Machine Error",
213 	"Cease", "ROUTE_REFRESH Message Error",
214 };
215 #define bgp_notify_major(x) \
216 	num_or_str(bgpnotify_major, \
217 		sizeof(bgpnotify_major)/sizeof(bgpnotify_major[0]), (x))
218 
219 static const char *bgpnotify_minor_msg[] = {
220 	NULL, "Connection Not Synchronized",
221 	"Bad Message Length", "Bad Message Type",
222 };
223 
224 static const char *bgpnotify_minor_open[] = {
225 	NULL, "Unsupported Version Number",
226 	"Bad Peer AS", "Bad BGP Identifier",
227 	"Unsupported Optional Parameter", "Authentication Failure",
228 	"Unacceptable Hold Time", "Unsupported Capability", NULL,
229 	NULL, NULL, "Role Mismatch"
230 };
231 
232 static const char *bgpnotify_minor_update[] = {
233 	NULL, "Malformed Attribute List",
234 	"Unrecognized Well-known Attribute", "Missing Well-known Attribute",
235 	"Attribute Flags Error", "Attribute Length Error",
236 	"Invalid ORIGIN Attribute", "AS Routing Loop",
237 	"Invalid NEXT_HOP Attribute", "Optional Attribute Error",
238 	"Invalid Network Field", "Malformed AS_PATH",
239 };
240 
241 static const char *bgpnotify_minor_holdtime[] = {
242 	NULL,
243 };
244 
245 /* RFC 6608 */
246 static const char *bgpnotify_minor_fsm[] = {
247 	"Unspecified Error", "In OpenSent State", "In OpenConfirm State",
248 	"In Established State",
249 };
250 
251 /* RFC 4486 */
252 #define BGP_NOTIFY_MINOR_CEASE_MAXPRFX  1
253 /* RFC 8203 */
254 #define BGP_NOTIFY_MINOR_CEASE_SHUT			2
255 #define BGP_NOTIFY_MINOR_CEASE_RESET			4
256 #define BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN	255
257 static const char *bgpnotify_minor_cease[] = {
258 	NULL, "Maximum Number of Prefixes Reached", "Administrative Shutdown",
259 	"Peer De-configured", "Administrative Reset", "Connection Rejected",
260 	"Other Configuration Change", "Connection Collision Resolution",
261 	"Out of Resources",
262 };
263 
264 /* RFC 7313 */
265 static const char *bgpnotify_minor_err[] = {
266 	NULL, "Invalid Message Length",
267 };
268 
269 static const char **bgpnotify_minor[] = {
270 	NULL, bgpnotify_minor_msg, bgpnotify_minor_open, bgpnotify_minor_update,
271 	bgpnotify_minor_holdtime, bgpnotify_minor_fsm, bgpnotify_minor_cease,
272 	bgpnotify_minor_err,
273 };
274 static const int bgpnotify_minor_siz[] = {
275 	0,
276 	sizeof(bgpnotify_minor_msg)/sizeof(bgpnotify_minor_msg[0]),
277 	sizeof(bgpnotify_minor_open)/sizeof(bgpnotify_minor_open[0]),
278 	sizeof(bgpnotify_minor_update)/sizeof(bgpnotify_minor_update[0]),
279 	sizeof(bgpnotify_minor_holdtime)/sizeof(bgpnotify_minor_holdtime[0]),
280 	sizeof(bgpnotify_minor_fsm)/sizeof(bgpnotify_minor_fsm[0]),
281 	sizeof(bgpnotify_minor_cease)/sizeof(bgpnotify_minor_cease[0]),
282 	sizeof(bgpnotify_minor_err)/sizeof(bgpnotify_minor_err[0]),
283 };
284 
285 static const char *bgpattr_origin[] = {
286 	"IGP", "EGP", "INCOMPLETE",
287 };
288 #define bgp_attr_origin(x) \
289 	num_or_str(bgpattr_origin, \
290 		sizeof(bgpattr_origin)/sizeof(bgpattr_origin[0]), (x))
291 
292 static const char *bgpattr_type[] = {
293 	NULL, "ORIGIN", "AS_PATH", "NEXT_HOP",
294 	"MULTI_EXIT_DISC", "LOCAL_PREF", "ATOMIC_AGGREGATE", "AGGREGATOR",
295 	"COMMUNITIES", "ORIGINATOR_ID", "CLUSTER_LIST", "DPA",
296 	"ADVERTISERS", "RCID_PATH", "MP_REACH_NLRI", "MP_UNREACH_NLRI",
297 	"EXTD_COMMUNITIES", "AS4_PATH", "AGGREGATOR4", NULL, NULL, NULL,
298 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
299 	"LARGE_COMMUNITIES", NULL, NULL, "ONLY_TO_CUSTOMER"
300 };
301 #define bgp_attr_type(x) \
302 	num_or_str(bgpattr_type, \
303 		sizeof(bgpattr_type)/sizeof(bgpattr_type[0]), (x))
304 
305 /* Subsequent address family identifier, RFC2283 section 7 */
306 static const char *bgpattr_nlri_safi[] = {
307 	"Reserved", "Unicast", "Multicast", "Unicast+Multicast",
308 	"labeled Unicast", /* MPLS BGP RFC3107 */
309 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
310 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
311 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
312 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
313 	/* 64-66: MPLS BGP RFC3107 */
314 	"Tunnel", "VPLS", "MDT",
315 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
316 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
317 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
318 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
319 	/* 128-129: RFC4364 + RFC6513 */
320 	"L3VPN Unicast", "L3VPN Multicast",
321 };
322 #define bgp_attr_nlri_safi(x) \
323 	num_or_str(bgpattr_nlri_safi, \
324 		sizeof(bgpattr_nlri_safi)/sizeof(bgpattr_nlri_safi[0]), (x))
325 
326 /* well-known community */
327 #define BGP_COMMUNITY_NO_EXPORT			0xffffff01
328 #define BGP_COMMUNITY_NO_ADVERT			0xffffff02
329 #define BGP_COMMUNITY_NO_EXPORT_SUBCONFED	0xffffff03
330 #define BGP_COMMUNITY_NO_PEER			0xffffff04
331 
332 static const char *afnumber[] = AFNUM_NAME_STR;
333 #define af_name(x) \
334 	(((x) == 65535) ? afnumber[0] : \
335 		num_or_str(afnumber, \
336 			sizeof(afnumber)/sizeof(afnumber[0]), (x)))
337 
338 static const char *refreshtype[] = {
339 	"Request", "BoRR", "EoRR"
340 };
341 #define refresh_subtype(x) \
342 	num_or_str(refreshtype, sizeof(refreshtype)/sizeof(refreshtype[0]), (x))
343 
344 static const char *
345 num_or_str(const char **table, size_t siz, int value)
346 {
347 	static char buf[20];
348 	if (value < 0 || siz <= value || table[value] == NULL) {
349 		snprintf(buf, sizeof(buf), "#%d", value);
350 		return buf;
351 	} else
352 		return table[value];
353 }
354 
355 static const char *
356 bgp_notify_minor(int major, int minor)
357 {
358 	static const char **table;
359 	int siz;
360 	static char buf[20];
361 	const char *p;
362 
363 	if (0 <= major
364 	 && major < sizeof(bgpnotify_minor)/sizeof(bgpnotify_minor[0])
365 	 && bgpnotify_minor[major]) {
366 		table = bgpnotify_minor[major];
367 		siz = bgpnotify_minor_siz[major];
368 		if (0 <= minor && minor < siz && table[minor])
369 			p = table[minor];
370 		else
371 			p = NULL;
372 	} else
373 		p = NULL;
374 	if (p == NULL) {
375 		snprintf(buf, sizeof(buf), "#%d", minor);
376 		return buf;
377 	} else
378 		return p;
379 }
380 
381 static int
382 decode_prefix4(const u_char *pd, char *buf, u_int buflen)
383 {
384 	struct in_addr addr;
385 	u_int plen;
386 	int n;
387 
388 	TCHECK(pd[0]);
389 	plen = pd[0]; /*
390 		       * prefix length is in bits; packet only contains
391 		       * enough bytes of address to contain this many bits
392 		       */
393 	plen = pd[0];
394 	if (32 < plen)
395 		return -1;
396 	memset(&addr, 0, sizeof(addr));
397 	TCHECK2(pd[1], (plen + 7) / 8);
398 	memcpy(&addr, &pd[1], (plen + 7) / 8);
399 	if (plen % 8) {
400 		((u_char *)&addr)[(plen + 7) / 8 - 1] &=
401 			((0xff00 >> (plen % 8)) & 0xff);
402 	}
403 	n = snprintf(buf, buflen, "%s/%u", getname((u_char *)&addr), plen);
404 	if (n < 0 || n >= buflen)
405 		return -1;
406 
407 	return 1 + (plen + 7) / 8;
408 
409 trunc:
410 	return -2;
411 }
412 
413 static int
414 decode_prefix6(const u_char *pd, char *buf, u_int buflen)
415 {
416 	struct in6_addr addr;
417 	u_int plen;
418 	int n;
419 
420 	TCHECK(pd[0]);
421 	plen = pd[0];
422 	if (128 < plen)
423 		return -1;
424 
425 	memset(&addr, 0, sizeof(addr));
426 	TCHECK2(pd[1], (plen + 7) / 8);
427 	memcpy(&addr, &pd[1], (plen + 7) / 8);
428 	if (plen % 8) {
429 		addr.s6_addr[(plen + 7) / 8 - 1] &=
430 			((0xff00 >> (plen % 8)) & 0xff);
431 	}
432 
433 	n = snprintf(buf, buflen, "%s/%u", getname6((u_char *)&addr), plen);
434 	if (n < 0 || n >= buflen)
435 		return -1;
436 
437 	return 1 + (plen + 7) / 8;
438 
439 trunc:
440 	return -2;
441 }
442 
443 static int
444 bgp_attr_print(const struct bgp_attr *attr, const u_char *dat, int len)
445 {
446 	int i;
447 	u_int16_t af;
448 	u_int8_t safi, snpa;
449 	int advance;
450 	int tlen, asn_bytes;
451 	const u_char *p;
452 	char buf[HOST_NAME_MAX+1 + 100];
453 
454 	p = dat;
455 	tlen = len;
456 	asn_bytes = 0;
457 
458 	switch (attr->bgpa_type) {
459 	case BGPTYPE_ORIGIN:
460 		if (len != 1)
461 			printf(" invalid len");
462 		else {
463 			TCHECK(p[0]);
464 			printf(" %s", bgp_attr_origin(p[0]));
465 		}
466 		break;
467 	case BGPTYPE_AS4_PATH:
468 		asn_bytes = 4;
469 		/* FALLTHROUGH */
470 	case BGPTYPE_AS_PATH:
471 	/*
472 	 * 2-byte speakers will receive AS4_PATH as well AS_PATH (2-byte).
473 	 * 4-byte speakers will only receive AS_PATH but it will be 4-byte.
474 	 * To identify which is the case, compare the length of the path
475 	 * segment value in bytes, with the path segment length from the
476 	 * message (counted in # of AS)
477 	 */
478 
479 		if (len % 2) {
480 			printf(" invalid len");
481 			break;
482 		}
483 		if (!len) {
484 			/* valid: local originated routes to IBGP peers */
485 			printf(" empty");
486 			break;
487 		}
488 		while (p < dat + len) {
489 			TCHECK2(p[0], 2);
490 			if (asn_bytes == 0) {
491 				if (p[1] == 0) {
492 				/* invalid: segment contains one or more AS */
493 					printf(" malformed");
494 					break;
495 				}
496 				asn_bytes = (len-2)/p[1];
497 			}
498 			printf("%s",
499 			    tok2str(bgp_as_path_segment_open_values,
500 			    "?", p[0]));
501 			for (i = 0; i < p[1] * asn_bytes; i += asn_bytes) {
502 				TCHECK2(p[2 + i], asn_bytes);
503 				printf("%s", i == 0 ? "" : " ");
504 				if (asn_bytes == 2)
505 					printf("%u", EXTRACT_16BITS(&p[2 + i]));
506 				else
507 					printf("%u", EXTRACT_32BITS(&p[2 + i]));
508 			}
509 			printf("%s",
510 			    tok2str(bgp_as_path_segment_close_values,
511 			    "?", p[0]));
512 			p += 2 + p[1] * asn_bytes;
513 		}
514 		break;
515 	case BGPTYPE_NEXT_HOP:
516 		if (len != 4)
517 			printf(" invalid len");
518 		else {
519 			TCHECK2(p[0], 4);
520 			printf(" %s", getname(p));
521 		}
522 		break;
523 	case BGPTYPE_MULTI_EXIT_DISC:
524 	case BGPTYPE_LOCAL_PREF:
525 		if (len != 4)
526 			printf(" invalid len");
527 		else {
528 			TCHECK2(p[0], 4);
529 			printf(" %u", EXTRACT_32BITS(p));
530 		}
531 		break;
532 	case BGPTYPE_ATOMIC_AGGREGATE:
533 		if (len != 0)
534 			printf(" invalid len");
535 		break;
536 	case BGPTYPE_AGGREGATOR4:
537 	case BGPTYPE_AGGREGATOR:
538 	/*
539 	 * like AS_PATH/AS4_PATH, AGGREGATOR can contain
540 	 * either 2-byte or 4-byte ASN, and AGGREGATOR4
541 	 * always contains 4-byte ASN.
542 	 */
543 		if (len != 6 && len != 8) {
544 			printf(" invalid len");
545 			break;
546 		}
547 		TCHECK2(p[0], len);
548 		printf(" AS #");
549 		if (len == 6)
550 			printf("%u", EXTRACT_16BITS(p));
551 		else
552 			printf("%u", EXTRACT_32BITS(p));
553 		printf(", origin %s", getname(p+len-4));
554 		break;
555 	case BGPTYPE_COMMUNITIES:
556 		if (len % 4) {
557 			printf(" invalid len");
558 			break;
559 		}
560 		while (tlen>0) {
561 			u_int32_t comm;
562 			TCHECK2(p[0], 4);
563 			comm = EXTRACT_32BITS(p);
564 			switch (comm) {
565 			case BGP_COMMUNITY_NO_EXPORT:
566 				printf(" NO_EXPORT");
567 				break;
568 			case BGP_COMMUNITY_NO_ADVERT:
569 				printf(" NO_ADVERTISE");
570 				break;
571 			case BGP_COMMUNITY_NO_EXPORT_SUBCONFED:
572 				printf(" NO_EXPORT_SUBCONFED");
573 				break;
574 			case BGP_COMMUNITY_NO_PEER:
575 				printf(" NO_PEER");
576 				break;
577 			default:
578 				printf(" %d:%d",
579 					(comm >> 16) & 0xffff, comm & 0xffff);
580 				break;
581 			}
582 			tlen -= 4;
583 			p += 4;
584 		}
585 		break;
586 	case BGPTYPE_LARGE_COMMUNITIES:
587 		if (len == 0 || len % 12) {
588 			printf(" invalid len");
589 			break;
590 		}
591 		while (tlen>0) {
592 			TCHECK2(p[0], 12);
593 			printf(" %u:%u:%u",
594 			EXTRACT_32BITS(p),
595 			EXTRACT_32BITS(p + 4),
596 			EXTRACT_32BITS(p + 8));
597 			tlen -= 12;
598 			p += 12;
599 		}
600 		break;
601 	case BGPTYPE_ONLY_TO_CUSTOMER:
602 		if (len != 4) {
603 			printf(" invalid len");
604 			break;
605 		}
606 		TCHECK2(p[0], 4);
607 		printf(" AS%u", EXTRACT_32BITS(p));
608 		break;
609 	case BGPTYPE_ORIGINATOR_ID:
610 		if (len != 4) {
611 			printf(" invalid len");
612 			break;
613                 }
614 		TCHECK2(p[0], 4);
615 		printf("%s",getname(p));
616 		break;
617 	case BGPTYPE_CLUSTER_LIST:
618 		if (len % 4) {
619 			printf(" invalid len");
620 			break;
621 		}
622 		while (tlen>0) {
623 			TCHECK2(p[0], 4);
624 			printf(" %s%s",
625 			    getname(p),
626 			    (tlen>4) ? ", " : "");
627 			tlen -=4;
628 			p +=4;
629 		}
630 		break;
631 	case BGPTYPE_MP_REACH_NLRI:
632 		TCHECK2(p[0], BGP_MP_NLRI_MINSIZE);
633 		af = EXTRACT_16BITS(p);
634 		safi = p[2];
635 		if (safi >= 128)
636 			printf(" %s vendor specific %u,", af_name(af), safi);
637 		else {
638 			printf(" %s %s,", af_name(af),
639 				bgp_attr_nlri_safi(safi));
640 		}
641 		p += 3;
642 
643 		if (af != AFNUM_INET && af != AFNUM_INET6)
644 			break;
645 
646 		TCHECK(p[0]);
647 		tlen = p[0];
648 		if (tlen) {
649 			printf(" nexthop");
650 			i = 0;
651 			while (i < tlen) {
652 				switch (af) {
653 				case AFNUM_INET:
654 					TCHECK2(p[1+i], sizeof(struct in_addr));
655 					printf(" %s", getname(p + 1 + i));
656 					i += sizeof(struct in_addr);
657 					break;
658 				case AFNUM_INET6:
659 					TCHECK2(p[1+i], sizeof(struct in6_addr));
660 					printf(" %s", getname6(p + 1 + i));
661 					i += sizeof(struct in6_addr);
662 					break;
663 				default:
664 					printf(" (unknown af)");
665 					i = tlen;	/*exit loop*/
666 					break;
667 				}
668 			}
669 			printf(",");
670 		}
671 		p += 1 + tlen;
672 
673 		TCHECK(p[0]);
674 		snpa = p[0];
675 		p++;
676 		if (snpa) {
677 			printf(" %u snpa", snpa);
678 			for (/*nothing*/; snpa > 0; snpa--) {
679 				TCHECK(p[0]);
680 				printf("(%d bytes)", p[0]);
681 				p += p[0] + 1;
682 			}
683 			printf(",");
684 		}
685 
686 		printf(" NLRI");
687 		while (len - (p - dat) > 0) {
688 			switch (af) {
689 			case AFNUM_INET:
690 				advance = decode_prefix4(p, buf, sizeof(buf));
691 				break;
692 			case AFNUM_INET6:
693 				advance = decode_prefix6(p, buf, sizeof(buf));
694 				break;
695 			default:
696 				printf(" (unknown af)");
697 				advance = 0;
698 				p = dat + len;
699 				break;
700 			}
701 
702 			if (advance <= 0)
703 				break;
704 
705 			printf(" %s", buf);
706 			p += advance;
707 		}
708 
709 		break;
710 
711 	case BGPTYPE_MP_UNREACH_NLRI:
712 		TCHECK2(p[0], BGP_MP_NLRI_MINSIZE);
713 		af = EXTRACT_16BITS(p);
714 		safi = p[2];
715 		if (safi >= 128)
716 			printf(" %s vendor specific %u,", af_name(af), safi);
717 		else {
718 			printf(" %s %s,", af_name(af),
719 				bgp_attr_nlri_safi(safi));
720 		}
721 		p += 3;
722 
723 		printf(" Withdraw");
724 		while (len - (p - dat) > 0) {
725 			switch (af) {
726 			case AFNUM_INET:
727 				advance = decode_prefix4(p, buf, sizeof(buf));
728 				break;
729 			case AFNUM_INET6:
730 				advance = decode_prefix6(p, buf, sizeof(buf));
731 				break;
732 			default:
733 				printf(" (unknown af)");
734 				advance = 0;
735 				p = dat + len;
736 				break;
737 			}
738 
739 			if (advance <= 0)
740 				break;
741 
742 			printf(" %s", buf);
743 			p += advance;
744 		}
745 		break;
746 	default:
747 		break;
748 	}
749 	return 1;
750 
751 trunc:
752 	return 0;
753 }
754 
755 static void
756 bgp_open_capa_print(const u_char *opt, int length)
757 {
758 	int i,cap_type,cap_len,tcap_len,cap_offset;
759 
760 	i = 0;
761 	while (i < length) {
762 		TCHECK2(opt[i], 2);
763 
764 		cap_type=opt[i];
765 		cap_len=opt[i+1];
766 		printf("%sCAP %s", i == 0 ? "(" : " ", 		/* ) */
767 		    bgp_capcode(cap_type));
768 
769 		/* can we print the capability? */
770 		TCHECK2(opt[i+2],cap_len);
771 		i += 2;
772 
773 		switch(cap_type) {
774 		case BGP_CAPCODE_MP:
775 			if (cap_len != 4) {
776 				printf(" BAD ENCODING");
777 				break;
778 			}
779 			printf(" [%s %s]",
780 			    af_name(EXTRACT_16BITS(opt+i)),
781 			    bgp_attr_nlri_safi(opt[i+3]));
782 			break;
783 		case BGP_CAPCODE_REFRESH:
784 			if (cap_len != 0) {
785 				printf(" BAD ENCODING");
786 				break;
787 			}
788 			break;
789 		case BGP_CAPCODE_BGPROLE:
790 			if (cap_len != 1) {
791 				printf(" BAD ENCODING");
792 				break;
793 			}
794 			printf(" [%s]", bgp_roletype(opt[i]));
795 			break;
796 		case BGP_CAPCODE_RESTART:
797 			if (cap_len < 2 || (cap_len - 2) % 4) {
798 				printf(" BAD ENCODING");
799 				break;
800 			}
801 			printf(" [%s], Time %us",
802 			    ((opt[i])&0x80) ? "R" : "none",
803 			    EXTRACT_16BITS(opt+i)&0xfff);
804 			tcap_len=cap_len - 2;
805 			cap_offset=2;
806 			while(tcap_len>=4) {
807 				printf(" (%s %s)%s",
808 				    af_name(EXTRACT_16BITS(opt+i+cap_offset)),
809 				    bgp_attr_nlri_safi(opt[i+cap_offset+2]),
810 				    ((opt[i+cap_offset+3])&0x80) ?
811 					" forwarding state preserved" : "" );
812 				tcap_len-=4;
813 				cap_offset+=4;
814 			}
815 			break;
816 		case BGP_CAPCODE_AS4:
817 			if (cap_len != 4) {
818 				printf(" BAD ENCODING");
819 				break;
820 			}
821 			printf(" #");
822 			printf("%u", EXTRACT_32BITS(opt+i));
823 			break;
824 		default:
825 			printf(" len %d", cap_len);
826 			break;
827 		}
828 		i += cap_len;
829 		if (i + cap_len < length)
830 			printf(",");
831 	}
832 	/* ( */
833 	printf(")");
834 	return;
835 trunc:
836 	printf("[|BGP]");
837 }
838 
839 static void
840 bgp_open_print(const u_char *dat, int length)
841 {
842 	struct bgp_open bgpo;
843 	struct bgp_opt bgpopt;
844 	const u_char *opt;
845 	int i;
846 
847 	TCHECK2(dat[0], BGP_OPEN_SIZE);
848 	memcpy(&bgpo, dat, BGP_OPEN_SIZE);
849 
850 	printf(": Version %d,", bgpo.bgpo_version);
851 	printf(" AS #%u,", ntohs(bgpo.bgpo_myas));
852 	printf(" Holdtime %u,", ntohs(bgpo.bgpo_holdtime));
853 	printf(" ID %s,", getname((u_char *)&bgpo.bgpo_id));
854 	printf(" Option length %u", bgpo.bgpo_optlen);
855 
856 	/* sanity checking */
857 	if ((length < bgpo.bgpo_optlen+BGP_OPEN_SIZE) || (!bgpo.bgpo_optlen))
858 		return;
859 
860 	/* ugly! */
861 	opt = &((const struct bgp_open *)dat)->bgpo_optlen;
862 	opt++;
863 
864 	i = 0;
865 	while (i < bgpo.bgpo_optlen) {
866 		TCHECK2(opt[i], BGP_OPT_SIZE);
867 		memcpy(&bgpopt, &opt[i], BGP_OPT_SIZE);
868 		if (i + 2 + bgpopt.bgpopt_len > bgpo.bgpo_optlen) {
869 			printf(" [|opt %d %d]", bgpopt.bgpopt_len, bgpopt.bgpopt_type);
870 			break;
871 		}
872 
873 		if (i == 0)
874 			printf(" (");		/* ) */
875 		else
876 			printf(" ");
877 
878 		switch(bgpopt.bgpopt_type) {
879 		case BGP_OPT_CAP:
880 			bgp_open_capa_print(opt + i + BGP_OPT_SIZE,
881 			    bgpopt.bgpopt_len);
882 			break;
883 		default:
884 			printf(" (option %s, len=%u)",
885 			    bgp_opttype(bgpopt.bgpopt_type),
886 			    bgpopt.bgpopt_len);
887 			break;
888 		}
889 
890 		i += BGP_OPT_SIZE + bgpopt.bgpopt_len;
891 	}
892 	/* ( */
893 	printf(")");
894 	return;
895 trunc:
896 	printf("[|BGP]");
897 }
898 
899 static void
900 bgp_update_print(const u_char *dat, int length)
901 {
902 	struct bgp bgp;
903 	struct bgp_attr bgpa;
904 	const u_char *p;
905 	int len;
906 	int i;
907 	int newline;
908 
909 	TCHECK2(dat[0], BGP_SIZE);
910 	memcpy(&bgp, dat, BGP_SIZE);
911 	p = dat + BGP_SIZE;	/*XXX*/
912 	printf(":");
913 
914 	/* Unfeasible routes */
915 	len = EXTRACT_16BITS(p);
916 	if (len) {
917 		/*
918 		 * Without keeping state from the original NLRI message,
919 		 * it's not possible to tell if this a v4 or v6 route,
920 		 * so do not try to decode it.
921 		 */
922 		printf(" (Withdrawn routes: %d bytes)", len);
923 	}
924 	p += 2 + len;
925 
926 	TCHECK2(p[0], 2);
927 	len = EXTRACT_16BITS(p);
928 
929 	if (len == 0 && length == BGP_UPDATE_MINSIZE) {
930 		printf(" End-of-Rib Marker (empty NLRI)");
931 		return;
932 	}
933 
934 	if (len) {
935 		/* do something more useful!*/
936 		i = 2;
937 		printf(" (Path attributes:");	/* ) */
938 		newline = 0;
939 		while (i < 2 + len) {
940 			int alen, aoff;
941 
942 			TCHECK2(p[i], sizeof(bgpa));
943 			memcpy(&bgpa, &p[i], sizeof(bgpa));
944 			alen = bgp_attr_len(&bgpa);
945 			aoff = bgp_attr_off(&bgpa);
946 
947 			if (vflag && newline)
948 				printf("\n\t\t");
949 			else
950 				printf(" ");
951 			printf("(");		/* ) */
952 			printf("%s", bgp_attr_type(bgpa.bgpa_type));
953 			if (bgpa.bgpa_flags) {
954 				printf("[%s%s%s%s",
955 					bgpa.bgpa_flags & 0x80 ? "O" : "",
956 					bgpa.bgpa_flags & 0x40 ? "T" : "",
957 					bgpa.bgpa_flags & 0x20 ? "P" : "",
958 					bgpa.bgpa_flags & 0x10 ? "E" : "");
959 				if (bgpa.bgpa_flags & 0xf)
960 					printf("+%x", bgpa.bgpa_flags & 0xf);
961 				printf("]");
962 			}
963 
964 			if (!bgp_attr_print(&bgpa, &p[i + aoff], alen))
965 				goto trunc;
966 			newline = 1;
967 
968 			/* ( */
969 			printf(")");
970 
971 			i += aoff + alen;
972 		}
973 
974 		/* ( */
975 		printf(")");
976 	}
977 	p += 2 + len;
978 
979 	if (len && dat + length > p)
980 		printf("\n\t\t");
981 	if (dat + length > p) {
982 		printf("(NLRI:");	/* ) */
983 		while (dat + length > p) {
984 			char buf[HOST_NAME_MAX+1 + 100];
985 			i = decode_prefix4(p, buf, sizeof(buf));
986 			if (i == -1) {
987 				printf(" (illegal prefix length)");
988 				break;
989 			} else if (i == -2)
990 				goto trunc;
991 			printf(" %s", buf);
992 			p += i;
993 		}
994 
995 		/* ( */
996 		printf(")");
997 	}
998 	return;
999 trunc:
1000 	printf("[|BGP]");
1001 }
1002 
1003 static void
1004 bgp_notification_print(const u_char *dat, int length)
1005 {
1006 	struct bgp_notification bgpn;
1007 	u_int16_t af;
1008 	u_int8_t safi;
1009 	const u_char *p;
1010 	size_t shutdown_comm_length;
1011 	char shutstring[BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN + 1];
1012 
1013 	TCHECK2(dat[0], BGP_NOTIFICATION_SIZE);
1014 	memcpy(&bgpn, dat, BGP_NOTIFICATION_SIZE);
1015 
1016 	/* sanity checking */
1017 	if (length < BGP_NOTIFICATION_SIZE)
1018 		return;
1019 
1020 	printf(": error %s,", bgp_notify_major(bgpn.bgpn_major));
1021 	printf(" subcode %s",
1022 		bgp_notify_minor(bgpn.bgpn_major, bgpn.bgpn_minor));
1023 
1024 	if (bgpn.bgpn_major == BGP_NOTIFY_MAJOR_CEASE) {
1025 		/*
1026 		 * RFC 4486: optional maxprefix subtype of 7 bytes
1027 		 * may contain AFI, SAFI and MAXPREFIXES
1028 		 */
1029 		if(bgpn.bgpn_minor == BGP_NOTIFY_MINOR_CEASE_MAXPRFX &&
1030 		    length >= BGP_NOTIFICATION_SIZE + 7) {
1031 
1032 			p = dat + BGP_NOTIFICATION_SIZE;
1033 			TCHECK2(*p, 7);
1034 
1035 			af = EXTRACT_16BITS(p);
1036 			safi = p[2];
1037 			printf(" %s %s,", af_name(af),
1038 			    bgp_attr_nlri_safi(safi));
1039 
1040 			printf(" Max Prefixes: %u", EXTRACT_32BITS(p+3));
1041 		}
1042 
1043 		/*
1044 		 * RFC 8203 describes a method to send a message intended
1045 		 * for human consumption regarding the Administrative
1046 		 * Shutdown or Reset event. This is called the "Shutdown
1047 		 * Communication". The communication is UTF-8 encoded
1048 		 * and may be no longer than 128 bytes.
1049 		 */
1050 		if ((bgpn.bgpn_minor == BGP_NOTIFY_MINOR_CEASE_SHUT ||
1051 		    bgpn.bgpn_minor == BGP_NOTIFY_MINOR_CEASE_RESET) &&
1052 		    (length >= BGP_NOTIFICATION_SIZE + 1)) {
1053 			p = dat + BGP_NOTIFICATION_SIZE;
1054 			TCHECK2(*p, 1);
1055 			shutdown_comm_length = *p;
1056 
1057 			/* sanity checking */
1058 			if (shutdown_comm_length == 0)
1059 				return;
1060 			if (shutdown_comm_length >
1061 			    BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN)
1062 				goto trunc;
1063 			if (length < (shutdown_comm_length + 1 +
1064 			    BGP_NOTIFICATION_SIZE))
1065 				goto trunc;
1066 			TCHECK2(*(p+1), shutdown_comm_length);
1067 
1068 			/* a proper shutdown communication */
1069 			printf(", Shutdown Communication [len %zu]: \"",
1070 			    shutdown_comm_length);
1071 			memset(shutstring, 0, sizeof(shutstring));
1072 			memcpy(shutstring, p+1, shutdown_comm_length);
1073 			safeputs(shutstring);
1074 			printf("\"");
1075 		}
1076 	}
1077 
1078 	return;
1079 
1080 trunc:
1081 	printf("[|BGP]");
1082 }
1083 
1084 static void
1085 bgp_route_refresh_print(const u_char *dat, int length)
1086 {
1087 	const struct bgp_route_refresh *bgp_route_refresh_header;
1088 
1089 	TCHECK2(dat[0], BGP_ROUTE_REFRESH_SIZE);
1090 
1091 	/* sanity checking */
1092 	if (length<BGP_ROUTE_REFRESH_SIZE)
1093 		return;
1094 
1095 	bgp_route_refresh_header = (const struct bgp_route_refresh *)dat;
1096 
1097 	printf(" %s (%s %s)",
1098 	    refresh_subtype(bgp_route_refresh_header->subtype),
1099 	    af_name(EXTRACT_16BITS(&bgp_route_refresh_header->afi)),
1100 	    bgp_attr_nlri_safi(bgp_route_refresh_header->safi));
1101 
1102 	return;
1103 trunc:
1104 	printf("[|BGP]");
1105 }
1106 
1107 static int
1108 bgp_header_print(const u_char *dat, int length)
1109 {
1110 	struct bgp bgp;
1111 
1112 	TCHECK2(dat[0], BGP_SIZE);
1113 	memcpy(&bgp, dat, BGP_SIZE);
1114 	printf("(%s", bgp_type(bgp.bgp_type));		/* ) */
1115 
1116 	switch (bgp.bgp_type) {
1117 	case BGP_OPEN:
1118 		bgp_open_print(dat, length);
1119 		break;
1120 	case BGP_UPDATE:
1121 		bgp_update_print(dat, length);
1122 		break;
1123 	case BGP_NOTIFICATION:
1124 		bgp_notification_print(dat, length);
1125 		break;
1126 	case BGP_KEEPALIVE:
1127 		break;
1128 	case BGP_ROUTE_REFRESH:
1129 		bgp_route_refresh_print(dat, length);
1130 	default:
1131 		TCHECK2(*dat, length);
1132 		break;
1133 	}
1134 
1135 	/* ( */
1136 	printf(")");
1137 	return 1;
1138 trunc:
1139 	printf("[|BGP]");
1140 	return 0;
1141 }
1142 
1143 void
1144 bgp_print(const u_char *dat, int length)
1145 {
1146 	const u_char *p;
1147 	const u_char *ep;
1148 	const u_char *start;
1149 	const u_char marker[] = {
1150 		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1151 		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1152 	};
1153 	struct bgp bgp;
1154 	u_int16_t hlen;
1155 	int newline;
1156 
1157 	ep = dat + length;
1158 	if (snapend < dat + length)
1159 		ep = snapend;
1160 
1161 	printf(": BGP");
1162 
1163 	p = dat;
1164 	newline = 0;
1165 	start = p;
1166 	while (p < ep) {
1167 		if (!TTEST2(p[0], 1))
1168 			break;
1169 		if (p[0] != 0xff) {
1170 			p++;
1171 			continue;
1172 		}
1173 
1174 		if (!TTEST2(p[0], sizeof(marker)))
1175 			break;
1176 		if (memcmp(p, marker, sizeof(marker)) != 0) {
1177 			p++;
1178 			continue;
1179 		}
1180 
1181 		/* found BGP header */
1182 		TCHECK2(p[0], BGP_SIZE);	/*XXX*/
1183 		memcpy(&bgp, p, BGP_SIZE);
1184 
1185 		if (start != p)
1186 			printf(" [|BGP]");
1187 
1188 		hlen = ntohs(bgp.bgp_len);
1189 		if (vflag && newline)
1190 			printf("\n\t");
1191 		else
1192 			printf(" ");
1193 		if (hlen < BGP_SIZE) {
1194 			printf("\n[|BGP Bogus header length %u < %u]",
1195 			    hlen, BGP_SIZE);
1196 			break;
1197 		}
1198 		if (TTEST2(p[0], hlen)) {
1199 			if (!bgp_header_print(p, hlen))
1200 				return;
1201 			newline = 1;
1202 			p += hlen;
1203 			start = p;
1204 		} else {
1205 			printf("[|BGP %s]", bgp_type(bgp.bgp_type));
1206 			break;
1207 		}
1208 	}
1209 
1210 	return;
1211 
1212 trunc:
1213 	printf(" [|BGP]");
1214 }
1215