Bug Summary

File:src/usr.sbin/bgpd/printconf.c
Warning:line 993, column 17
Use of zero-allocated memory

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 printconf.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/bgpd/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.sbin/bgpd -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/bgpd/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/bgpd/printconf.c
1/* $OpenBSD: printconf.c,v 1.148 2021/09/01 12:39:52 claudio Exp $ */
2
3/*
4 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5 * Copyright (c) 2016 Job Snijders <job@instituut.net>
6 * Copyright (c) 2016 Peter Hessler <phessler@openbsd.org>
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA, PROFITS OR MIND, WHETHER IN
17 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
18 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20
21#include <limits.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25
26#include "bgpd.h"
27#include "session.h"
28#include "rde.h"
29#include "log.h"
30
31void print_prefix(struct filter_prefix *p);
32const char *community_type(struct community *c);
33void print_community(struct community *c);
34void print_origin(u_int8_t);
35void print_set(struct filter_set_head *);
36void print_mainconf(struct bgpd_config *);
37void print_l3vpn_targets(struct filter_set_head *, const char *);
38void print_l3vpn(struct l3vpn *);
39const char *print_af(u_int8_t);
40void print_network(struct network_config *, const char *);
41void print_as_sets(struct as_set_head *);
42void print_prefixsets(struct prefixset_head *);
43void print_originsets(struct prefixset_head *);
44void print_roa(struct roa_tree *);
45void print_rtrs(struct rtr_config_head *);
46void print_peer(struct peer_config *, struct bgpd_config *,
47 const char *);
48const char *print_auth_alg(u_int8_t);
49const char *print_enc_alg(u_int8_t);
50void print_announce(struct peer_config *, const char *);
51void print_as(struct filter_rule *);
52void print_rule(struct bgpd_config *, struct filter_rule *);
53const char *mrt_type(enum mrt_type);
54void print_mrt(struct bgpd_config *, u_int32_t, u_int32_t,
55 const char *, const char *);
56void print_groups(struct bgpd_config *);
57int peer_compare(const void *, const void *);
58
59void
60print_prefix(struct filter_prefix *p)
61{
62 u_int8_t max_len = 0;
63
64 switch (p->addr.aid) {
65 case AID_INET1:
66 case AID_VPN_IPv43:
67 max_len = 32;
68 break;
69 case AID_INET62:
70 case AID_VPN_IPv64:
71 max_len = 128;
72 break;
73 case AID_UNSPEC0:
74 /* no prefix to print */
75 return;
76 }
77
78 printf("%s/%u", log_addr(&p->addr), p->len);
79
80 switch (p->op) {
81 case OP_NONE:
82 break;
83 case OP_NE:
84 printf(" prefixlen != %u", p->len_min);
85 break;
86 case OP_XRANGE:
87 printf(" prefixlen %u >< %u ", p->len_min, p->len_max);
88 break;
89 case OP_RANGE:
90 if (p->len_min == p->len_max && p->len != p->len_min)
91 printf(" prefixlen = %u", p->len_min);
92 else if (p->len == p->len_min && p->len_max == max_len)
93 printf(" or-longer");
94 else if (p->len == p->len_min && p->len != p->len_max)
95 printf(" maxlen %u", p->len_max);
96 else if (p->len_max == max_len)
97 printf(" prefixlen >= %u", p->len_min);
98 else
99 printf(" prefixlen %u - %u", p->len_min, p->len_max);
100 break;
101 default:
102 printf(" prefixlen %u ??? %u", p->len_min, p->len_max);
103 break;
104 }
105}
106
107const char *
108community_type(struct community *c)
109{
110 switch ((u_int8_t)c->flags) {
111 case COMMUNITY_TYPE_BASIC8:
112 return "community";
113 case COMMUNITY_TYPE_LARGE32:
114 return "large-community";
115 case COMMUNITY_TYPE_EXT16:
116 return "ext-community";
117 default:
118 return "???";
119 }
120}
121
122void
123print_community(struct community *c)
124{
125 struct in_addr addr;
126 short type;
127 u_int8_t subtype;
128
129 switch ((u_int8_t)c->flags) {
130 case COMMUNITY_TYPE_BASIC8:
131 switch ((c->flags >> 8) & 0xff) {
132 case COMMUNITY_ANY1:
133 printf("*:");
134 break;
135 case COMMUNITY_NEIGHBOR_AS2:
136 printf("neighbor-as:");
137 break;
138 case COMMUNITY_LOCAL_AS3:
139 printf("local-as:");
140 break;
141 default:
142 printf("%u:", c->data1);
143 break;
144 }
145 switch ((c->flags >> 16) & 0xff) {
146 case COMMUNITY_ANY1:
147 printf("* ");
148 break;
149 case COMMUNITY_NEIGHBOR_AS2:
150 printf("neighbor-as ");
151 break;
152 case COMMUNITY_LOCAL_AS3:
153 printf("local-as ");
154 break;
155 default:
156 printf("%u ", c->data2);
157 break;
158 }
159 break;
160 case COMMUNITY_TYPE_LARGE32:
161 switch ((c->flags >> 8) & 0xff) {
162 case COMMUNITY_ANY1:
163 printf("*:");
164 break;
165 case COMMUNITY_NEIGHBOR_AS2:
166 printf("neighbor-as:");
167 break;
168 case COMMUNITY_LOCAL_AS3:
169 printf("local-as:");
170 break;
171 default:
172 printf("%u:", c->data1);
173 break;
174 }
175 switch ((c->flags >> 16) & 0xff) {
176 case COMMUNITY_ANY1:
177 printf("*:");
178 break;
179 case COMMUNITY_NEIGHBOR_AS2:
180 printf("neighbor-as:");
181 break;
182 case COMMUNITY_LOCAL_AS3:
183 printf("local-as:");
184 break;
185 default:
186 printf("%u:", c->data2);
187 break;
188 }
189 switch ((c->flags >> 24) & 0xff) {
190 case COMMUNITY_ANY1:
191 printf("* ");
192 break;
193 case COMMUNITY_NEIGHBOR_AS2:
194 printf("neighbor-as ");
195 break;
196 case COMMUNITY_LOCAL_AS3:
197 printf("local-as ");
198 break;
199 default:
200 printf("%u ", c->data3);
201 break;
202 }
203 break;
204 case COMMUNITY_TYPE_EXT16:
205 if ((c->flags >> 24 & 0xff) == COMMUNITY_ANY1) {
206 printf("* * ");
207 break;
208 }
209 type = (int32_t)c->data3 >> 8;
210 subtype = c->data3;
211 printf("%s ", log_ext_subtype(type, subtype));
212 if ((c->flags >> 8 & 0xff) == COMMUNITY_ANY1) {
213 printf("* ");
214 break;
215 }
216
217 switch (type) {
218 case EXT_COMMUNITY_TRANS_TWO_AS0x00:
219 case EXT_COMMUNITY_TRANS_FOUR_AS0x02:
220 if ((c->flags >> 8 & 0xff) == COMMUNITY_NEIGHBOR_AS2)
221 printf("neighbor-as:");
222 else if ((c->flags >> 8 & 0xff) == COMMUNITY_LOCAL_AS3)
223 printf("local-as:");
224 else
225 printf("%s:", log_as(c->data1));
226 break;
227 case EXT_COMMUNITY_TRANS_IPV40x01:
228 addr.s_addr = htonl(c->data1)(__uint32_t)(__builtin_constant_p(c->data1) ? (__uint32_t)
(((__uint32_t)(c->data1) & 0xff) << 24 | ((__uint32_t
)(c->data1) & 0xff00) << 8 | ((__uint32_t)(c->
data1) & 0xff0000) >> 8 | ((__uint32_t)(c->data1
) & 0xff000000) >> 24) : __swap32md(c->data1))
;
229 printf("%s:", inet_ntoa(addr));
230 break;
231 }
232
233 switch (type) {
234 case EXT_COMMUNITY_TRANS_TWO_AS0x00:
235 case EXT_COMMUNITY_TRANS_FOUR_AS0x02:
236 case EXT_COMMUNITY_TRANS_IPV40x01:
237 if ((c->flags >> 16 & 0xff) == COMMUNITY_ANY1)
238 printf("* ");
239 else if ((c->flags >> 16 & 0xff) ==
240 COMMUNITY_NEIGHBOR_AS2)
241 printf("neighbor-as ");
242 else if ((c->flags >> 16 & 0xff) == COMMUNITY_LOCAL_AS3)
243 printf("local-as ");
244 else
245 printf("%u ", c->data2);
246 break;
247 case EXT_COMMUNITY_NON_TRANS_OPAQUE0x43:
248 if (subtype == EXT_COMMUNITY_SUBTYPE_OVS0) {
249 switch (c->data2) {
250 case EXT_COMMUNITY_OVS_VALID0:
251 printf("valid ");
252 break;
253 case EXT_COMMUNITY_OVS_NOTFOUND1:
254 printf("not-found ");
255 break;
256 case EXT_COMMUNITY_OVS_INVALID2:
257 printf("invalid ");
258 break;
259 }
260 break;
261 }
262 printf("0x%x%08x ", c->data1 & 0xffff, c->data2);
263 break;
264 case EXT_COMMUNITY_TRANS_OPAQUE0x03:
265 case EXT_COMMUNITY_TRANS_EVPN0x06:
266 default:
267 printf("0x%x%08x ", c->data1 & 0xffff, c->data2);
268 break;
269 }
270 }
271}
272
273void
274print_origin(u_int8_t o)
275{
276 if (o == ORIGIN_IGP0)
277 printf("igp ");
278 else if (o == ORIGIN_EGP1)
279 printf("egp ");
280 else if (o == ORIGIN_INCOMPLETE2)
281 printf("incomplete ");
282 else
283 printf("%u ", o);
284}
285
286void
287print_set(struct filter_set_head *set)
288{
289 struct filter_set *s;
290
291 if (TAILQ_EMPTY(set)(((set)->tqh_first) == ((void*)0)))
292 return;
293
294 printf("set { ");
295 TAILQ_FOREACH(s, set, entry)for((s) = ((set)->tqh_first); (s) != ((void*)0); (s) = ((s
)->entry.tqe_next))
{
296 switch (s->type) {
297 case ACTION_SET_LOCALPREF:
298 printf("localpref %u ", s->action.metric);
299 break;
300 case ACTION_SET_RELATIVE_LOCALPREF:
301 printf("localpref %+d ", s->action.relative);
302 break;
303 case ACTION_SET_MED:
304 printf("metric %u ", s->action.metric);
305 break;
306 case ACTION_SET_RELATIVE_MED:
307 printf("metric %+d ", s->action.relative);
308 break;
309 case ACTION_SET_WEIGHT:
310 printf("weight %u ", s->action.metric);
311 break;
312 case ACTION_SET_RELATIVE_WEIGHT:
313 printf("weight %+d ", s->action.relative);
314 break;
315 case ACTION_SET_NEXTHOP:
316 printf("nexthop %s ", log_addr(&s->action.nexthop));
317 break;
318 case ACTION_SET_NEXTHOP_REJECT:
319 printf("nexthop reject ");
320 break;
321 case ACTION_SET_NEXTHOP_BLACKHOLE:
322 printf("nexthop blackhole ");
323 break;
324 case ACTION_SET_NEXTHOP_NOMODIFY:
325 printf("nexthop no-modify ");
326 break;
327 case ACTION_SET_NEXTHOP_SELF:
328 printf("nexthop self ");
329 break;
330 case ACTION_SET_PREPEND_SELF:
331 printf("prepend-self %u ", s->action.prepend);
332 break;
333 case ACTION_SET_PREPEND_PEER:
334 printf("prepend-neighbor %u ", s->action.prepend);
335 break;
336 case ACTION_SET_AS_OVERRIDE:
337 printf("as-override ");
338 break;
339 case ACTION_DEL_COMMUNITY:
340 printf("%s delete ",
341 community_type(&s->action.community));
342 print_community(&s->action.community);
343 break;
344 case ACTION_SET_COMMUNITY:
345 printf("%s ", community_type(&s->action.community));
346 print_community(&s->action.community);
347 break;
348 case ACTION_PFTABLE:
349 printf("pftable %s ", s->action.pftable);
350 break;
351 case ACTION_RTLABEL:
352 printf("rtlabel %s ", s->action.rtlabel);
353 break;
354 case ACTION_SET_ORIGIN:
355 printf("origin ");
356 print_origin(s->action.origin);
357 break;
358 case ACTION_RTLABEL_ID:
359 case ACTION_PFTABLE_ID:
360 case ACTION_SET_NEXTHOP_REF:
361 /* not possible */
362 printf("king bula saiz: config broken");
363 break;
364 }
365 }
366 printf("}");
367}
368
369void
370print_mainconf(struct bgpd_config *conf)
371{
372 struct in_addr ina;
373 struct listen_addr *la;
374
375 printf("AS %s", log_as(conf->as));
376 if (conf->as > USHRT_MAX(32767 *2 +1) && conf->short_as != AS_TRANS23456)
377 printf(" %u", conf->short_as);
378 ina.s_addr = conf->bgpid;
379 printf("\nrouter-id %s\n", inet_ntoa(ina));
380
381 printf("socket \"%s\"\n", conf->csock);
382 if (conf->rcsock)
383 printf("socket \"%s\" restricted\n", conf->rcsock);
384 if (conf->holdtime != INTERVAL_HOLD90)
385 printf("holdtime %u\n", conf->holdtime);
386 if (conf->min_holdtime != MIN_HOLDTIME3)
387 printf("holdtime min %u\n", conf->min_holdtime);
388 if (conf->connectretry != INTERVAL_CONNECTRETRY120)
389 printf("connect-retry %u\n", conf->connectretry);
390
391 if (conf->flags & BGPD_FLAG_DECISION_ROUTEAGE0x0100)
392 printf("rde route-age evaluate\n");
393 if (conf->flags & BGPD_FLAG_DECISION_MED_ALWAYS0x0400)
394 printf("rde med compare always\n");
395 if (conf->flags & BGPD_FLAG_DECISION_ALL_PATHS0x0800)
396 printf("rde evaluate all\n");
397
398 if (conf->flags & BGPD_FLAG_NO_AS_SET0x1000)
399 printf("reject as-set yes\n");
400
401 if (conf->log & BGPD_LOG_UPDATES0x0001)
402 printf("log updates\n");
403
404 TAILQ_FOREACH(la, conf->listen_addrs, entry)for((la) = ((conf->listen_addrs)->tqh_first); (la) != (
(void*)0); (la) = ((la)->entry.tqe_next))
405 printf("listen on %s\n",
406 log_sockaddr((struct sockaddr *)&la->sa, la->sa_len));
407
408 if (conf->flags & BGPD_FLAG_NEXTHOP_BGP0x0010)
409 printf("nexthop qualify via bgp\n");
410 if (conf->flags & BGPD_FLAG_NEXTHOP_DEFAULT0x0020)
411 printf("nexthop qualify via default\n");
412 if (conf->fib_priority != RTP_BGP48)
413 printf("fib-priority %hhu\n", conf->fib_priority);
414 printf("\n");
415}
416
417void
418print_l3vpn_targets(struct filter_set_head *set, const char *tgt)
419{
420 struct filter_set *s;
421 TAILQ_FOREACH(s, set, entry)for((s) = ((set)->tqh_first); (s) != ((void*)0); (s) = ((s
)->entry.tqe_next))
{
422 printf("\t%s ", tgt);
423 print_community(&s->action.community);
424 printf("\n");
425 }
426}
427
428void
429print_l3vpn(struct l3vpn *vpn)
430{
431 struct network *n;
432
433 printf("vpn \"%s\" on %s {\n", vpn->descr, vpn->ifmpe);
434 printf("\t%s\n", log_rd(vpn->rd));
435
436 print_l3vpn_targets(&vpn->export, "export-target");
437 print_l3vpn_targets(&vpn->import, "import-target");
438
439 if (vpn->flags & F_RIB_NOFIBSYNC0x0008)
440 printf("\tfib-update no\n");
441 else
442 printf("\tfib-update yes\n");
443
444 TAILQ_FOREACH(n, &vpn->net_l, entry)for((n) = ((&vpn->net_l)->tqh_first); (n) != ((void
*)0); (n) = ((n)->entry.tqe_next))
445 print_network(&n->net, "\t");
446
447 printf("}\n");
448}
449
450const char *
451print_af(u_int8_t aid)
452{
453 /*
454 * Hack around the fact that aid2str() will return "IPv4 unicast"
455 * for AID_INET. AID_INET and AID_INET6 need special handling and
456 * the other AID should never end up here (at least for now).
457 */
458 if (aid == AID_INET1)
459 return ("inet");
460 if (aid == AID_INET62)
461 return ("inet6");
462 return (aid2str(aid));
463}
464
465void
466print_network(struct network_config *n, const char *c)
467{
468 switch (n->type) {
469 case NETWORK_STATIC:
470 printf("%snetwork %s static", c, print_af(n->prefix.aid));
471 break;
472 case NETWORK_CONNECTED:
473 printf("%snetwork %s connected", c, print_af(n->prefix.aid));
474 break;
475 case NETWORK_RTLABEL:
476 printf("%snetwork %s rtlabel \"%s\"", c,
477 print_af(n->prefix.aid), rtlabel_id2name(n->rtlabel));
478 break;
479 case NETWORK_PRIORITY:
480 printf("%snetwork %s priority %d", c,
481 print_af(n->prefix.aid), n->priority);
482 break;
483 case NETWORK_PREFIXSET:
484 printf("%snetwork prefix-set %s", c, n->psname);
485 break;
486 default:
487 printf("%snetwork %s/%u", c, log_addr(&n->prefix),
488 n->prefixlen);
489 break;
490 }
491 if (!TAILQ_EMPTY(&n->attrset)(((&n->attrset)->tqh_first) == ((void*)0)))
492 printf(" ");
493 print_set(&n->attrset);
494 printf("\n");
495}
496
497void
498print_as_sets(struct as_set_head *as_sets)
499{
500 struct as_set *aset;
501 u_int32_t *as;
502 size_t i, n;
503 int len;
504
505 SIMPLEQ_FOREACH(aset, as_sets, entry)for((aset) = ((as_sets)->sqh_first); (aset) != ((void*)0);
(aset) = ((aset)->entry.sqe_next))
{
506 printf("as-set \"%s\" {\n\t", aset->name);
507 as = set_get(aset->set, &n);
508 for (i = 0, len = 8; i < n; i++) {
509 if (len > 72) {
510 printf("\n\t");
511 len = 8;
512 }
513 len += printf("%u ", as[i]);
514 }
515 printf("\n}\n\n");
516 }
517}
518
519void
520print_prefixsets(struct prefixset_head *psh)
521{
522 struct prefixset *ps;
523 struct prefixset_item *psi;
524
525 SIMPLEQ_FOREACH(ps, psh, entry)for((ps) = ((psh)->sqh_first); (ps) != ((void*)0); (ps) = (
(ps)->entry.sqe_next))
{
526 int count = 0;
527 printf("prefix-set \"%s\" {", ps->name);
528 RB_FOREACH(psi, prefixset_tree, &ps->psitems)for ((psi) = prefixset_tree_RB_MINMAX(&ps->psitems, -1
); (psi) != ((void*)0); (psi) = prefixset_tree_RB_NEXT(psi))
{
529 if (count++ % 2 == 0)
530 printf("\n\t");
531 else
532 printf(", ");
533 print_prefix(&psi->p);
534 }
535 printf("\n}\n\n");
536 }
537}
538
539void
540print_originsets(struct prefixset_head *psh)
541{
542 struct prefixset *ps;
543 struct roa *roa;
544 struct bgpd_addr addr;
545
546 SIMPLEQ_FOREACH(ps, psh, entry)for((ps) = ((psh)->sqh_first); (ps) != ((void*)0); (ps) = (
(ps)->entry.sqe_next))
{
547 printf("origin-set \"%s\" {", ps->name);
548 RB_FOREACH(roa, roa_tree, &ps->roaitems)for ((roa) = roa_tree_RB_MINMAX(&ps->roaitems, -1); (roa
) != ((void*)0); (roa) = roa_tree_RB_NEXT(roa))
{
549 printf("\n\t");
550 addr.aid = roa->aid;
551 addr.v6ba.v6 = roa->prefix.inet6;
552 printf("%s/%u", log_addr(&addr), roa->prefixlen);
553 if (roa->prefixlen != roa->maxlen)
554 printf(" maxlen %u", roa->maxlen);
555 printf(" source-as %u", roa->asnum);
556 }
557 printf("\n}\n\n");
558 }
559}
560
561void
562print_roa(struct roa_tree *r)
563{
564 struct roa *roa;
565 struct bgpd_addr addr;
566
567 if (RB_EMPTY(r)((r)->rbh_root == ((void*)0)))
568 return;
569
570 printf("roa-set {");
571 RB_FOREACH(roa, roa_tree, r)for ((roa) = roa_tree_RB_MINMAX(r, -1); (roa) != ((void*)0); (
roa) = roa_tree_RB_NEXT(roa))
{
572 printf("\n\t");
573 addr.aid = roa->aid;
574 addr.v6ba.v6 = roa->prefix.inet6;
575 printf("%s/%u", log_addr(&addr), roa->prefixlen);
576 if (roa->prefixlen != roa->maxlen)
577 printf(" maxlen %u", roa->maxlen);
578 printf(" source-as %u", roa->asnum);
579 if (roa->expires != 0)
580 printf(" expires %lld", (long long)roa->expires);
581 }
582 printf("\n}\n\n");
583}
584
585void
586print_rtrs(struct rtr_config_head *rh)
587{
588 struct rtr_config *r;
589
590 SIMPLEQ_FOREACH(r, rh, entry)for((r) = ((rh)->sqh_first); (r) != ((void*)0); (r) = ((r)
->entry.sqe_next))
{
591 printf("rtr %s {\n", log_addr(&r->remote_addr));
592 printf("\tdescr \"%s\"\n", r->descr);
593 printf("\tport %u\n", r->remote_port);
594 if (r->local_addr.aid != AID_UNSPEC0)
595 printf("local-addr %s\n", log_addr(&r->local_addr));
596 printf("}\n\n");
597 }
598}
599
600void
601print_peer(struct peer_config *p, struct bgpd_config *conf, const char *c)
602{
603 char *method;
604 struct in_addr ina;
605
606 if ((p->remote_addr.aid == AID_INET1 && p->remote_masklen != 32) ||
607 (p->remote_addr.aid == AID_INET62 && p->remote_masklen != 128))
608 printf("%sneighbor %s/%u {\n", c, log_addr(&p->remote_addr),
609 p->remote_masklen);
610 else
611 printf("%sneighbor %s {\n", c, log_addr(&p->remote_addr));
612 if (p->descr[0])
613 printf("%s\tdescr \"%s\"\n", c, p->descr);
614 if (p->rib[0])
615 printf("%s\trib \"%s\"\n", c, p->rib);
616 if (p->remote_as)
617 printf("%s\tremote-as %s\n", c, log_as(p->remote_as));
618 if (p->local_as != conf->as) {
619 printf("%s\tlocal-as %s", c, log_as(p->local_as));
620 if (p->local_as > USHRT_MAX(32767 *2 +1) && p->local_short_as != AS_TRANS23456)
621 printf(" %u", p->local_short_as);
622 printf("\n");
623 }
624 if (p->down)
625 printf("%s\tdown\n", c);
626 if (p->distance > 1)
627 printf("%s\tmultihop %u\n", c, p->distance);
628 if (p->passive)
629 printf("%s\tpassive\n", c);
630 if (p->local_addr_v4.aid)
631 printf("%s\tlocal-address %s\n", c,
632 log_addr(&p->local_addr_v4));
633 if (p->local_addr_v6.aid)
634 printf("%s\tlocal-address %s\n", c,
635 log_addr(&p->local_addr_v6));
636 if (p->max_prefix) {
637 printf("%s\tmax-prefix %u", c, p->max_prefix);
638 if (p->max_prefix_restart)
639 printf(" restart %u", p->max_prefix_restart);
640 printf("\n");
641 }
642 if (p->max_out_prefix) {
643 printf("%s\tmax-prefix %u out", c, p->max_out_prefix);
644 if (p->max_out_prefix_restart)
645 printf(" restart %u", p->max_out_prefix_restart);
646 printf("\n");
647 }
648 if (p->holdtime)
649 printf("%s\tholdtime %u\n", c, p->holdtime);
650 if (p->min_holdtime)
651 printf("%s\tholdtime min %u\n", c, p->min_holdtime);
652 if (p->announce_capa == 0)
653 printf("%s\tannounce capabilities no\n", c);
654 if (p->capabilities.refresh == 0)
655 printf("%s\tannounce refresh no\n", c);
656 if (p->capabilities.grestart.restart == 0)
657 printf("%s\tannounce restart no\n", c);
658 if (p->capabilities.as4byte == 0)
659 printf("%s\tannounce as4byte no\n", c);
660 if (p->export_type == EXPORT_NONE)
661 printf("%s\texport none\n", c);
662 else if (p->export_type == EXPORT_DEFAULT_ROUTE)
663 printf("%s\texport default-route\n", c);
664 if (p->enforce_as == ENFORCE_AS_ON)
665 printf("%s\tenforce neighbor-as yes\n", c);
666 else
667 printf("%s\tenforce neighbor-as no\n", c);
668 if (p->enforce_local_as == ENFORCE_AS_ON)
669 printf("%s\tenforce local-as yes\n", c);
670 else
671 printf("%s\tenforce local-as no\n", c);
672 if (p->reflector_client) {
673 if (conf->clusterid == 0)
674 printf("%s\troute-reflector\n", c);
675 else {
676 ina.s_addr = conf->clusterid;
677 printf("%s\troute-reflector %s\n", c,
678 inet_ntoa(ina));
679 }
680 }
681 if (p->demote_group[0])
682 printf("%s\tdemote %s\n", c, p->demote_group);
683 if (p->if_depend[0])
684 printf("%s\tdepend on \"%s\"\n", c, p->if_depend);
685 if (p->flags & PEERFLAG_TRANS_AS0x01)
686 printf("%s\ttransparent-as yes\n", c);
687
688 if (conf->flags & BGPD_FLAG_DECISION_ALL_PATHS0x0800) {
689 if (!(p->flags & PEERFLAG_EVALUATE_ALL0x04))
690 printf("%s\trde evaluate default\n", c);
691 } else {
692 if (p->flags & PEERFLAG_EVALUATE_ALL0x04)
693 printf("%s\trde evaluate all\n", c);
694 }
695
696 if (conf->flags & BGPD_FLAG_NO_AS_SET0x1000) {
697 if (!(p->flags & PEERFLAG_NO_AS_SET0x08))
698 printf("%s\treject as-set no\n", c);
699 } else {
700 if (p->flags & PEERFLAG_NO_AS_SET0x08)
701 printf("%s\treject as-set yes\n", c);
702 }
703
704 if (p->flags & PEERFLAG_LOG_UPDATES0x02)
705 printf("%s\tlog updates\n", c);
706
707 if (p->auth.method == AUTH_MD5SIG)
708 printf("%s\ttcp md5sig\n", c);
709 else if (p->auth.method == AUTH_IPSEC_MANUAL_ESP ||
710 p->auth.method == AUTH_IPSEC_MANUAL_AH) {
711 if (p->auth.method == AUTH_IPSEC_MANUAL_ESP)
712 method = "esp";
713 else
714 method = "ah";
715
716 printf("%s\tipsec %s in spi %u %s XXXXXX", c, method,
717 p->auth.spi_in, print_auth_alg(p->auth.auth_alg_in));
718 if (p->auth.enc_alg_in)
719 printf(" %s XXXXXX", print_enc_alg(p->auth.enc_alg_in));
720 printf("\n");
721
722 printf("%s\tipsec %s out spi %u %s XXXXXX", c, method,
723 p->auth.spi_out, print_auth_alg(p->auth.auth_alg_out));
724 if (p->auth.enc_alg_out)
725 printf(" %s XXXXXX",
726 print_enc_alg(p->auth.enc_alg_out));
727 printf("\n");
728 } else if (p->auth.method == AUTH_IPSEC_IKE_AH)
729 printf("%s\tipsec ah ike\n", c);
730 else if (p->auth.method == AUTH_IPSEC_IKE_ESP)
731 printf("%s\tipsec esp ike\n", c);
732
733 if (p->ttlsec)
734 printf("%s\tttl-security yes\n", c);
735
736 print_announce(p, c);
737
738 print_mrt(conf, p->id, p->groupid, c, "\t");
739
740 printf("%s}\n", c);
741}
742
743const char *
744print_auth_alg(u_int8_t alg)
745{
746 switch (alg) {
747 case SADB_AALG_SHA1HMAC3:
748 return ("sha1");
749 case SADB_AALG_MD5HMAC2:
750 return ("md5");
751 default:
752 return ("???");
753 }
754}
755
756const char *
757print_enc_alg(u_int8_t alg)
758{
759 switch (alg) {
760 case SADB_EALG_3DESCBC3:
761 return ("3des");
762 case SADB_X_EALG_AES12:
763 return ("aes");
764 default:
765 return ("???");
766 }
767}
768
769void
770print_announce(struct peer_config *p, const char *c)
771{
772 u_int8_t aid;
773
774 for (aid = 0; aid < AID_MAX5; aid++)
775 if (p->capabilities.mp[aid])
776 printf("%s\tannounce %s\n", c, aid2str(aid));
777}
778
779void
780print_as(struct filter_rule *r)
781{
782 if (r->match.as.flags & AS_FLAG_AS_SET_NAME0x02) {
783 printf("as-set \"%s\" ", r->match.as.name);
784 return;
785 }
786 switch (r->match.as.op) {
787 case OP_RANGE:
788 printf("%s - ", log_as(r->match.as.as_min));
789 printf("%s ", log_as(r->match.as.as_max));
790 break;
791 case OP_XRANGE:
792 printf("%s >< ", log_as(r->match.as.as_min));
793 printf("%s ", log_as(r->match.as.as_max));
794 break;
795 case OP_NE:
796 printf("!= %s ", log_as(r->match.as.as_min));
797 break;
798 default:
799 printf("%s ", log_as(r->match.as.as_min));
800 break;
801 }
802}
803
804void
805print_rule(struct bgpd_config *conf, struct filter_rule *r)
806{
807 struct peer *p;
808 int i;
809
810 if (r->action == ACTION_ALLOW)
811 printf("allow ");
812 else if (r->action == ACTION_DENY)
813 printf("deny ");
814 else
815 printf("match ");
816 if (r->quick)
817 printf("quick ");
818
819 if (r->rib[0])
820 printf("rib %s ", r->rib);
821
822 if (r->dir == DIR_IN)
823 printf("from ");
824 else if (r->dir == DIR_OUT)
825 printf("to ");
826 else
827 printf("eeeeeeeps. ");
828
829 if (r->peer.peerid) {
830 RB_FOREACH(p, peer_head, &conf->peers)for ((p) = peer_head_RB_MINMAX(&conf->peers, -1); (p) !=
((void*)0); (p) = peer_head_RB_NEXT(p))
831 if (p->conf.id == r->peer.peerid)
832 break;
833 if (p == NULL((void*)0))
834 printf("? ");
835 else
836 printf("%s ", log_addr(&p->conf.remote_addr));
837 } else if (r->peer.groupid) {
838 RB_FOREACH(p, peer_head, &conf->peers)for ((p) = peer_head_RB_MINMAX(&conf->peers, -1); (p) !=
((void*)0); (p) = peer_head_RB_NEXT(p))
839 if (p->conf.groupid == r->peer.groupid)
840 break;
841 if (p == NULL((void*)0))
842 printf("group ? ");
843 else
844 printf("group \"%s\" ", p->conf.group);
845 } else if (r->peer.remote_as) {
846 printf("AS %s ", log_as(r->peer.remote_as));
847 } else if (r->peer.ebgp) {
848 printf("ebgp ");
849 } else if (r->peer.ibgp) {
850 printf("ibgp ");
851 } else
852 printf("any ");
853
854 if (r->match.ovs.is_set) {
855 switch (r->match.ovs.validity) {
856 case ROA_VALID0x2:
857 printf("ovs valid ");
858 break;
859 case ROA_INVALID0x1:
860 printf("ovs invalid ");
861 break;
862 case ROA_NOTFOUND0x0:
863 printf("ovs not-found ");
864 break;
865 default:
866 printf("ovs ??? %d ??? ", r->match.ovs.validity);
867 }
868 }
869
870 if (r->match.prefix.addr.aid != AID_UNSPEC0) {
871 printf("prefix ");
872 print_prefix(&r->match.prefix);
873 printf(" ");
874 }
875
876 if (r->match.prefixset.name[0] != '\0')
877 printf("prefix-set \"%s\" ", r->match.prefixset.name);
878 if (r->match.prefixset.flags & PREFIXSET_FLAG_LONGER0x08)
879 printf("or-longer ");
880
881 if (r->match.originset.name[0] != '\0')
882 printf("origin-set \"%s\" ", r->match.originset.name);
883
884 if (r->match.nexthop.flags) {
885 if (r->match.nexthop.flags == FILTER_NEXTHOP_NEIGHBOR2)
886 printf("nexthop neighbor ");
887 else
888 printf("nexthop %s ", log_addr(&r->match.nexthop.addr));
889 }
890
891 if (r->match.as.type) {
892 if (r->match.as.type == AS_ALL)
893 printf("AS ");
894 else if (r->match.as.type == AS_SOURCE)
895 printf("source-as ");
896 else if (r->match.as.type == AS_TRANSIT)
897 printf("transit-as ");
898 else if (r->match.as.type == AS_PEER)
899 printf("peer-as ");
900 else
901 printf("unfluffy-as ");
902 print_as(r);
903 }
904
905 if (r->match.aslen.type) {
906 printf("%s %u ", r->match.aslen.type == ASLEN_MAX ?
907 "max-as-len" : "max-as-seq", r->match.aslen.aslen);
908 }
909
910 for (i = 0; i < MAX_COMM_MATCH3; i++) {
911 struct community *c = &r->match.community[i];
912 if (c->flags != 0) {
913 printf("%s ", community_type(c));
914 print_community(c);
915 }
916 }
917
918 print_set(&r->set);
919
920 printf("\n");
921}
922
923const char *
924mrt_type(enum mrt_type t)
925{
926 switch (t) {
927 case MRT_NONE:
928 break;
929 case MRT_TABLE_DUMP:
930 return "table";
931 case MRT_TABLE_DUMP_MP:
932 return "table-mp";
933 case MRT_TABLE_DUMP_V2:
934 return "table-v2";
935 case MRT_ALL_IN:
936 return "all in";
937 case MRT_ALL_OUT:
938 return "all out";
939 case MRT_UPDATE_IN:
940 return "updates in";
941 case MRT_UPDATE_OUT:
942 return "updates out";
943 }
944 return "unfluffy MRT";
945}
946
947void
948print_mrt(struct bgpd_config *conf, u_int32_t pid, u_int32_t gid,
949 const char *prep, const char *prep2)
950{
951 struct mrt *m;
952
953 if (conf->mrt == NULL((void*)0))
954 return;
955
956 LIST_FOREACH(m, conf->mrt, entry)for((m) = ((conf->mrt)->lh_first); (m)!= ((void*)0); (m
) = ((m)->entry.le_next))
957 if ((gid != 0 && m->group_id == gid) ||
958 (m->peer_id == pid && m->group_id == gid)) {
959 printf("%s%sdump ", prep, prep2);
960 if (m->rib[0])
961 printf("rib %s ", m->rib);
962 printf("%s \"%s\"", mrt_type(m->type),
963 MRT2MC(m)((struct mrt_config *)(m))->name);
964 if (MRT2MC(m)((struct mrt_config *)(m))->ReopenTimerInterval == 0)
965 printf("\n");
966 else
967 printf(" %d\n", MRT2MC(m)((struct mrt_config *)(m))->ReopenTimerInterval);
968 }
969 if (!LIST_EMPTY(conf->mrt)(((conf->mrt)->lh_first) == ((void*)0)))
970 printf("\n");
971}
972
973void
974print_groups(struct bgpd_config *conf)
975{
976 struct peer_config **peerlist;
977 struct peer *p;
978 u_int peer_cnt, i;
979 u_int32_t prev_groupid;
980 const char *tab = "\t";
981 const char *nada = "";
982 const char *c;
983
984 peer_cnt = 0;
985 RB_FOREACH(p, peer_head, &conf->peers)for ((p) = peer_head_RB_MINMAX(&conf->peers, -1); (p) !=
((void*)0); (p) = peer_head_RB_NEXT(p))
11
Assuming 'p' is equal to null
12
Loop condition is false. Execution continues on line 988
986 peer_cnt++;
987
988 if ((peerlist = calloc(peer_cnt, sizeof(struct peer_config *))) == NULL((void*)0))
13
Memory is allocated
14
Assuming the condition is false
15
Taking false branch
989 fatal("print_groups calloc");
990
991 i = 0;
992 RB_FOREACH(p, peer_head, &conf->peers)for ((p) = peer_head_RB_MINMAX(&conf->peers, -1); (p) !=
((void*)0); (p) = peer_head_RB_NEXT(p))
16
Assuming 'p' is not equal to null
17
Loop condition is true. Entering loop body
993 peerlist[i++] = &p->conf;
18
Use of zero-allocated memory
994
995 qsort(peerlist, peer_cnt, sizeof(struct peer_config *), peer_compare);
996
997 prev_groupid = 0;
998 for (i = 0; i < peer_cnt; i++) {
999 if (peerlist[i]->groupid) {
1000 c = tab;
1001 if (peerlist[i]->groupid != prev_groupid) {
1002 if (prev_groupid)
1003 printf("}\n\n");
1004 printf("group \"%s\" {\n", peerlist[i]->group);
1005 prev_groupid = peerlist[i]->groupid;
1006 }
1007 } else
1008 c = nada;
1009
1010 print_peer(peerlist[i], conf, c);
1011 }
1012
1013 if (prev_groupid)
1014 printf("}\n\n");
1015
1016 free(peerlist);
1017}
1018
1019int
1020peer_compare(const void *aa, const void *bb)
1021{
1022 const struct peer_config * const *a;
1023 const struct peer_config * const *b;
1024
1025 a = aa;
1026 b = bb;
1027
1028 return ((*a)->groupid - (*b)->groupid);
1029}
1030
1031void
1032print_config(struct bgpd_config *conf, struct rib_names *rib_l)
1033{
1034 struct filter_rule *r;
1035 struct network *n;
1036 struct rde_rib *rr;
1037 struct l3vpn *vpn;
1038
1039 print_mainconf(conf);
1040 print_rtrs(&conf->rtrs);
1041 print_roa(&conf->roa);
1042 print_as_sets(&conf->as_sets);
1043 print_prefixsets(&conf->prefixsets);
1044 print_originsets(&conf->originsets);
1045 TAILQ_FOREACH(n, &conf->networks, entry)for((n) = ((&conf->networks)->tqh_first); (n) != ((
void*)0); (n) = ((n)->entry.tqe_next))
1
Assuming 'n' is equal to null
2
Loop condition is false. Execution continues on line 1047
1046 print_network(&n->net, "");
1047 if (!SIMPLEQ_EMPTY(&conf->l3vpns)(((&conf->l3vpns)->sqh_first) == ((void*)0)))
3
Assuming field 'sqh_first' is not equal to null
4
Taking true branch
1048 printf("\n");
1049 SIMPLEQ_FOREACH(vpn, &conf->l3vpns, entry)for((vpn) = ((&conf->l3vpns)->sqh_first); (vpn) != (
(void*)0); (vpn) = ((vpn)->entry.sqe_next))
5
Loop condition is true. Entering loop body
6
Assuming 'vpn' is equal to null
7
Loop condition is false. Execution continues on line 1051
1050 print_l3vpn(vpn);
1051 printf("\n");
1052 SIMPLEQ_FOREACH(rr, rib_l, entry)for((rr) = ((rib_l)->sqh_first); (rr) != ((void*)0); (rr) =
((rr)->entry.sqe_next))
{
8
Assuming 'rr' is equal to null
9
Loop condition is false. Execution continues on line 1062
1053 if (rr->flags & F_RIB_NOEVALUATE0x0002)
1054 printf("rde rib %s no evaluate\n", rr->name);
1055 else if (rr->flags & F_RIB_NOFIB0x0004)
1056 printf("rde rib %s\n", rr->name);
1057 else
1058 printf("rde rib %s rtable %u fib-update %s\n", rr->name,
1059 rr->rtableid, rr->flags & F_RIB_NOFIBSYNC0x0008 ?
1060 "no" : "yes");
1061 }
1062 printf("\n");
1063 print_mrt(conf, 0, 0, "", "");
1064 print_groups(conf);
10
Calling 'print_groups'
1065 TAILQ_FOREACH(r, conf->filters, entry)for((r) = ((conf->filters)->tqh_first); (r) != ((void*)
0); (r) = ((r)->entry.tqe_next))
1066 print_rule(conf, r);
1067}