Bug Summary

File:src/usr.sbin/tcpdump/print-bgp.c
Warning:line 378, column 2
Value stored to 'plen' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name print-bgp.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/tcpdump/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.sbin/tcpdump/../../sbin/pfctl -I /usr/src/usr.sbin/tcpdump/../hostapd -I /usr/src/usr.sbin/tcpdump/../../lib/libpcap -D CSLIP -D PPP -D HAVE_FDDI -D ETHER_SERVICE -D HAVE_ETHER_NTOHOST -D INET6 -I /usr/src/usr.sbin/tcpdump/../../sbin/pfctl -D FAKE_PF_KERNEL -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/tcpdump/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.sbin/tcpdump/print-bgp.c
1/* $OpenBSD: print-bgp.c,v 1.30 2021/06/17 15:59:23 job 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(*__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
49struct bgp {
50 u_int8_t bgp_marker[16];
51 u_int16_t bgp_len;
52 u_int8_t bgp_type;
53};
54#define BGP_SIZE19 19 /* unaligned */
55
56#define BGP_OPEN1 1
57#define BGP_UPDATE2 2
58#define BGP_NOTIFICATION3 3
59#define BGP_KEEPALIVE4 4
60#define BGP_ROUTE_REFRESH5 5
61
62struct 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_SIZE29 29 /* unaligned */
74
75struct bgp_opt {
76 u_int8_t bgpopt_type;
77 u_int8_t bgpopt_len;
78 /* variable length */
79};
80#define BGP_OPT_CAP2 2
81#define BGP_OPT_SIZE2 2 /* some compilers may pad to 4 bytes */
82
83#define BGP_UPDATE_MINSIZE23 23
84
85struct 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_SIZE21 21 /* unaligned */
94
95struct 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_SIZE23 23
104
105struct 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)(((p)->bgpa_flags & 0x10) ? (__uint16_t)(__builtin_constant_p
((p)->bgpa_len.elen) ? (__uint16_t)(((__uint16_t)((p)->
bgpa_len.elen) & 0xffU) << 8 | ((__uint16_t)((p)->
bgpa_len.elen) & 0xff00U) >> 8) : __swap16md((p)->
bgpa_len.elen)) : (p)->bgpa_len.len)
\
113 (((p)->bgpa_flags & 0x10) ? \
114 ntohs((p)->bgpa_len.elen)(__uint16_t)(__builtin_constant_p((p)->bgpa_len.elen) ? (__uint16_t
)(((__uint16_t)((p)->bgpa_len.elen) & 0xffU) << 8
| ((__uint16_t)((p)->bgpa_len.elen) & 0xff00U) >>
8) : __swap16md((p)->bgpa_len.elen))
: (p)->bgpa_len.len)
115#define bgp_attr_off(p)(((p)->bgpa_flags & 0x10) ? 4 : 3) \
116 (((p)->bgpa_flags & 0x10) ? 4 : 3)
117};
118
119#define BGPTYPE_ORIGIN1 1
120#define BGPTYPE_AS_PATH2 2
121#define BGPTYPE_NEXT_HOP3 3
122#define BGPTYPE_MULTI_EXIT_DISC4 4
123#define BGPTYPE_LOCAL_PREF5 5
124#define BGPTYPE_ATOMIC_AGGREGATE6 6
125#define BGPTYPE_AGGREGATOR7 7
126#define BGPTYPE_COMMUNITIES8 8 /* RFC1997 */
127#define BGPTYPE_ORIGINATOR_ID9 9 /* RFC1998 */
128#define BGPTYPE_CLUSTER_LIST10 10 /* RFC1998 */
129#define BGPTYPE_DPA11 11 /* draft-ietf-idr-bgp-dpa */
130#define BGPTYPE_ADVERTISERS12 12 /* RFC1863 */
131#define BGPTYPE_RCID_PATH13 13 /* RFC1863 */
132#define BGPTYPE_MP_REACH_NLRI14 14 /* RFC2283 */
133#define BGPTYPE_MP_UNREACH_NLRI15 15 /* RFC2283 */
134#define BGPTYPE_EXTD_COMMUNITIES16 16 /* RFC4360 */
135#define BGPTYPE_AS4_PATH17 17 /* RFC4893 */
136#define BGPTYPE_AGGREGATOR418 18 /* RFC4893 */
137#define BGPTYPE_LARGE_COMMUNITIES32 32 /* draft-ietf-idr-large-community */
138
139#define BGP_AS_SET1 1
140#define BGP_AS_SEQUENCE2 2
141#define BGP_CONFED_AS_SEQUENCE3 3 /* draft-ietf-idr-rfc3065bis-01 */
142#define BGP_CONFED_AS_SET4 4 /* draft-ietf-idr-rfc3065bis-01 */
143
144static struct tok bgp_as_path_segment_open_values[] = {
145 { BGP_AS_SET1, " {" },
146 { BGP_AS_SEQUENCE2, " " },
147 { BGP_CONFED_AS_SEQUENCE3, " (" },
148 { BGP_CONFED_AS_SET4, " ({" },
149 { 0, NULL((void *)0)},
150};
151
152static struct tok bgp_as_path_segment_close_values[] = {
153 { BGP_AS_SET1, "}" },
154 { BGP_AS_SEQUENCE2, "" },
155 { BGP_CONFED_AS_SEQUENCE3, ")" },
156 { BGP_CONFED_AS_SET4, "})" },
157 { 0, NULL((void *)0)},
158};
159
160#define BGP_MP_NLRI_MINSIZE3 3
161
162static const char *bgptype[] = {
163 NULL((void *)0), "OPEN", "UPDATE", "NOTIFICATION", "KEEPALIVE", "ROUTE-REFRESH",
164};
165#define bgp_type(x)num_or_str(bgptype, sizeof(bgptype)/sizeof(bgptype[0]), (x)) num_or_str(bgptype, sizeof(bgptype)/sizeof(bgptype[0]), (x))
166
167static const char *bgpopt_type[] = {
168 NULL((void *)0), "Authentication Information", "Capabilities Advertisement",
169};
170#define bgp_opttype(x)num_or_str(bgpopt_type, sizeof(bgpopt_type)/sizeof(bgpopt_type
[0]), (x))
\
171 num_or_str(bgpopt_type, sizeof(bgpopt_type)/sizeof(bgpopt_type[0]), (x))
172
173#define BGP_CAPCODE_MP1 1
174#define BGP_CAPCODE_REFRESH2 2
175#define BGP_CAPCODE_RESTART64 64 /* draft-ietf-idr-restart-05 */
176#define BGP_CAPCODE_AS465 65 /* RFC4893 */
177
178static const char *bgp_capcode[] = {
179 NULL((void *)0), "MULTI_PROTOCOL", "ROUTE_REFRESH",
180 /* 3: RFC5291 */ "OUTBOUND_ROUTE_FILTERING",
181 /* 4: RFC3107 */ "MULTIPLE_ROUTES",
182 /* 5: RFC5549 */ "EXTENDED_NEXTHOP_ENCODING",
183 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
184 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
185 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
186 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
187 /* 64: RFC4724 */ "GRACEFUL_RESTART",
188 /* 65: RFC4893 */ "AS4", 0,
189 /* 67: [Chen] */ "DYNAMIC_CAPABILITY",
190 /* 68: [Appanna] */ "MULTISESSION",
191 /* 69: [draft-ietf-idr-add-paths] */ "ADD-PATH",
192 /* 70: RFC7313 */ "ENHANCED_ROUTE_REFRESH"
193};
194
195#define bgp_capcode(x)num_or_str(bgp_capcode, sizeof(bgp_capcode)/sizeof(bgp_capcode
[0]), (x))
\
196 num_or_str(bgp_capcode, sizeof(bgp_capcode)/sizeof(bgp_capcode[0]), (x))
197
198#define BGP_NOTIFY_MAJOR_CEASE6 6
199static const char *bgpnotify_major[] = {
200 NULL((void *)0), "Message Header Error",
201 "OPEN Message Error", "UPDATE Message Error",
202 "Hold Timer Expired", "Finite State Machine Error",
203 "Cease", "ROUTE_REFRESH Message Error",
204};
205#define bgp_notify_major(x)num_or_str(bgpnotify_major, sizeof(bgpnotify_major)/sizeof(bgpnotify_major
[0]), (x))
\
206 num_or_str(bgpnotify_major, \
207 sizeof(bgpnotify_major)/sizeof(bgpnotify_major[0]), (x))
208
209static const char *bgpnotify_minor_msg[] = {
210 NULL((void *)0), "Connection Not Synchronized",
211 "Bad Message Length", "Bad Message Type",
212};
213
214static const char *bgpnotify_minor_open[] = {
215 NULL((void *)0), "Unsupported Version Number",
216 "Bad Peer AS", "Bad BGP Identifier",
217 "Unsupported Optional Parameter", "Authentication Failure",
218 "Unacceptable Hold Time", "Unsupported Capability",
219};
220
221static const char *bgpnotify_minor_update[] = {
222 NULL((void *)0), "Malformed Attribute List",
223 "Unrecognized Well-known Attribute", "Missing Well-known Attribute",
224 "Attribute Flags Error", "Attribute Length Error",
225 "Invalid ORIGIN Attribute", "AS Routing Loop",
226 "Invalid NEXT_HOP Attribute", "Optional Attribute Error",
227 "Invalid Network Field", "Malformed AS_PATH",
228};
229
230static const char *bgpnotify_minor_holdtime[] = {
231 NULL((void *)0),
232};
233
234/* RFC 6608 */
235static const char *bgpnotify_minor_fsm[] = {
236 "Unspecified Error", "In OpenSent State", "In OpenConfirm State",
237 "In Established State",
238};
239
240/* RFC 4486 */
241#define BGP_NOTIFY_MINOR_CEASE_MAXPRFX1 1
242/* RFC 8203 */
243#define BGP_NOTIFY_MINOR_CEASE_SHUT2 2
244#define BGP_NOTIFY_MINOR_CEASE_RESET4 4
245#define BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN255 255
246static const char *bgpnotify_minor_cease[] = {
247 NULL((void *)0), "Maximum Number of Prefixes Reached", "Administrative Shutdown",
248 "Peer De-configured", "Administrative Reset", "Connection Rejected",
249 "Other Configuration Change", "Connection Collision Resolution",
250 "Out of Resources",
251};
252
253/* RFC 7313 */
254static const char *bgpnotify_minor_err[] = {
255 NULL((void *)0), "Invalid Message Length",
256};
257
258static const char **bgpnotify_minor[] = {
259 NULL((void *)0), bgpnotify_minor_msg, bgpnotify_minor_open, bgpnotify_minor_update,
260 bgpnotify_minor_holdtime, bgpnotify_minor_fsm, bgpnotify_minor_cease,
261 bgpnotify_minor_err,
262};
263static const int bgpnotify_minor_siz[] = {
264 0,
265 sizeof(bgpnotify_minor_msg)/sizeof(bgpnotify_minor_msg[0]),
266 sizeof(bgpnotify_minor_open)/sizeof(bgpnotify_minor_open[0]),
267 sizeof(bgpnotify_minor_update)/sizeof(bgpnotify_minor_update[0]),
268 sizeof(bgpnotify_minor_holdtime)/sizeof(bgpnotify_minor_holdtime[0]),
269 sizeof(bgpnotify_minor_fsm)/sizeof(bgpnotify_minor_fsm[0]),
270 sizeof(bgpnotify_minor_cease)/sizeof(bgpnotify_minor_cease[0]),
271 sizeof(bgpnotify_minor_err)/sizeof(bgpnotify_minor_err[0]),
272};
273
274static const char *bgpattr_origin[] = {
275 "IGP", "EGP", "INCOMPLETE",
276};
277#define bgp_attr_origin(x)num_or_str(bgpattr_origin, sizeof(bgpattr_origin)/sizeof(bgpattr_origin
[0]), (x))
\
278 num_or_str(bgpattr_origin, \
279 sizeof(bgpattr_origin)/sizeof(bgpattr_origin[0]), (x))
280
281static const char *bgpattr_type[] = {
282 NULL((void *)0), "ORIGIN", "AS_PATH", "NEXT_HOP",
283 "MULTI_EXIT_DISC", "LOCAL_PREF", "ATOMIC_AGGREGATE", "AGGREGATOR",
284 "COMMUNITIES", "ORIGINATOR_ID", "CLUSTER_LIST", "DPA",
285 "ADVERTISERS", "RCID_PATH", "MP_REACH_NLRI", "MP_UNREACH_NLRI",
286 "EXTD_COMMUNITIES", "AS4_PATH", "AGGREGATOR4", NULL((void *)0), NULL((void *)0), NULL((void *)0),
287 NULL((void *)0), NULL((void *)0), NULL((void *)0), NULL((void *)0), NULL((void *)0), NULL((void *)0), NULL((void *)0), NULL((void *)0), NULL((void *)0), NULL((void *)0),
288 "LARGE_COMMUNITIES",
289};
290#define bgp_attr_type(x)num_or_str(bgpattr_type, sizeof(bgpattr_type)/sizeof(bgpattr_type
[0]), (x))
\
291 num_or_str(bgpattr_type, \
292 sizeof(bgpattr_type)/sizeof(bgpattr_type[0]), (x))
293
294/* Subsequent address family identifier, RFC2283 section 7 */
295static const char *bgpattr_nlri_safi[] = {
296 "Reserved", "Unicast", "Multicast", "Unicast+Multicast",
297 "labeled Unicast", /* MPLS BGP RFC3107 */
298 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
299 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
300 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
301 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
302 /* 64-66: MPLS BGP RFC3107 */
303 "Tunnel", "VPLS", "MDT",
304 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
305 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
306 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
307 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
308 /* 128-129: RFC4364 + RFC6513 */
309 "L3VPN Unicast", "L3VPN Multicast",
310};
311#define bgp_attr_nlri_safi(x)num_or_str(bgpattr_nlri_safi, sizeof(bgpattr_nlri_safi)/sizeof
(bgpattr_nlri_safi[0]), (x))
\
312 num_or_str(bgpattr_nlri_safi, \
313 sizeof(bgpattr_nlri_safi)/sizeof(bgpattr_nlri_safi[0]), (x))
314
315/* well-known community */
316#define BGP_COMMUNITY_NO_EXPORT0xffffff01 0xffffff01
317#define BGP_COMMUNITY_NO_ADVERT0xffffff02 0xffffff02
318#define BGP_COMMUNITY_NO_EXPORT_SUBCONFED0xffffff03 0xffffff03
319#define BGP_COMMUNITY_NO_PEER0xffffff04 0xffffff04
320
321static const char *afnumber[] = AFNUM_NAME_STR{ "Reserved", "IPv4", "IPv6", "NSAP", "HDLC", "BBN 1822", "802"
, "E.163", "E.164", "F.69", "X.121", "IPX", "Appletalk", "Decnet IV"
, "Banyan Vines", "E.164 with NSAP subaddress", "DNS", "AS Number"
, "XTP over IPv4", "XTP over IPv6", "XTP native mode", "Fibre Channel WWPN"
, "Fibre Channel WWNN", "GWID" }
;
322#define af_name(x)(((x) == 65535) ? afnumber[0] : num_or_str(afnumber, sizeof(afnumber
)/sizeof(afnumber[0]), (x)))
\
323 (((x) == 65535) ? afnumber[0] : \
324 num_or_str(afnumber, \
325 sizeof(afnumber)/sizeof(afnumber[0]), (x)))
326
327static const char *refreshtype[] = {
328 "Request", "BoRR", "EoRR"
329};
330#define refresh_subtype(x)num_or_str(refreshtype, sizeof(refreshtype)/sizeof(refreshtype
[0]), (x))
\
331 num_or_str(refreshtype, sizeof(refreshtype)/sizeof(refreshtype[0]), (x))
332
333static const char *
334num_or_str(const char **table, size_t siz, int value)
335{
336 static char buf[20];
337 if (value < 0 || siz <= value || table[value] == NULL((void *)0)) {
338 snprintf(buf, sizeof(buf), "#%d", value);
339 return buf;
340 } else
341 return table[value];
342}
343
344static const char *
345bgp_notify_minor(int major, int minor)
346{
347 static const char **table;
348 int siz;
349 static char buf[20];
350 const char *p;
351
352 if (0 <= major
353 && major < sizeof(bgpnotify_minor)/sizeof(bgpnotify_minor[0])
354 && bgpnotify_minor[major]) {
355 table = bgpnotify_minor[major];
356 siz = bgpnotify_minor_siz[major];
357 if (0 <= minor && minor < siz && table[minor])
358 p = table[minor];
359 else
360 p = NULL((void *)0);
361 } else
362 p = NULL((void *)0);
363 if (p == NULL((void *)0)) {
364 snprintf(buf, sizeof(buf), "#%d", minor);
365 return buf;
366 } else
367 return p;
368}
369
370static int
371decode_prefix4(const u_char *pd, char *buf, u_int buflen)
372{
373 struct in_addr addr;
374 u_int plen;
375 int n;
376
377 TCHECK(pd[0])if (!(snapend - (sizeof(pd[0])) <= snapend && (const
u_char *)&(pd[0]) <= snapend - (sizeof(pd[0])))) goto
trunc
;
378 plen = pd[0]; /*
Value stored to 'plen' is never read
379 * prefix length is in bits; packet only contains
380 * enough bytes of address to contain this many bits
381 */
382 plen = pd[0];
383 if (32 < plen)
384 return -1;
385 memset(&addr, 0, sizeof(addr));
386 TCHECK2(pd[1], (plen + 7) / 8)if (!(snapend - ((plen + 7) / 8) <= snapend && (const
u_char *)&(pd[1]) <= snapend - ((plen + 7) / 8))) goto
trunc
;
387 memcpy(&addr, &pd[1], (plen + 7) / 8);
388 if (plen % 8) {
389 ((u_char *)&addr)[(plen + 7) / 8 - 1] &=
390 ((0xff00 >> (plen % 8)) & 0xff);
391 }
392 n = snprintf(buf, buflen, "%s/%u", getname((u_char *)&addr), plen);
393 if (n < 0 || n >= buflen)
394 return -1;
395
396 return 1 + (plen + 7) / 8;
397
398trunc:
399 return -2;
400}
401
402static int
403decode_prefix6(const u_char *pd, char *buf, u_int buflen)
404{
405 struct in6_addr addr;
406 u_int plen;
407 int n;
408
409 TCHECK(pd[0])if (!(snapend - (sizeof(pd[0])) <= snapend && (const
u_char *)&(pd[0]) <= snapend - (sizeof(pd[0])))) goto
trunc
;
410 plen = pd[0];
411 if (128 < plen)
412 return -1;
413
414 memset(&addr, 0, sizeof(addr));
415 TCHECK2(pd[1], (plen + 7) / 8)if (!(snapend - ((plen + 7) / 8) <= snapend && (const
u_char *)&(pd[1]) <= snapend - ((plen + 7) / 8))) goto
trunc
;
416 memcpy(&addr, &pd[1], (plen + 7) / 8);
417 if (plen % 8) {
418 addr.s6_addr__u6_addr.__u6_addr8[(plen + 7) / 8 - 1] &=
419 ((0xff00 >> (plen % 8)) & 0xff);
420 }
421
422 n = snprintf(buf, buflen, "%s/%u", getname6((u_char *)&addr), plen);
423 if (n < 0 || n >= buflen)
424 return -1;
425
426 return 1 + (plen + 7) / 8;
427
428trunc:
429 return -2;
430}
431
432static int
433bgp_attr_print(const struct bgp_attr *attr, const u_char *dat, int len)
434{
435 int i;
436 u_int16_t af;
437 u_int8_t safi, snpa;
438 int advance;
439 int tlen, asn_bytes;
440 const u_char *p;
441 char buf[HOST_NAME_MAX255+1 + 100];
442
443 p = dat;
444 tlen = len;
445 asn_bytes = 0;
446
447 switch (attr->bgpa_type) {
448 case BGPTYPE_ORIGIN1:
449 if (len != 1)
450 printf(" invalid len");
451 else {
452 TCHECK(p[0])if (!(snapend - (sizeof(p[0])) <= snapend && (const
u_char *)&(p[0]) <= snapend - (sizeof(p[0])))) goto trunc
;
453 printf(" %s", bgp_attr_origin(p[0])num_or_str(bgpattr_origin, sizeof(bgpattr_origin)/sizeof(bgpattr_origin
[0]), (p[0]))
);
454 }
455 break;
456 case BGPTYPE_AS4_PATH17:
457 asn_bytes = 4;
458 /* FALLTHROUGH */
459 case BGPTYPE_AS_PATH2:
460 /*
461 * 2-byte speakers will receive AS4_PATH as well AS_PATH (2-byte).
462 * 4-byte speakers will only receive AS_PATH but it will be 4-byte.
463 * To identify which is the case, compare the length of the path
464 * segment value in bytes, with the path segment length from the
465 * message (counted in # of AS)
466 */
467
468 if (len % 2) {
469 printf(" invalid len");
470 break;
471 }
472 if (!len) {
473 /* valid: local originated routes to IBGP peers */
474 printf(" empty");
475 break;
476 }
477 while (p < dat + len) {
478 TCHECK2(p[0], 2)if (!(snapend - (2) <= snapend && (const u_char *)
&(p[0]) <= snapend - (2))) goto trunc
;
479 if (asn_bytes == 0) {
480 if (p[1] == 0) {
481 /* invalid: segment contains one or more AS */
482 printf(" malformed");
483 break;
484 }
485 asn_bytes = (len-2)/p[1];
486 }
487 printf("%s",
488 tok2str(bgp_as_path_segment_open_values,
489 "?", p[0]));
490 for (i = 0; i < p[1] * asn_bytes; i += asn_bytes) {
491 TCHECK2(p[2 + i], asn_bytes)if (!(snapend - (asn_bytes) <= snapend && (const u_char
*)&(p[2 + i]) <= snapend - (asn_bytes))) goto trunc
;
492 printf("%s", i == 0 ? "" : " ");
493 if (asn_bytes == 2 || EXTRACT_16BITS(&p[2 + i])((u_int16_t)*((const u_int8_t *)(&p[2 + i]) + 0) <<
8 | (u_int16_t)*((const u_int8_t *)(&p[2 + i]) + 1))
)
494 printf("%u%s",
495 EXTRACT_16BITS(&p[2 + i])((u_int16_t)*((const u_int8_t *)(&p[2 + i]) + 0) <<
8 | (u_int16_t)*((const u_int8_t *)(&p[2 + i]) + 1))
,
496 asn_bytes == 4 ? "." : "");
497 if (asn_bytes == 4)
498 printf("%u",
499 EXTRACT_16BITS(&p[2 + i + 2])((u_int16_t)*((const u_int8_t *)(&p[2 + i + 2]) + 0) <<
8 | (u_int16_t)*((const u_int8_t *)(&p[2 + i + 2]) + 1))
);
500 }
501 printf("%s",
502 tok2str(bgp_as_path_segment_close_values,
503 "?", p[0]));
504 p += 2 + p[1] * asn_bytes;
505 }
506 break;
507 case BGPTYPE_NEXT_HOP3:
508 if (len != 4)
509 printf(" invalid len");
510 else {
511 TCHECK2(p[0], 4)if (!(snapend - (4) <= snapend && (const u_char *)
&(p[0]) <= snapend - (4))) goto trunc
;
512 printf(" %s", getname(p));
513 }
514 break;
515 case BGPTYPE_MULTI_EXIT_DISC4:
516 case BGPTYPE_LOCAL_PREF5:
517 if (len != 4)
518 printf(" invalid len");
519 else {
520 TCHECK2(p[0], 4)if (!(snapend - (4) <= snapend && (const u_char *)
&(p[0]) <= snapend - (4))) goto trunc
;
521 printf(" %u", EXTRACT_32BITS(p)((u_int32_t)*((const u_int8_t *)(p) + 0) << 24 | (u_int32_t
)*((const u_int8_t *)(p) + 1) << 16 | (u_int32_t)*((const
u_int8_t *)(p) + 2) << 8 | (u_int32_t)*((const u_int8_t
*)(p) + 3))
);
522 }
523 break;
524 case BGPTYPE_ATOMIC_AGGREGATE6:
525 if (len != 0)
526 printf(" invalid len");
527 break;
528 case BGPTYPE_AGGREGATOR418:
529 case BGPTYPE_AGGREGATOR7:
530 /*
531 * like AS_PATH/AS4_PATH, AGGREGATOR can contain
532 * either 2-byte or 4-byte ASN, and AGGREGATOR4
533 * always contains 4-byte ASN.
534 */
535 if (len != 6 && len != 8) {
536 printf(" invalid len");
537 break;
538 }
539 TCHECK2(p[0], len)if (!(snapend - (len) <= snapend && (const u_char *
)&(p[0]) <= snapend - (len))) goto trunc
;
540 printf(" AS #");
541 if (len == 6 || EXTRACT_16BITS(p)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | (u_int16_t
)*((const u_int8_t *)(p) + 1))
)
542 printf("%u%s", EXTRACT_16BITS(p)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | (u_int16_t
)*((const u_int8_t *)(p) + 1))
, len == 8 ? "." : "");
543 if (len == 8)
544 printf("%u", EXTRACT_16BITS(p+2)((u_int16_t)*((const u_int8_t *)(p+2) + 0) << 8 | (u_int16_t
)*((const u_int8_t *)(p+2) + 1))
);
545 printf(", origin %s", getname(p+len-4));
546 break;
547 case BGPTYPE_COMMUNITIES8:
548 if (len % 4) {
549 printf(" invalid len");
550 break;
551 }
552 while (tlen>0) {
553 u_int32_t comm;
554 TCHECK2(p[0], 4)if (!(snapend - (4) <= snapend && (const u_char *)
&(p[0]) <= snapend - (4))) goto trunc
;
555 comm = EXTRACT_32BITS(p)((u_int32_t)*((const u_int8_t *)(p) + 0) << 24 | (u_int32_t
)*((const u_int8_t *)(p) + 1) << 16 | (u_int32_t)*((const
u_int8_t *)(p) + 2) << 8 | (u_int32_t)*((const u_int8_t
*)(p) + 3))
;
556 switch (comm) {
557 case BGP_COMMUNITY_NO_EXPORT0xffffff01:
558 printf(" NO_EXPORT");
559 break;
560 case BGP_COMMUNITY_NO_ADVERT0xffffff02:
561 printf(" NO_ADVERTISE");
562 break;
563 case BGP_COMMUNITY_NO_EXPORT_SUBCONFED0xffffff03:
564 printf(" NO_EXPORT_SUBCONFED");
565 break;
566 case BGP_COMMUNITY_NO_PEER0xffffff04:
567 printf(" NO_PEER");
568 break;
569 default:
570 printf(" %d:%d",
571 (comm >> 16) & 0xffff, comm & 0xffff);
572 break;
573 }
574 tlen -= 4;
575 p += 4;
576 }
577 break;
578 case BGPTYPE_LARGE_COMMUNITIES32:
579 if (len == 0 || len % 12) {
580 printf(" invalid len");
581 break;
582 }
583 while (tlen>0) {
584 TCHECK2(p[0], 12)if (!(snapend - (12) <= snapend && (const u_char *
)&(p[0]) <= snapend - (12))) goto trunc
;
585 printf(" %u:%u:%u",
586 EXTRACT_32BITS(p)((u_int32_t)*((const u_int8_t *)(p) + 0) << 24 | (u_int32_t
)*((const u_int8_t *)(p) + 1) << 16 | (u_int32_t)*((const
u_int8_t *)(p) + 2) << 8 | (u_int32_t)*((const u_int8_t
*)(p) + 3))
,
587 EXTRACT_32BITS(p + 4)((u_int32_t)*((const u_int8_t *)(p + 4) + 0) << 24 | (u_int32_t
)*((const u_int8_t *)(p + 4) + 1) << 16 | (u_int32_t)*(
(const u_int8_t *)(p + 4) + 2) << 8 | (u_int32_t)*((const
u_int8_t *)(p + 4) + 3))
,
588 EXTRACT_32BITS(p + 8)((u_int32_t)*((const u_int8_t *)(p + 8) + 0) << 24 | (u_int32_t
)*((const u_int8_t *)(p + 8) + 1) << 16 | (u_int32_t)*(
(const u_int8_t *)(p + 8) + 2) << 8 | (u_int32_t)*((const
u_int8_t *)(p + 8) + 3))
);
589 tlen -= 12;
590 p += 12;
591 }
592 break;
593 case BGPTYPE_ORIGINATOR_ID9:
594 if (len != 4) {
595 printf(" invalid len");
596 break;
597 }
598 TCHECK2(p[0], 4)if (!(snapend - (4) <= snapend && (const u_char *)
&(p[0]) <= snapend - (4))) goto trunc
;
599 printf("%s",getname(p));
600 break;
601 case BGPTYPE_CLUSTER_LIST10:
602 if (len % 4) {
603 printf(" invalid len");
604 break;
605 }
606 while (tlen>0) {
607 TCHECK2(p[0], 4)if (!(snapend - (4) <= snapend && (const u_char *)
&(p[0]) <= snapend - (4))) goto trunc
;
608 printf(" %s%s",
609 getname(p),
610 (tlen>4) ? ", " : "");
611 tlen -=4;
612 p +=4;
613 }
614 break;
615 case BGPTYPE_MP_REACH_NLRI14:
616 TCHECK2(p[0], BGP_MP_NLRI_MINSIZE)if (!(snapend - (3) <= snapend && (const u_char *)
&(p[0]) <= snapend - (3))) goto trunc
;
617 af = EXTRACT_16BITS(p)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | (u_int16_t
)*((const u_int8_t *)(p) + 1))
;
618 safi = p[2];
619 if (safi >= 128)
620 printf(" %s vendor specific %u,", af_name(af)(((af) == 65535) ? afnumber[0] : num_or_str(afnumber, sizeof(
afnumber)/sizeof(afnumber[0]), (af)))
, safi);
621 else {
622 printf(" %s %s,", af_name(af)(((af) == 65535) ? afnumber[0] : num_or_str(afnumber, sizeof(
afnumber)/sizeof(afnumber[0]), (af)))
,
623 bgp_attr_nlri_safi(safi)num_or_str(bgpattr_nlri_safi, sizeof(bgpattr_nlri_safi)/sizeof
(bgpattr_nlri_safi[0]), (safi))
);
624 }
625 p += 3;
626
627 if (af != AFNUM_INET1 && af != AFNUM_INET62)
628 break;
629
630 TCHECK(p[0])if (!(snapend - (sizeof(p[0])) <= snapend && (const
u_char *)&(p[0]) <= snapend - (sizeof(p[0])))) goto trunc
;
631 tlen = p[0];
632 if (tlen) {
633 printf(" nexthop");
634 i = 0;
635 while (i < tlen) {
636 switch (af) {
637 case AFNUM_INET1:
638 TCHECK2(p[1+i], sizeof(struct in_addr))if (!(snapend - (sizeof(struct in_addr)) <= snapend &&
(const u_char *)&(p[1+i]) <= snapend - (sizeof(struct
in_addr)))) goto trunc
;
639 printf(" %s", getname(p + 1 + i));
640 i += sizeof(struct in_addr);
641 break;
642 case AFNUM_INET62:
643 TCHECK2(p[1+i], sizeof(struct in6_addr))if (!(snapend - (sizeof(struct in6_addr)) <= snapend &&
(const u_char *)&(p[1+i]) <= snapend - (sizeof(struct
in6_addr)))) goto trunc
;
644 printf(" %s", getname6(p + 1 + i));
645 i += sizeof(struct in6_addr);
646 break;
647 default:
648 printf(" (unknown af)");
649 i = tlen; /*exit loop*/
650 break;
651 }
652 }
653 printf(",");
654 }
655 p += 1 + tlen;
656
657 TCHECK(p[0])if (!(snapend - (sizeof(p[0])) <= snapend && (const
u_char *)&(p[0]) <= snapend - (sizeof(p[0])))) goto trunc
;
658 snpa = p[0];
659 p++;
660 if (snpa) {
661 printf(" %u snpa", snpa);
662 for (/*nothing*/; snpa > 0; snpa--) {
663 TCHECK(p[0])if (!(snapend - (sizeof(p[0])) <= snapend && (const
u_char *)&(p[0]) <= snapend - (sizeof(p[0])))) goto trunc
;
664 printf("(%d bytes)", p[0]);
665 p += p[0] + 1;
666 }
667 printf(",");
668 }
669
670 printf(" NLRI");
671 while (len - (p - dat) > 0) {
672 switch (af) {
673 case AFNUM_INET1:
674 advance = decode_prefix4(p, buf, sizeof(buf));
675 break;
676 case AFNUM_INET62:
677 advance = decode_prefix6(p, buf, sizeof(buf));
678 break;
679 default:
680 printf(" (unknown af)");
681 advance = 0;
682 p = dat + len;
683 break;
684 }
685
686 if (advance <= 0)
687 break;
688
689 printf(" %s", buf);
690 p += advance;
691 }
692
693 break;
694
695 case BGPTYPE_MP_UNREACH_NLRI15:
696 TCHECK2(p[0], BGP_MP_NLRI_MINSIZE)if (!(snapend - (3) <= snapend && (const u_char *)
&(p[0]) <= snapend - (3))) goto trunc
;
697 af = EXTRACT_16BITS(p)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | (u_int16_t
)*((const u_int8_t *)(p) + 1))
;
698 safi = p[2];
699 if (safi >= 128)
700 printf(" %s vendor specific %u,", af_name(af)(((af) == 65535) ? afnumber[0] : num_or_str(afnumber, sizeof(
afnumber)/sizeof(afnumber[0]), (af)))
, safi);
701 else {
702 printf(" %s %s,", af_name(af)(((af) == 65535) ? afnumber[0] : num_or_str(afnumber, sizeof(
afnumber)/sizeof(afnumber[0]), (af)))
,
703 bgp_attr_nlri_safi(safi)num_or_str(bgpattr_nlri_safi, sizeof(bgpattr_nlri_safi)/sizeof
(bgpattr_nlri_safi[0]), (safi))
);
704 }
705 p += 3;
706
707 printf(" Withdraw");
708 while (len - (p - dat) > 0) {
709 switch (af) {
710 case AFNUM_INET1:
711 advance = decode_prefix4(p, buf, sizeof(buf));
712 break;
713 case AFNUM_INET62:
714 advance = decode_prefix6(p, buf, sizeof(buf));
715 break;
716 default:
717 printf(" (unknown af)");
718 advance = 0;
719 p = dat + len;
720 break;
721 }
722
723 if (advance <= 0)
724 break;
725
726 printf(" %s", buf);
727 p += advance;
728 }
729 break;
730 default:
731 break;
732 }
733 return 1;
734
735trunc:
736 return 0;
737}
738
739static void
740bgp_open_capa_print(const u_char *opt, int length)
741{
742 int i,cap_type,cap_len,tcap_len,cap_offset;
743
744 i = 0;
745 while (i < length) {
746 TCHECK2(opt[i], 2)if (!(snapend - (2) <= snapend && (const u_char *)
&(opt[i]) <= snapend - (2))) goto trunc
;
747
748 cap_type=opt[i];
749 cap_len=opt[i+1];
750 printf("%sCAP %s", i == 0 ? "(" : " ", /* ) */
751 bgp_capcode(cap_type)num_or_str(bgp_capcode, sizeof(bgp_capcode)/sizeof(bgp_capcode
[0]), (cap_type))
);
752
753 /* can we print the capability? */
754 TCHECK2(opt[i+2],cap_len)if (!(snapend - (cap_len) <= snapend && (const u_char
*)&(opt[i+2]) <= snapend - (cap_len))) goto trunc
;
755 i += 2;
756
757 switch(cap_type) {
758 case BGP_CAPCODE_MP1:
759 if (cap_len != 4) {
760 printf(" BAD ENCODING");
761 break;
762 }
763 printf(" [%s %s]",
764 af_name(EXTRACT_16BITS(opt+i))(((((u_int16_t)*((const u_int8_t *)(opt+i) + 0) << 8 | (
u_int16_t)*((const u_int8_t *)(opt+i) + 1))) == 65535) ? afnumber
[0] : num_or_str(afnumber, sizeof(afnumber)/sizeof(afnumber[0
]), (((u_int16_t)*((const u_int8_t *)(opt+i) + 0) << 8 |
(u_int16_t)*((const u_int8_t *)(opt+i) + 1)))))
,
765 bgp_attr_nlri_safi(opt[i+3])num_or_str(bgpattr_nlri_safi, sizeof(bgpattr_nlri_safi)/sizeof
(bgpattr_nlri_safi[0]), (opt[i+3]))
);
766 break;
767 case BGP_CAPCODE_REFRESH2:
768 if (cap_len != 0) {
769 printf(" BAD ENCODING");
770 break;
771 }
772 break;
773 case BGP_CAPCODE_RESTART64:
774 if (cap_len < 2 || (cap_len - 2) % 4) {
775 printf(" BAD ENCODING");
776 break;
777 }
778 printf(" [%s], Time %us",
779 ((opt[i])&0x80) ? "R" : "none",
780 EXTRACT_16BITS(opt+i)((u_int16_t)*((const u_int8_t *)(opt+i) + 0) << 8 | (u_int16_t
)*((const u_int8_t *)(opt+i) + 1))
&0xfff);
781 tcap_len=cap_len - 2;
782 cap_offset=2;
783 while(tcap_len>=4) {
784 printf(" (%s %s)%s",
785 af_name(EXTRACT_16BITS(opt+i+cap_offset))(((((u_int16_t)*((const u_int8_t *)(opt+i+cap_offset) + 0) <<
8 | (u_int16_t)*((const u_int8_t *)(opt+i+cap_offset) + 1)))
== 65535) ? afnumber[0] : num_or_str(afnumber, sizeof(afnumber
)/sizeof(afnumber[0]), (((u_int16_t)*((const u_int8_t *)(opt+
i+cap_offset) + 0) << 8 | (u_int16_t)*((const u_int8_t *
)(opt+i+cap_offset) + 1)))))
,
786 bgp_attr_nlri_safi(opt[i+cap_offset+2])num_or_str(bgpattr_nlri_safi, sizeof(bgpattr_nlri_safi)/sizeof
(bgpattr_nlri_safi[0]), (opt[i+cap_offset+2]))
,
787 ((opt[i+cap_offset+3])&0x80) ?
788 " forwarding state preserved" : "" );
789 tcap_len-=4;
790 cap_offset+=4;
791 }
792 break;
793 case BGP_CAPCODE_AS465:
794 if (cap_len != 4) {
795 printf(" BAD ENCODING");
796 break;
797 }
798 printf(" #");
799 if (EXTRACT_16BITS(opt+i)((u_int16_t)*((const u_int8_t *)(opt+i) + 0) << 8 | (u_int16_t
)*((const u_int8_t *)(opt+i) + 1))
)
800 printf("%u.",
801 EXTRACT_16BITS(opt+i)((u_int16_t)*((const u_int8_t *)(opt+i) + 0) << 8 | (u_int16_t
)*((const u_int8_t *)(opt+i) + 1))
);
802 printf("%u",
803 EXTRACT_16BITS(opt+i+2)((u_int16_t)*((const u_int8_t *)(opt+i+2) + 0) << 8 | (
u_int16_t)*((const u_int8_t *)(opt+i+2) + 1))
);
804 break;
805 default:
806 printf(" len %d", cap_len);
807 break;
808 }
809 i += cap_len;
810 if (i + cap_len < length)
811 printf(",");
812 }
813 /* ( */
814 printf(")");
815 return;
816trunc:
817 printf("[|BGP]");
818}
819
820static void
821bgp_open_print(const u_char *dat, int length)
822{
823 struct bgp_open bgpo;
824 struct bgp_opt bgpopt;
825 const u_char *opt;
826 int i;
827
828 TCHECK2(dat[0], BGP_OPEN_SIZE)if (!(snapend - (29) <= snapend && (const u_char *
)&(dat[0]) <= snapend - (29))) goto trunc
;
829 memcpy(&bgpo, dat, BGP_OPEN_SIZE29);
830
831 printf(": Version %d,", bgpo.bgpo_version);
832 printf(" AS #%u,", ntohs(bgpo.bgpo_myas)(__uint16_t)(__builtin_constant_p(bgpo.bgpo_myas) ? (__uint16_t
)(((__uint16_t)(bgpo.bgpo_myas) & 0xffU) << 8 | ((__uint16_t
)(bgpo.bgpo_myas) & 0xff00U) >> 8) : __swap16md(bgpo
.bgpo_myas))
);
833 printf(" Holdtime %u,", ntohs(bgpo.bgpo_holdtime)(__uint16_t)(__builtin_constant_p(bgpo.bgpo_holdtime) ? (__uint16_t
)(((__uint16_t)(bgpo.bgpo_holdtime) & 0xffU) << 8 |
((__uint16_t)(bgpo.bgpo_holdtime) & 0xff00U) >> 8)
: __swap16md(bgpo.bgpo_holdtime))
);
834 printf(" ID %s,", getname((u_char *)&bgpo.bgpo_id));
835 printf(" Option length %u", bgpo.bgpo_optlen);
836
837 /* sanity checking */
838 if ((length < bgpo.bgpo_optlen+BGP_OPEN_SIZE29) || (!bgpo.bgpo_optlen))
839 return;
840
841 /* ugly! */
842 opt = &((const struct bgp_open *)dat)->bgpo_optlen;
843 opt++;
844
845 i = 0;
846 while (i < bgpo.bgpo_optlen) {
847 TCHECK2(opt[i], BGP_OPT_SIZE)if (!(snapend - (2) <= snapend && (const u_char *)
&(opt[i]) <= snapend - (2))) goto trunc
;
848 memcpy(&bgpopt, &opt[i], BGP_OPT_SIZE2);
849 if (i + 2 + bgpopt.bgpopt_len > bgpo.bgpo_optlen) {
850 printf(" [|opt %d %d]", bgpopt.bgpopt_len, bgpopt.bgpopt_type);
851 break;
852 }
853
854 if (i == 0)
855 printf(" ("); /* ) */
856 else
857 printf(" ");
858
859 switch(bgpopt.bgpopt_type) {
860 case BGP_OPT_CAP2:
861 bgp_open_capa_print(opt + i + BGP_OPT_SIZE2,
862 bgpopt.bgpopt_len);
863 break;
864 default:
865 printf(" (option %s, len=%u)",
866 bgp_opttype(bgpopt.bgpopt_type)num_or_str(bgpopt_type, sizeof(bgpopt_type)/sizeof(bgpopt_type
[0]), (bgpopt.bgpopt_type))
,
867 bgpopt.bgpopt_len);
868 break;
869 }
870
871 i += BGP_OPT_SIZE2 + bgpopt.bgpopt_len;
872 }
873 /* ( */
874 printf(")");
875 return;
876trunc:
877 printf("[|BGP]");
878}
879
880static void
881bgp_update_print(const u_char *dat, int length)
882{
883 struct bgp bgp;
884 struct bgp_attr bgpa;
885 const u_char *p;
886 int len;
887 int i;
888 int newline;
889
890 TCHECK2(dat[0], BGP_SIZE)if (!(snapend - (19) <= snapend && (const u_char *
)&(dat[0]) <= snapend - (19))) goto trunc
;
891 memcpy(&bgp, dat, BGP_SIZE19);
892 p = dat + BGP_SIZE19; /*XXX*/
893 printf(":");
894
895 /* Unfeasible routes */
896 len = EXTRACT_16BITS(p)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | (u_int16_t
)*((const u_int8_t *)(p) + 1))
;
897 if (len) {
898 /*
899 * Without keeping state from the original NLRI message,
900 * it's not possible to tell if this a v4 or v6 route,
901 * so do not try to decode it.
902 */
903 printf(" (Withdrawn routes: %d bytes)", len);
904 }
905 p += 2 + len;
906
907 TCHECK2(p[0], 2)if (!(snapend - (2) <= snapend && (const u_char *)
&(p[0]) <= snapend - (2))) goto trunc
;
908 len = EXTRACT_16BITS(p)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | (u_int16_t
)*((const u_int8_t *)(p) + 1))
;
909
910 if (len == 0 && length == BGP_UPDATE_MINSIZE23) {
911 printf(" End-of-Rib Marker (empty NLRI)");
912 return;
913 }
914
915 if (len) {
916 /* do something more useful!*/
917 i = 2;
918 printf(" (Path attributes:"); /* ) */
919 newline = 0;
920 while (i < 2 + len) {
921 int alen, aoff;
922
923 TCHECK2(p[i], sizeof(bgpa))if (!(snapend - (sizeof(bgpa)) <= snapend && (const
u_char *)&(p[i]) <= snapend - (sizeof(bgpa)))) goto trunc
;
924 memcpy(&bgpa, &p[i], sizeof(bgpa));
925 alen = bgp_attr_len(&bgpa)(((&bgpa)->bgpa_flags & 0x10) ? (__uint16_t)(__builtin_constant_p
((&bgpa)->bgpa_len.elen) ? (__uint16_t)(((__uint16_t)(
(&bgpa)->bgpa_len.elen) & 0xffU) << 8 | ((__uint16_t
)((&bgpa)->bgpa_len.elen) & 0xff00U) >> 8) :
__swap16md((&bgpa)->bgpa_len.elen)) : (&bgpa)->
bgpa_len.len)
;
926 aoff = bgp_attr_off(&bgpa)(((&bgpa)->bgpa_flags & 0x10) ? 4 : 3);
927
928 if (vflag && newline)
929 printf("\n\t\t");
930 else
931 printf(" ");
932 printf("("); /* ) */
933 printf("%s", bgp_attr_type(bgpa.bgpa_type)num_or_str(bgpattr_type, sizeof(bgpattr_type)/sizeof(bgpattr_type
[0]), (bgpa.bgpa_type))
);
934 if (bgpa.bgpa_flags) {
935 printf("[%s%s%s%s",
936 bgpa.bgpa_flags & 0x80 ? "O" : "",
937 bgpa.bgpa_flags & 0x40 ? "T" : "",
938 bgpa.bgpa_flags & 0x20 ? "P" : "",
939 bgpa.bgpa_flags & 0x10 ? "E" : "");
940 if (bgpa.bgpa_flags & 0xf)
941 printf("+%x", bgpa.bgpa_flags & 0xf);
942 printf("]");
943 }
944
945 if (!bgp_attr_print(&bgpa, &p[i + aoff], alen))
946 goto trunc;
947 newline = 1;
948
949 /* ( */
950 printf(")");
951
952 i += aoff + alen;
953 }
954
955 /* ( */
956 printf(")");
957 }
958 p += 2 + len;
959
960 if (len && dat + length > p)
961 printf("\n\t\t");
962 if (dat + length > p) {
963 printf("(NLRI:"); /* ) */
964 while (dat + length > p) {
965 char buf[HOST_NAME_MAX255+1 + 100];
966 i = decode_prefix4(p, buf, sizeof(buf));
967 if (i == -1) {
968 printf(" (illegal prefix length)");
969 break;
970 } else if (i == -2)
971 goto trunc;
972 printf(" %s", buf);
973 p += i;
974 }
975
976 /* ( */
977 printf(")");
978 }
979 return;
980trunc:
981 printf("[|BGP]");
982}
983
984static void
985bgp_notification_print(const u_char *dat, int length)
986{
987 struct bgp_notification bgpn;
988 u_int16_t af;
989 u_int8_t safi;
990 const u_char *p;
991 size_t shutdown_comm_length;
992 char shutstring[BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN255 + 1];
993
994 TCHECK2(dat[0], BGP_NOTIFICATION_SIZE)if (!(snapend - (21) <= snapend && (const u_char *
)&(dat[0]) <= snapend - (21))) goto trunc
;
995 memcpy(&bgpn, dat, BGP_NOTIFICATION_SIZE21);
996
997 /* sanity checking */
998 if (length < BGP_NOTIFICATION_SIZE21)
999 return;
1000
1001 printf(": error %s,", bgp_notify_major(bgpn.bgpn_major)num_or_str(bgpnotify_major, sizeof(bgpnotify_major)/sizeof(bgpnotify_major
[0]), (bgpn.bgpn_major))
);
1002 printf(" subcode %s",
1003 bgp_notify_minor(bgpn.bgpn_major, bgpn.bgpn_minor));
1004
1005 if (bgpn.bgpn_major == BGP_NOTIFY_MAJOR_CEASE6) {
1006 /*
1007 * RFC 4486: optional maxprefix subtype of 7 bytes
1008 * may contain AFI, SAFI and MAXPREFIXES
1009 */
1010 if(bgpn.bgpn_minor == BGP_NOTIFY_MINOR_CEASE_MAXPRFX1 &&
1011 length >= BGP_NOTIFICATION_SIZE21 + 7) {
1012
1013 p = dat + BGP_NOTIFICATION_SIZE21;
1014 TCHECK2(*p, 7)if (!(snapend - (7) <= snapend && (const u_char *)
&(*p) <= snapend - (7))) goto trunc
;
1015
1016 af = EXTRACT_16BITS(p)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | (u_int16_t
)*((const u_int8_t *)(p) + 1))
;
1017 safi = p[2];
1018 printf(" %s %s,", af_name(af)(((af) == 65535) ? afnumber[0] : num_or_str(afnumber, sizeof(
afnumber)/sizeof(afnumber[0]), (af)))
,
1019 bgp_attr_nlri_safi(safi)num_or_str(bgpattr_nlri_safi, sizeof(bgpattr_nlri_safi)/sizeof
(bgpattr_nlri_safi[0]), (safi))
);
1020
1021 printf(" Max Prefixes: %u", EXTRACT_32BITS(p+3)((u_int32_t)*((const u_int8_t *)(p+3) + 0) << 24 | (u_int32_t
)*((const u_int8_t *)(p+3) + 1) << 16 | (u_int32_t)*((const
u_int8_t *)(p+3) + 2) << 8 | (u_int32_t)*((const u_int8_t
*)(p+3) + 3))
);
1022 }
1023
1024 /*
1025 * RFC 8203 describes a method to send a message intended
1026 * for human consumption regarding the Administrative
1027 * Shutdown or Reset event. This is called the "Shutdown
1028 * Communication". The communication is UTF-8 encoded
1029 * and may be no longer than 128 bytes.
1030 */
1031 if ((bgpn.bgpn_minor == BGP_NOTIFY_MINOR_CEASE_SHUT2 ||
1032 bgpn.bgpn_minor == BGP_NOTIFY_MINOR_CEASE_RESET4) &&
1033 (length >= BGP_NOTIFICATION_SIZE21 + 1)) {
1034 p = dat + BGP_NOTIFICATION_SIZE21;
1035 TCHECK2(*p, 1)if (!(snapend - (1) <= snapend && (const u_char *)
&(*p) <= snapend - (1))) goto trunc
;
1036 shutdown_comm_length = *p;
1037
1038 /* sanity checking */
1039 if (shutdown_comm_length == 0)
1040 return;
1041 if (shutdown_comm_length >
1042 BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN255)
1043 goto trunc;
1044 if (length < (shutdown_comm_length + 1 +
1045 BGP_NOTIFICATION_SIZE21))
1046 goto trunc;
1047 TCHECK2(*(p+1), shutdown_comm_length)if (!(snapend - (shutdown_comm_length) <= snapend &&
(const u_char *)&(*(p+1)) <= snapend - (shutdown_comm_length
))) goto trunc
;
1048
1049 /* a proper shutdown communication */
1050 printf(", Shutdown Communication [len %zu]: \"",
1051 shutdown_comm_length);
1052 memset(shutstring, 0, sizeof(shutstring));
1053 memcpy(shutstring, p+1, shutdown_comm_length);
1054 safeputs(shutstring);
1055 printf("\"");
1056 }
1057 }
1058
1059 return;
1060
1061trunc:
1062 printf("[|BGP]");
1063}
1064
1065static void
1066bgp_route_refresh_print(const u_char *dat, int length)
1067{
1068 const struct bgp_route_refresh *bgp_route_refresh_header;
1069
1070 TCHECK2(dat[0], BGP_ROUTE_REFRESH_SIZE)if (!(snapend - (23) <= snapend && (const u_char *
)&(dat[0]) <= snapend - (23))) goto trunc
;
1071
1072 /* sanity checking */
1073 if (length<BGP_ROUTE_REFRESH_SIZE23)
1074 return;
1075
1076 bgp_route_refresh_header = (const struct bgp_route_refresh *)dat;
1077
1078 printf(" %s (%s %s)",
1079 refresh_subtype(bgp_route_refresh_header->subtype)num_or_str(refreshtype, sizeof(refreshtype)/sizeof(refreshtype
[0]), (bgp_route_refresh_header->subtype))
,
1080 af_name(EXTRACT_16BITS(&bgp_route_refresh_header->afi))(((((u_int16_t)*((const u_int8_t *)(&bgp_route_refresh_header
->afi) + 0) << 8 | (u_int16_t)*((const u_int8_t *)(&
bgp_route_refresh_header->afi) + 1))) == 65535) ? afnumber
[0] : num_or_str(afnumber, sizeof(afnumber)/sizeof(afnumber[0
]), (((u_int16_t)*((const u_int8_t *)(&bgp_route_refresh_header
->afi) + 0) << 8 | (u_int16_t)*((const u_int8_t *)(&
bgp_route_refresh_header->afi) + 1)))))
,
1081 bgp_attr_nlri_safi(bgp_route_refresh_header->safi)num_or_str(bgpattr_nlri_safi, sizeof(bgpattr_nlri_safi)/sizeof
(bgpattr_nlri_safi[0]), (bgp_route_refresh_header->safi))
);
1082
1083 return;
1084trunc:
1085 printf("[|BGP]");
1086}
1087
1088static int
1089bgp_header_print(const u_char *dat, int length)
1090{
1091 struct bgp bgp;
1092
1093 TCHECK2(dat[0], BGP_SIZE)if (!(snapend - (19) <= snapend && (const u_char *
)&(dat[0]) <= snapend - (19))) goto trunc
;
1094 memcpy(&bgp, dat, BGP_SIZE19);
1095 printf("(%s", bgp_type(bgp.bgp_type)num_or_str(bgptype, sizeof(bgptype)/sizeof(bgptype[0]), (bgp.
bgp_type))
); /* ) */
1096
1097 switch (bgp.bgp_type) {
1098 case BGP_OPEN1:
1099 bgp_open_print(dat, length);
1100 break;
1101 case BGP_UPDATE2:
1102 bgp_update_print(dat, length);
1103 break;
1104 case BGP_NOTIFICATION3:
1105 bgp_notification_print(dat, length);
1106 break;
1107 case BGP_KEEPALIVE4:
1108 break;
1109 case BGP_ROUTE_REFRESH5:
1110 bgp_route_refresh_print(dat, length);
1111 default:
1112 TCHECK2(*dat, length)if (!(snapend - (length) <= snapend && (const u_char
*)&(*dat) <= snapend - (length))) goto trunc
;
1113 break;
1114 }
1115
1116 /* ( */
1117 printf(")");
1118 return 1;
1119trunc:
1120 printf("[|BGP]");
1121 return 0;
1122}
1123
1124void
1125bgp_print(const u_char *dat, int length)
1126{
1127 const u_char *p;
1128 const u_char *ep;
1129 const u_char *start;
1130 const u_char marker[] = {
1131 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1132 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1133 };
1134 struct bgp bgp;
1135 u_int16_t hlen;
1136 int newline;
1137
1138 ep = dat + length;
1139 if (snapend < dat + length)
1140 ep = snapend;
1141
1142 printf(": BGP");
1143
1144 p = dat;
1145 newline = 0;
1146 start = p;
1147 while (p < ep) {
1148 if (!TTEST2(p[0], 1)(snapend - (1) <= snapend && (const u_char *)&
(p[0]) <= snapend - (1))
)
1149 break;
1150 if (p[0] != 0xff) {
1151 p++;
1152 continue;
1153 }
1154
1155 if (!TTEST2(p[0], sizeof(marker))(snapend - (sizeof(marker)) <= snapend && (const u_char
*)&(p[0]) <= snapend - (sizeof(marker)))
)
1156 break;
1157 if (memcmp(p, marker, sizeof(marker)) != 0) {
1158 p++;
1159 continue;
1160 }
1161
1162 /* found BGP header */
1163 TCHECK2(p[0], BGP_SIZE)if (!(snapend - (19) <= snapend && (const u_char *
)&(p[0]) <= snapend - (19))) goto trunc
; /*XXX*/
1164 memcpy(&bgp, p, BGP_SIZE19);
1165
1166 if (start != p)
1167 printf(" [|BGP]");
1168
1169 hlen = ntohs(bgp.bgp_len)(__uint16_t)(__builtin_constant_p(bgp.bgp_len) ? (__uint16_t)
(((__uint16_t)(bgp.bgp_len) & 0xffU) << 8 | ((__uint16_t
)(bgp.bgp_len) & 0xff00U) >> 8) : __swap16md(bgp.bgp_len
))
;
1170 if (vflag && newline)
1171 printf("\n\t");
1172 else
1173 printf(" ");
1174 if (hlen < BGP_SIZE19) {
1175 printf("\n[|BGP Bogus header length %u < %u]",
1176 hlen, BGP_SIZE19);
1177 break;
1178 }
1179 if (TTEST2(p[0], hlen)(snapend - (hlen) <= snapend && (const u_char *)&
(p[0]) <= snapend - (hlen))
) {
1180 if (!bgp_header_print(p, hlen))
1181 return;
1182 newline = 1;
1183 p += hlen;
1184 start = p;
1185 } else {
1186 printf("[|BGP %s]", bgp_type(bgp.bgp_type)num_or_str(bgptype, sizeof(bgptype)/sizeof(bgptype[0]), (bgp.
bgp_type))
);
1187 break;
1188 }
1189 }
1190
1191 return;
1192
1193trunc:
1194 printf(" [|BGP]");
1195}