Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name print-bgp.c -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 -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -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/llvm16/lib/clang/16 -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/llvm16/lib/clang/16/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 -fcf-protection=branch -fno-jump-tables -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/scan/2024-01-11-140451-98009-1 -x c /usr/src/usr.sbin/tcpdump/print-bgp.c
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(*__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 /* RFC8092 */
138#define BGPTYPE_ONLY_TO_CUSTOMER35 35 /* RFC9234 */
139
140#define BGP_AS_SET1 1
141#define BGP_AS_SEQUENCE2 2
142#define BGP_CONFED_AS_SEQUENCE3 3 /* draft-ietf-idr-rfc3065bis-01 */
143#define BGP_CONFED_AS_SET4 4 /* draft-ietf-idr-rfc3065bis-01 */
144
145static struct tok bgp_as_path_segment_open_values[] = {
146 { BGP_AS_SET1, " {" },
147 { BGP_AS_SEQUENCE2, " " },
148 { BGP_CONFED_AS_SEQUENCE3, " (" },
149 { BGP_CONFED_AS_SET4, " ({" },
150 { 0, NULL((void *)0)},
151};
152
153static struct tok bgp_as_path_segment_close_values[] = {
154 { BGP_AS_SET1, "}" },
155 { BGP_AS_SEQUENCE2, "" },
156 { BGP_CONFED_AS_SEQUENCE3, ")" },
157 { BGP_CONFED_AS_SET4, "})" },
158 { 0, NULL((void *)0)},
159};
160
161#define BGP_MP_NLRI_MINSIZE3 3
162
163static const char *bgptype[] = {
164 NULL((void *)0), "OPEN", "UPDATE", "NOTIFICATION", "KEEPALIVE", "ROUTE-REFRESH",
165};
166#define bgp_type(x)num_or_str(bgptype, sizeof(bgptype)/sizeof(bgptype[0]), (x)) num_or_str(bgptype, sizeof(bgptype)/sizeof(bgptype[0]), (x))
167
168static const char *bgpopt_type[] = {
169 NULL((void *)0), "Authentication Information", "Capabilities Advertisement",
170};
171#define bgp_opttype(x)num_or_str(bgpopt_type, sizeof(bgpopt_type)/sizeof(bgpopt_type
[0]), (x))
\
172 num_or_str(bgpopt_type, sizeof(bgpopt_type)/sizeof(bgpopt_type[0]), (x))
173
174#define BGP_CAPCODE_MP1 1
175#define BGP_CAPCODE_REFRESH2 2
176#define BGP_CAPCODE_BGPROLE9 9 /* RFC9234 */
177#define BGP_CAPCODE_RESTART64 64 /* RFC4724 */
178#define BGP_CAPCODE_AS465 65 /* RFC4893 */
179
180static const char *bgp_capcode[] = {
181 NULL((void *)0), "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)num_or_str(bgp_capcode, sizeof(bgp_capcode)/sizeof(bgp_capcode
[0]), (x))
\
199 num_or_str(bgp_capcode, sizeof(bgp_capcode)/sizeof(bgp_capcode[0]), (x))
200
201static const char *bgp_roletype[] = {
202 "Provider", "Route Server", "RS Client", "Customer", "Lateral Peer"
203};
204#define bgp_roletype(x)num_or_str(bgp_roletype, sizeof(bgp_roletype)/sizeof(bgp_roletype
[0]), (x))
\
205 num_or_str(bgp_roletype, \
206 sizeof(bgp_roletype)/sizeof(bgp_roletype[0]), (x))
207
208#define BGP_NOTIFY_MAJOR_CEASE6 6
209static const char *bgpnotify_major[] = {
210 NULL((void *)0), "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)num_or_str(bgpnotify_major, sizeof(bgpnotify_major)/sizeof(bgpnotify_major
[0]), (x))
\
216 num_or_str(bgpnotify_major, \
217 sizeof(bgpnotify_major)/sizeof(bgpnotify_major[0]), (x))
218
219static const char *bgpnotify_minor_msg[] = {
220 NULL((void *)0), "Connection Not Synchronized",
221 "Bad Message Length", "Bad Message Type",
222};
223
224static const char *bgpnotify_minor_open[] = {
225 NULL((void *)0), "Unsupported Version Number",
226 "Bad Peer AS", "Bad BGP Identifier",
227 "Unsupported Optional Parameter", "Authentication Failure",
228 "Unacceptable Hold Time", "Unsupported Capability", NULL((void *)0),
229 NULL((void *)0), NULL((void *)0), "Role Mismatch"
230};
231
232static const char *bgpnotify_minor_update[] = {
233 NULL((void *)0), "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
241static const char *bgpnotify_minor_holdtime[] = {
242 NULL((void *)0),
243};
244
245/* RFC 6608 */
246static 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_MAXPRFX1 1
253/* RFC 8203 */
254#define BGP_NOTIFY_MINOR_CEASE_SHUT2 2
255#define BGP_NOTIFY_MINOR_CEASE_RESET4 4
256#define BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN255 255
257static const char *bgpnotify_minor_cease[] = {
258 NULL((void *)0), "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 */
265static const char *bgpnotify_minor_err[] = {
266 NULL((void *)0), "Invalid Message Length",
267};
268
269static const char **bgpnotify_minor[] = {
270 NULL((void *)0), bgpnotify_minor_msg, bgpnotify_minor_open, bgpnotify_minor_update,
271 bgpnotify_minor_holdtime, bgpnotify_minor_fsm, bgpnotify_minor_cease,
272 bgpnotify_minor_err,
273};
274static 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
285static const char *bgpattr_origin[] = {
286 "IGP", "EGP", "INCOMPLETE",
287};
288#define bgp_attr_origin(x)num_or_str(bgpattr_origin, sizeof(bgpattr_origin)/sizeof(bgpattr_origin
[0]), (x))
\
289 num_or_str(bgpattr_origin, \
290 sizeof(bgpattr_origin)/sizeof(bgpattr_origin[0]), (x))
291
292static const char *bgpattr_type[] = {
293 NULL((void *)0), "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((void *)0), NULL((void *)0), NULL((void *)0),
298 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),
299 "LARGE_COMMUNITIES", NULL((void *)0), NULL((void *)0), "ONLY_TO_CUSTOMER"
300};
301#define bgp_attr_type(x)num_or_str(bgpattr_type, sizeof(bgpattr_type)/sizeof(bgpattr_type
[0]), (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 */
306static 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)num_or_str(bgpattr_nlri_safi, sizeof(bgpattr_nlri_safi)/sizeof
(bgpattr_nlri_safi[0]), (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_EXPORT0xffffff01 0xffffff01
328#define BGP_COMMUNITY_NO_ADVERT0xffffff02 0xffffff02
329#define BGP_COMMUNITY_NO_EXPORT_SUBCONFED0xffffff03 0xffffff03
330#define BGP_COMMUNITY_NO_PEER0xffffff04 0xffffff04
331
332static 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" }
;
333#define af_name(x)(((x) == 65535) ? afnumber[0] : num_or_str(afnumber, sizeof(afnumber
)/sizeof(afnumber[0]), (x)))
\
334 (((x) == 65535) ? afnumber[0] : \
335 num_or_str(afnumber, \
336 sizeof(afnumber)/sizeof(afnumber[0]), (x)))
337
338static const char *refreshtype[] = {
339 "Request", "BoRR", "EoRR"
340};
341#define refresh_subtype(x)num_or_str(refreshtype, sizeof(refreshtype)/sizeof(refreshtype
[0]), (x))
\
342 num_or_str(refreshtype, sizeof(refreshtype)/sizeof(refreshtype[0]), (x))
343
344static const char *
345num_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((void *)0)) {
349 snprintf(buf, sizeof(buf), "#%d", value);
350 return buf;
351 } else
352 return table[value];
353}
354
355static const char *
356bgp_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((void *)0);
372 } else
373 p = NULL((void *)0);
374 if (p == NULL((void *)0)) {
375 snprintf(buf, sizeof(buf), "#%d", minor);
376 return buf;
377 } else
378 return p;
379}
380
381static int
382decode_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])if (!(snapend - (sizeof(pd[0])) <= snapend && (const
u_char *)&(pd[0]) <= snapend - (sizeof(pd[0])))) goto
trunc
;
389 plen = pd[0]; /*
Value stored to 'plen' is never read
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)if (!(snapend - ((plen + 7) / 8) <= snapend && (const
u_char *)&(pd[1]) <= snapend - ((plen + 7) / 8))) goto
trunc
;
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
409trunc:
410 return -2;
411}
412
413static int
414decode_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])if (!(snapend - (sizeof(pd[0])) <= snapend && (const
u_char *)&(pd[0]) <= snapend - (sizeof(pd[0])))) goto
trunc
;
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)if (!(snapend - ((plen + 7) / 8) <= snapend && (const
u_char *)&(pd[1]) <= snapend - ((plen + 7) / 8))) goto
trunc
;
427 memcpy(&addr, &pd[1], (plen + 7) / 8);
428 if (plen % 8) {
429 addr.s6_addr__u6_addr.__u6_addr8[(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
439trunc:
440 return -2;
441}
442
443static int
444bgp_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_MAX255+1 + 100];
453
454 p = dat;
455 tlen = len;
456 asn_bytes = 0;
457
458 switch (attr->bgpa_type) {
459 case BGPTYPE_ORIGIN1:
460 if (len != 1)
461 printf(" invalid len");
462 else {
463 TCHECK(p[0])if (!(snapend - (sizeof(p[0])) <= snapend && (const
u_char *)&(p[0]) <= snapend - (sizeof(p[0])))) goto trunc
;
464 printf(" %s", bgp_attr_origin(p[0])num_or_str(bgpattr_origin, sizeof(bgpattr_origin)/sizeof(bgpattr_origin
[0]), (p[0]))
);
465 }
466 break;
467 case BGPTYPE_AS4_PATH17:
468 asn_bytes = 4;
469 /* FALLTHROUGH */
470 case BGPTYPE_AS_PATH2:
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)if (!(snapend - (2) <= snapend && (const u_char *)
&(p[0]) <= snapend - (2))) goto trunc
;
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)if (!(snapend - (asn_bytes) <= snapend && (const u_char
*)&(p[2 + i]) <= snapend - (asn_bytes))) goto trunc
;
503 printf("%s", i == 0 ? "" : " ");
504 if (asn_bytes == 2)
505 printf("%u", 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))
);
506 else
507 printf("%u", EXTRACT_32BITS(&p[2 + i])((u_int32_t)*((const u_int8_t *)(&p[2 + i]) + 0) <<
24 | (u_int32_t)*((const u_int8_t *)(&p[2 + i]) + 1) <<
16 | (u_int32_t)*((const u_int8_t *)(&p[2 + i]) + 2) <<
8 | (u_int32_t)*((const u_int8_t *)(&p[2 + i]) + 3))
);
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_HOP3:
516 if (len != 4)
517 printf(" invalid len");
518 else {
519 TCHECK2(p[0], 4)if (!(snapend - (4) <= snapend && (const u_char *)
&(p[0]) <= snapend - (4))) goto trunc
;
520 printf(" %s", getname(p));
521 }
522 break;
523 case BGPTYPE_MULTI_EXIT_DISC4:
524 case BGPTYPE_LOCAL_PREF5:
525 if (len != 4)
526 printf(" invalid len");
527 else {
528 TCHECK2(p[0], 4)if (!(snapend - (4) <= snapend && (const u_char *)
&(p[0]) <= snapend - (4))) goto trunc
;
529 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))
);
530 }
531 break;
532 case BGPTYPE_ATOMIC_AGGREGATE6:
533 if (len != 0)
534 printf(" invalid len");
535 break;
536 case BGPTYPE_AGGREGATOR418:
537 case BGPTYPE_AGGREGATOR7:
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)if (!(snapend - (len) <= snapend && (const u_char *
)&(p[0]) <= snapend - (len))) goto trunc
;
548 printf(" AS #");
549 if (len == 6)
550 printf("%u", EXTRACT_16BITS(p)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | (u_int16_t
)*((const u_int8_t *)(p) + 1))
);
551 else
552 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))
);
553 printf(", origin %s", getname(p+len-4));
554 break;
555 case BGPTYPE_COMMUNITIES8:
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)if (!(snapend - (4) <= snapend && (const u_char *)
&(p[0]) <= snapend - (4))) goto trunc
;
563 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))
;
564 switch (comm) {
565 case BGP_COMMUNITY_NO_EXPORT0xffffff01:
566 printf(" NO_EXPORT");
567 break;
568 case BGP_COMMUNITY_NO_ADVERT0xffffff02:
569 printf(" NO_ADVERTISE");
570 break;
571 case BGP_COMMUNITY_NO_EXPORT_SUBCONFED0xffffff03:
572 printf(" NO_EXPORT_SUBCONFED");
573 break;
574 case BGP_COMMUNITY_NO_PEER0xffffff04:
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_COMMUNITIES32:
587 if (len == 0 || len % 12) {
588 printf(" invalid len");
589 break;
590 }
591 while (tlen>0) {
592 TCHECK2(p[0], 12)if (!(snapend - (12) <= snapend && (const u_char *
)&(p[0]) <= snapend - (12))) goto trunc
;
593 printf(" %u:%u:%u",
594 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))
,
595 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))
,
596 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))
);
597 tlen -= 12;
598 p += 12;
599 }
600 break;
601 case BGPTYPE_ONLY_TO_CUSTOMER35:
602 if (len != 4) {
603 printf(" invalid len");
604 break;
605 }
606 TCHECK2(p[0], 4)if (!(snapend - (4) <= snapend && (const u_char *)
&(p[0]) <= snapend - (4))) goto trunc
;
607 printf(" AS%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))
);
608 break;
609 case BGPTYPE_ORIGINATOR_ID9:
610 if (len != 4) {
611 printf(" invalid len");
612 break;
613 }
614 TCHECK2(p[0], 4)if (!(snapend - (4) <= snapend && (const u_char *)
&(p[0]) <= snapend - (4))) goto trunc
;
615 printf("%s",getname(p));
616 break;
617 case BGPTYPE_CLUSTER_LIST10:
618 if (len % 4) {
619 printf(" invalid len");
620 break;
621 }
622 while (tlen>0) {
623 TCHECK2(p[0], 4)if (!(snapend - (4) <= snapend && (const u_char *)
&(p[0]) <= snapend - (4))) goto trunc
;
624 printf(" %s%s",
625 getname(p),
626 (tlen>4) ? ", " : "");
627 tlen -=4;
628 p +=4;
629 }
630 break;
631 case BGPTYPE_MP_REACH_NLRI14:
632 TCHECK2(p[0], BGP_MP_NLRI_MINSIZE)if (!(snapend - (3) <= snapend && (const u_char *)
&(p[0]) <= snapend - (3))) goto trunc
;
633 af = EXTRACT_16BITS(p)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | (u_int16_t
)*((const u_int8_t *)(p) + 1))
;
634 safi = p[2];
635 if (safi >= 128)
636 printf(" %s vendor specific %u,", af_name(af)(((af) == 65535) ? afnumber[0] : num_or_str(afnumber, sizeof(
afnumber)/sizeof(afnumber[0]), (af)))
, safi);
637 else {
638 printf(" %s %s,", af_name(af)(((af) == 65535) ? afnumber[0] : num_or_str(afnumber, sizeof(
afnumber)/sizeof(afnumber[0]), (af)))
,
639 bgp_attr_nlri_safi(safi)num_or_str(bgpattr_nlri_safi, sizeof(bgpattr_nlri_safi)/sizeof
(bgpattr_nlri_safi[0]), (safi))
);
640 }
641 p += 3;
642
643 if (af != AFNUM_INET1 && af != AFNUM_INET62)
644 break;
645
646 TCHECK(p[0])if (!(snapend - (sizeof(p[0])) <= snapend && (const
u_char *)&(p[0]) <= snapend - (sizeof(p[0])))) goto trunc
;
647 tlen = p[0];
648 if (tlen) {
649 printf(" nexthop");
650 i = 0;
651 while (i < tlen) {
652 switch (af) {
653 case AFNUM_INET1:
654 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
;
655 printf(" %s", getname(p + 1 + i));
656 i += sizeof(struct in_addr);
657 break;
658 case AFNUM_INET62:
659 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
;
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])if (!(snapend - (sizeof(p[0])) <= snapend && (const
u_char *)&(p[0]) <= snapend - (sizeof(p[0])))) goto trunc
;
674 snpa = p[0];
675 p++;
676 if (snpa) {
677 printf(" %u snpa", snpa);
678 for (/*nothing*/; snpa > 0; snpa--) {
679 TCHECK(p[0])if (!(snapend - (sizeof(p[0])) <= snapend && (const
u_char *)&(p[0]) <= snapend - (sizeof(p[0])))) goto trunc
;
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_INET1:
690 advance = decode_prefix4(p, buf, sizeof(buf));
691 break;
692 case AFNUM_INET62:
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_NLRI15:
712 TCHECK2(p[0], BGP_MP_NLRI_MINSIZE)if (!(snapend - (3) <= snapend && (const u_char *)
&(p[0]) <= snapend - (3))) goto trunc
;
713 af = EXTRACT_16BITS(p)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | (u_int16_t
)*((const u_int8_t *)(p) + 1))
;
714 safi = p[2];
715 if (safi >= 128)
716 printf(" %s vendor specific %u,", af_name(af)(((af) == 65535) ? afnumber[0] : num_or_str(afnumber, sizeof(
afnumber)/sizeof(afnumber[0]), (af)))
, safi);
717 else {
718 printf(" %s %s,", af_name(af)(((af) == 65535) ? afnumber[0] : num_or_str(afnumber, sizeof(
afnumber)/sizeof(afnumber[0]), (af)))
,
719 bgp_attr_nlri_safi(safi)num_or_str(bgpattr_nlri_safi, sizeof(bgpattr_nlri_safi)/sizeof
(bgpattr_nlri_safi[0]), (safi))
);
720 }
721 p += 3;
722
723 printf(" Withdraw");
724 while (len - (p - dat) > 0) {
725 switch (af) {
726 case AFNUM_INET1:
727 advance = decode_prefix4(p, buf, sizeof(buf));
728 break;
729 case AFNUM_INET62:
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
751trunc:
752 return 0;
753}
754
755static void
756bgp_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)if (!(snapend - (2) <= snapend && (const u_char *)
&(opt[i]) <= snapend - (2))) goto trunc
;
763
764 cap_type=opt[i];
765 cap_len=opt[i+1];
766 printf("%sCAP %s", i == 0 ? "(" : " ", /* ) */
767 bgp_capcode(cap_type)num_or_str(bgp_capcode, sizeof(bgp_capcode)/sizeof(bgp_capcode
[0]), (cap_type))
);
768
769 /* can we print the capability? */
770 TCHECK2(opt[i+2],cap_len)if (!(snapend - (cap_len) <= snapend && (const u_char
*)&(opt[i+2]) <= snapend - (cap_len))) goto trunc
;
771 i += 2;
772
773 switch(cap_type) {
774 case BGP_CAPCODE_MP1:
775 if (cap_len != 4) {
776 printf(" BAD ENCODING");
777 break;
778 }
779 printf(" [%s %s]",
780 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)))))
,
781 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]))
);
782 break;
783 case BGP_CAPCODE_REFRESH2:
784 if (cap_len != 0) {
785 printf(" BAD ENCODING");
786 break;
787 }
788 break;
789 case BGP_CAPCODE_BGPROLE9:
790 if (cap_len != 1) {
791 printf(" BAD ENCODING");
792 break;
793 }
794 printf(" [%s]", bgp_roletype(opt[i])num_or_str(bgp_roletype, sizeof(bgp_roletype)/sizeof(bgp_roletype
[0]), (opt[i]))
);
795 break;
796 case BGP_CAPCODE_RESTART64:
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)((u_int16_t)*((const u_int8_t *)(opt+i) + 0) << 8 | (u_int16_t
)*((const u_int8_t *)(opt+i) + 1))
&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))(((((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)))))
,
809 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]))
,
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_AS465:
817 if (cap_len != 4) {
818 printf(" BAD ENCODING");
819 break;
820 }
821 printf(" #");
822 printf("%u", EXTRACT_32BITS(opt+i)((u_int32_t)*((const u_int8_t *)(opt+i) + 0) << 24 | (u_int32_t
)*((const u_int8_t *)(opt+i) + 1) << 16 | (u_int32_t)*(
(const u_int8_t *)(opt+i) + 2) << 8 | (u_int32_t)*((const
u_int8_t *)(opt+i) + 3))
);
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;
835trunc:
836 printf("[|BGP]");
837}
838
839static void
840bgp_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)if (!(snapend - (29) <= snapend && (const u_char *
)&(dat[0]) <= snapend - (29))) goto trunc
;
848 memcpy(&bgpo, dat, BGP_OPEN_SIZE29);
849
850 printf(": Version %d,", bgpo.bgpo_version);
851 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))
);
852 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))
);
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_SIZE29) || (!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)if (!(snapend - (2) <= snapend && (const u_char *)
&(opt[i]) <= snapend - (2))) goto trunc
;
867 memcpy(&bgpopt, &opt[i], BGP_OPT_SIZE2);
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_CAP2:
880 bgp_open_capa_print(opt + i + BGP_OPT_SIZE2,
881 bgpopt.bgpopt_len);
882 break;
883 default:
884 printf(" (option %s, len=%u)",
885 bgp_opttype(bgpopt.bgpopt_type)num_or_str(bgpopt_type, sizeof(bgpopt_type)/sizeof(bgpopt_type
[0]), (bgpopt.bgpopt_type))
,
886 bgpopt.bgpopt_len);
887 break;
888 }
889
890 i += BGP_OPT_SIZE2 + bgpopt.bgpopt_len;
891 }
892 /* ( */
893 printf(")");
894 return;
895trunc:
896 printf("[|BGP]");
897}
898
899static void
900bgp_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)if (!(snapend - (19) <= snapend && (const u_char *
)&(dat[0]) <= snapend - (19))) goto trunc
;
910 memcpy(&bgp, dat, BGP_SIZE19);
911 p = dat + BGP_SIZE19; /*XXX*/
912 printf(":");
913
914 /* Unfeasible routes */
915 len = EXTRACT_16BITS(p)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | (u_int16_t
)*((const u_int8_t *)(p) + 1))
;
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)if (!(snapend - (2) <= snapend && (const u_char *)
&(p[0]) <= snapend - (2))) goto trunc
;
927 len = EXTRACT_16BITS(p)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | (u_int16_t
)*((const u_int8_t *)(p) + 1))
;
928
929 if (len == 0 && length == BGP_UPDATE_MINSIZE23) {
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))if (!(snapend - (sizeof(bgpa)) <= snapend && (const
u_char *)&(p[i]) <= snapend - (sizeof(bgpa)))) goto trunc
;
943 memcpy(&bgpa, &p[i], sizeof(bgpa));
944 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)
;
945 aoff = bgp_attr_off(&bgpa)(((&bgpa)->bgpa_flags & 0x10) ? 4 : 3);
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)num_or_str(bgpattr_type, sizeof(bgpattr_type)/sizeof(bgpattr_type
[0]), (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_MAX255+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;
999trunc:
1000 printf("[|BGP]");
1001}
1002
1003static void
1004bgp_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_LEN255 + 1];
1012
1013 TCHECK2(dat[0], BGP_NOTIFICATION_SIZE)if (!(snapend - (21) <= snapend && (const u_char *
)&(dat[0]) <= snapend - (21))) goto trunc
;
1014 memcpy(&bgpn, dat, BGP_NOTIFICATION_SIZE21);
1015
1016 /* sanity checking */
1017 if (length < BGP_NOTIFICATION_SIZE21)
1018 return;
1019
1020 printf(": error %s,", bgp_notify_major(bgpn.bgpn_major)num_or_str(bgpnotify_major, sizeof(bgpnotify_major)/sizeof(bgpnotify_major
[0]), (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_CEASE6) {
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_MAXPRFX1 &&
1030 length >= BGP_NOTIFICATION_SIZE21 + 7) {
1031
1032 p = dat + BGP_NOTIFICATION_SIZE21;
1033 TCHECK2(*p, 7)if (!(snapend - (7) <= snapend && (const u_char *)
&(*p) <= snapend - (7))) goto trunc
;
1034
1035 af = EXTRACT_16BITS(p)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | (u_int16_t
)*((const u_int8_t *)(p) + 1))
;
1036 safi = p[2];
1037 printf(" %s %s,", af_name(af)(((af) == 65535) ? afnumber[0] : num_or_str(afnumber, sizeof(
afnumber)/sizeof(afnumber[0]), (af)))
,
1038 bgp_attr_nlri_safi(safi)num_or_str(bgpattr_nlri_safi, sizeof(bgpattr_nlri_safi)/sizeof
(bgpattr_nlri_safi[0]), (safi))
);
1039
1040 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))
);
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_SHUT2 ||
1051 bgpn.bgpn_minor == BGP_NOTIFY_MINOR_CEASE_RESET4) &&
1052 (length >= BGP_NOTIFICATION_SIZE21 + 1)) {
1053 p = dat + BGP_NOTIFICATION_SIZE21;
1054 TCHECK2(*p, 1)if (!(snapend - (1) <= snapend && (const u_char *)
&(*p) <= snapend - (1))) goto trunc
;
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_LEN255)
1062 goto trunc;
1063 if (length < (shutdown_comm_length + 1 +
1064 BGP_NOTIFICATION_SIZE21))
1065 goto trunc;
1066 TCHECK2(*(p+1), shutdown_comm_length)if (!(snapend - (shutdown_comm_length) <= snapend &&
(const u_char *)&(*(p+1)) <= snapend - (shutdown_comm_length
))) goto trunc
;
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
1080trunc:
1081 printf("[|BGP]");
1082}
1083
1084static void
1085bgp_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)if (!(snapend - (23) <= snapend && (const u_char *
)&(dat[0]) <= snapend - (23))) goto trunc
;
1090
1091 /* sanity checking */
1092 if (length<BGP_ROUTE_REFRESH_SIZE23)
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)num_or_str(refreshtype, sizeof(refreshtype)/sizeof(refreshtype
[0]), (bgp_route_refresh_header->subtype))
,
1099 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)))))
,
1100 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))
);
1101
1102 return;
1103trunc:
1104 printf("[|BGP]");
1105}
1106
1107static int
1108bgp_header_print(const u_char *dat, int length)
1109{
1110 struct bgp bgp;
1111
1112 TCHECK2(dat[0], BGP_SIZE)if (!(snapend - (19) <= snapend && (const u_char *
)&(dat[0]) <= snapend - (19))) goto trunc
;
1113 memcpy(&bgp, dat, BGP_SIZE19);
1114 printf("(%s", bgp_type(bgp.bgp_type)num_or_str(bgptype, sizeof(bgptype)/sizeof(bgptype[0]), (bgp.
bgp_type))
); /* ) */
1115
1116 switch (bgp.bgp_type) {
1117 case BGP_OPEN1:
1118 bgp_open_print(dat, length);
1119 break;
1120 case BGP_UPDATE2:
1121 bgp_update_print(dat, length);
1122 break;
1123 case BGP_NOTIFICATION3:
1124 bgp_notification_print(dat, length);
1125 break;
1126 case BGP_KEEPALIVE4:
1127 break;
1128 case BGP_ROUTE_REFRESH5:
1129 bgp_route_refresh_print(dat, length);
1130 default:
1131 TCHECK2(*dat, length)if (!(snapend - (length) <= snapend && (const u_char
*)&(*dat) <= snapend - (length))) goto trunc
;
1132 break;
1133 }
1134
1135 /* ( */
1136 printf(")");
1137 return 1;
1138trunc:
1139 printf("[|BGP]");
1140 return 0;
1141}
1142
1143void
1144bgp_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)(snapend - (1) <= snapend && (const u_char *)&
(p[0]) <= snapend - (1))
)
1168 break;
1169 if (p[0] != 0xff) {
1170 p++;
1171 continue;
1172 }
1173
1174 if (!TTEST2(p[0], sizeof(marker))(snapend - (sizeof(marker)) <= snapend && (const u_char
*)&(p[0]) <= snapend - (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)if (!(snapend - (19) <= snapend && (const u_char *
)&(p[0]) <= snapend - (19))) goto trunc
; /*XXX*/
1183 memcpy(&bgp, p, BGP_SIZE19);
1184
1185 if (start != p)
1186 printf(" [|BGP]");
1187
1188 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
))
;
1189 if (vflag && newline)
1190 printf("\n\t");
1191 else
1192 printf(" ");
1193 if (hlen < BGP_SIZE19) {
1194 printf("\n[|BGP Bogus header length %u < %u]",
1195 hlen, BGP_SIZE19);
1196 break;
1197 }
1198 if (TTEST2(p[0], hlen)(snapend - (hlen) <= snapend && (const u_char *)&
(p[0]) <= snapend - (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)num_or_str(bgptype, sizeof(bgptype)/sizeof(bgptype[0]), (bgp.
bgp_type))
);
1206 break;
1207 }
1208 }
1209
1210 return;
1211
1212trunc:
1213 printf(" [|BGP]");
1214}