Bug Summary

File:src/sbin/route/show.c
Warning:line 162, column 37
Assigned value is garbage or undefined

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 show.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/sbin/route/obj -resource-dir /usr/local/lib/clang/13.0.0 -D BFD -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/sbin/route/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/sbin/route/show.c
1/* $OpenBSD: show.c,v 1.119 2021/01/30 22:00:06 danj Exp $ */
2/* $NetBSD: show.c,v 1.1 1996/11/15 18:01:41 gwr Exp $ */
3
4/*
5 * Copyright (c) 1983, 1988, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#include <sys/socket.h>
34#include <sys/sysctl.h>
35
36#include <net/if.h>
37#include <net/if_dl.h>
38#include <net/if_types.h>
39#include <net/route.h>
40#include <net/rtable.h>
41#include <netinet/in.h>
42#include <netinet/if_ether.h>
43#include <netmpls/mpls.h>
44#include <arpa/inet.h>
45
46#include <err.h>
47#include <errno(*__errno()).h>
48#include <netdb.h>
49#include <stdio.h>
50#include <stddef.h>
51#include <stdlib.h>
52#include <string.h>
53#include <unistd.h>
54#include <limits.h>
55
56#include "show.h"
57
58char *any_ntoa(const struct sockaddr *);
59char *link_print(struct sockaddr *);
60char *label_print(struct sockaddr *);
61
62#define ROUNDUP(a)((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof
(long))
\
63 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
64#define ADVANCE(x, n)(x += (((n)->sa_len) > 0 ? (1 + ((((n)->sa_len) - 1)
| (sizeof(long) - 1))) : sizeof(long)))
(x += ROUNDUP((n)->sa_len)(((n)->sa_len) > 0 ? (1 + ((((n)->sa_len) - 1) | (sizeof
(long) - 1))) : sizeof(long))
)
65
66/*
67 * Definitions for showing gateway flags.
68 */
69struct bits {
70 int b_mask;
71 char b_val;
72};
73static const struct bits bits[] = {
74 { RTF_UP0x1, 'U' },
75 { RTF_GATEWAY0x2, 'G' },
76 { RTF_HOST0x4, 'H' },
77 { RTF_REJECT0x8, 'R' },
78 { RTF_DYNAMIC0x10, 'D' },
79 { RTF_MODIFIED0x20, 'M' },
80 { RTF_DONE0x40, 'd' }, /* Completed -- for routing messages only */
81 { RTF_CLONING0x100, 'C' },
82 { RTF_MULTICAST0x200,'m' },
83 { RTF_LLINFO0x400, 'L' },
84 { RTF_STATIC0x800, 'S' },
85 { RTF_BLACKHOLE0x1000,'B' },
86 { RTF_PROTO30x2000, '3' },
87 { RTF_PROTO20x4000, '2' },
88 { RTF_PROTO10x8000, '1' },
89 { RTF_CLONED0x10000, 'c' },
90 { RTF_CACHED0x20000, 'h' },
91 { RTF_MPATH0x40000, 'P' },
92 { RTF_MPLS0x100000, 'T' },
93 { RTF_LOCAL0x200000, 'l' },
94 { RTF_BFD0x1000000, 'F' },
95 { RTF_BROADCAST0x400000,'b' },
96 { RTF_CONNECTED0x800000,'n' },
97 { 0 }
98};
99
100int WID_DST(int);
101void pr_rthdr(int);
102void p_rtentry(struct rt_msghdr *);
103void pr_family(int);
104void p_sockaddr_mpls(struct sockaddr *, struct sockaddr *, int, int);
105void p_flags(int, char *);
106char *routename4(in_addr_t);
107char *routename6(struct sockaddr_in6 *);
108char *netname4(in_addr_t, struct sockaddr_in *);
109char *netname6(struct sockaddr_in6 *, struct sockaddr_in6 *);
110
111size_t
112get_sysctl(const int *mib, u_int mcnt, char **buf)
113{
114 size_t needed;
115
116 while (1) {
117 if (sysctl(mib, mcnt, NULL((void*)0), &needed, NULL((void*)0), 0) == -1)
118 err(1, "sysctl-estimate");
119 if (needed == 0)
120 break;
121 if ((*buf = realloc(*buf, needed)) == NULL((void*)0))
122 err(1, NULL((void*)0));
123 if (sysctl(mib, mcnt, *buf, &needed, NULL((void*)0), 0) == -1) {
124 if (errno(*__errno()) == ENOMEM12)
125 continue;
126 err(1, "sysctl");
127 }
128 break;
129 }
130
131 return needed;
132}
133
134/*
135 * Print preferred source address
136 */
137void
138printsource(int af, u_int tableid)
139{
140 struct sockaddr *sa;
141 char *buf = NULL((void*)0), *next, *lim = NULL((void*)0);
142 size_t needed;
143 int mib[7], mcnt, size;
1
'size' declared without an initial value
144
145 mib[0] = CTL_NET4;
146 mib[1] = PF_ROUTE17;
147 mib[2] = 0;
148 mib[3] = af;
149 mib[4] = NET_RT_SOURCE7;
150 mib[5] = tableid;
151 mcnt = 6;
152
153 needed = get_sysctl(mib, mcnt, &buf);
154 lim = buf + needed;
155
156 if (pledge("stdio", NULL((void*)0)) == -1)
2
Assuming the condition is false
3
Taking false branch
157 err(1, "pledge");
158
159 printf("Preferred source address set for rdomain %d\n", tableid);
160
161 if (buf) {
4
Assuming 'buf' is non-null
5
Taking true branch
162 for (next = buf; next < lim; next += size) {
6
Loop condition is true. Entering loop body
8
Assigned value is garbage or undefined
163 sa = (struct sockaddr *)next;
164 switch (sa->sa_family) {
7
'Default' branch taken. Execution continues on line 174
165 case AF_INET2:
166 size = sizeof(struct sockaddr_in);
167 printf("IPv4: ");
168 break;
169 case AF_INET624:
170 size = sizeof(struct sockaddr_in6);
171 printf("IPv6: ");
172 break;
173 }
174 p_sockaddr(sa, NULL((void*)0), RTF_HOST0x4, WID_DST(sa->sa_family));
175 printf("\n");
176 }
177 }
178 free(buf);
179
180 exit(0);
181}
182/*
183 * Print routing tables.
184 */
185void
186p_rttables(int af, u_int tableid, char prio)
187{
188 struct rt_msghdr *rtm;
189 char *buf = NULL((void*)0), *next, *lim = NULL((void*)0);
190 size_t needed;
191 int mib[7], mcnt;
192
193 mib[0] = CTL_NET4;
194 mib[1] = PF_ROUTE17;
195 mib[2] = 0;
196 mib[3] = af;
197 mib[4] = NET_RT_DUMP1;
198 mib[5] = prio;
199 mib[6] = tableid;
200 mcnt = 7;
201
202 needed = get_sysctl(mib, mcnt, &buf);
203 lim = buf + needed;
204
205 if (pledge("stdio dns", NULL((void*)0)) == -1)
206 err(1, "pledge");
207
208 printf("Routing tables\n");
209
210 if (buf) {
211 for (next = buf; next < lim; next += rtm->rtm_msglen) {
212 rtm = (struct rt_msghdr *)next;
213 if (rtm->rtm_version != RTM_VERSION5)
214 continue;
215 p_rtentry(rtm);
216 }
217 }
218 free(buf);
219}
220
221/*
222 * column widths; each followed by one space
223 * width of destination/gateway column
224 * strlen("fe80::aaaa:bbbb:cccc:dddd@gif0") == 30, strlen("/128") == 4
225 */
226#define WID_GW(af)((af) == 24 ? 30 : 18) ((af) == AF_INET624 ? 30 : 18)
227
228int
229WID_DST(int af)
230{
231
232 switch (af) {
233 case AF_MPLS33:
234 return 9;
235 case AF_INET624:
236 return 34;
237 default:
238 return 18;
239 }
240}
241
242/*
243 * Print header for routing table columns.
244 */
245void
246pr_rthdr(int af)
247{
248 switch (af) {
249 case PF_KEY30:
250 printf("%-18s %-5s %-18s %-5s %-5s %-22s\n",
251 "Source", "Port", "Destination",
252 "Port", "Proto", "SA(Address/Proto/Type/Direction)");
253 break;
254 case PF_MPLS33:
255 printf("%-9s %-9s %-6s %-18s %-6.6s %5.5s %8.8s %5.5s %4.4s %s\n",
256 "In label", "Out label", "Op", "Gateway",
257 "Flags", "Refs", "Use", "Mtu", "Prio", "Interface");
258 break;
259 default:
260 printf("%-*.*s %-*.*s %-6.6s %5.5s %8.8s %5.5s %4.4s %s",
261 WID_DST(af), WID_DST(af), "Destination",
262 WID_GW(af)((af) == 24 ? 30 : 18), WID_GW(af)((af) == 24 ? 30 : 18), "Gateway",
263 "Flags", "Refs", "Use", "Mtu", "Prio", "Iface");
264 if (verbose)
265 printf(" %s", "Label");
266 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
267 break;
268 }
269}
270
271void
272get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
273{
274 int i;
275
276 for (i = 0; i < RTAX_MAX15; i++) {
277 if (addrs & (1 << i)) {
278 rti_info[i] = sa;
279 sa = (struct sockaddr *)((char *)(sa) +
280 ROUNDUP(sa->sa_len)((sa->sa_len) > 0 ? (1 + (((sa->sa_len) - 1) | (sizeof
(long) - 1))) : sizeof(long))
);
281 } else
282 rti_info[i] = NULL((void*)0);
283 }
284}
285
286/*
287 * Print a routing table entry.
288 */
289void
290p_rtentry(struct rt_msghdr *rtm)
291{
292 static int old_af = -1;
293 struct sockaddr *sa = (struct sockaddr *)((char *)rtm + rtm->rtm_hdrlen);
294 struct sockaddr *mask, *rti_info[RTAX_MAX15];
295 char ifbuf[IF_NAMESIZE16];
296 char *label;
297
298 if (sa->sa_family == AF_KEY30)
299 return;
300
301 get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
302
303 if (Fflag && rti_info[RTAX_GATEWAY1]->sa_family != sa->sa_family) {
304 return;
305 }
306
307 if (strlen(so_label.rtlabel.sr_label)) {
308 if (!rti_info[RTAX_LABEL10])
309 return;
310 label = ((struct sockaddr_rtlabel *)rti_info[RTAX_LABEL10])->
311 sr_label;
312 if (strcmp(label, so_label.rtlabel.sr_label))
313 return;
314 }
315
316 if (old_af != sa->sa_family) {
317 old_af = sa->sa_family;
318 pr_family(sa->sa_family);
319 pr_rthdr(sa->sa_family);
320 }
321
322 mask = rti_info[RTAX_NETMASK2];
323 if ((sa = rti_info[RTAX_DST0]) == NULL((void*)0))
324 return;
325
326 p_sockaddr(sa, mask, rtm->rtm_flags, WID_DST(sa->sa_family));
327 p_sockaddr_mpls(sa, rti_info[RTAX_SRC8], rtm->rtm_mpls,
328 WID_DST(sa->sa_family));
329
330 p_sockaddr(rti_info[RTAX_GATEWAY1], NULL((void*)0), RTF_HOST0x4,
331 WID_GW(sa->sa_family)((sa->sa_family) == 24 ? 30 : 18));
332
333 p_flags(rtm->rtm_flags, "%-6.6s ");
334 printf("%5u %8llu ", rtm->rtm_rmx.rmx_refcnt,
335 rtm->rtm_rmx.rmx_pksent);
336 if (rtm->rtm_rmx.rmx_mtu)
337 printf("%5u ", rtm->rtm_rmx.rmx_mtu);
338 else
339 printf("%5s ", "-");
340 putchar((rtm->rtm_rmx.rmx_locks & RTV_MTU) ? 'L' : ' ')(!__isthreaded ? __sputc((rtm->rtm_rmx.rmx_locks & 0x1
) ? 'L' : ' ', (&__sF[1])) : (putc)((rtm->rtm_rmx.rmx_locks
& 0x1) ? 'L' : ' ', (&__sF[1])))
;
341 printf(" %2d %-5.16s", rtm->rtm_priority,
342 if_indextoname(rtm->rtm_index, ifbuf));
343 if (verbose && rti_info[RTAX_LABEL10])
344 printf(" %s", routename(rti_info[RTAX_LABEL10]));
345 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
346}
347
348/*
349 * Print address family header before a section of the routing table.
350 */
351void
352pr_family(int af)
353{
354 char *afname;
355
356 switch (af) {
357 case AF_INET2:
358 afname = "Internet";
359 break;
360 case AF_INET624:
361 afname = "Internet6";
362 break;
363 case PF_KEY30:
364 afname = "Encap";
365 break;
366 case AF_MPLS33:
367 afname = "MPLS";
368 break;
369 default:
370 afname = NULL((void*)0);
371 break;
372 }
373 if (afname)
374 printf("\n%s:\n", afname);
375 else
376 printf("\nProtocol Family %d:\n", af);
377}
378
379void
380p_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags, int width)
381{
382 char *cp;
383
384 switch (sa->sa_family) {
385 case AF_INET624:
386 {
387 struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa;
388#ifdef __KAME__
389 struct in6_addr *in6 = &sa6->sin6_addr;
390
391 /*
392 * XXX: This is a special workaround for KAME kernels.
393 * sin6_scope_id field of SA should be set in the future.
394 */
395 if ((IN6_IS_ADDR_LINKLOCAL(in6)(((in6)->__u6_addr.__u6_addr8[0] == 0xfe) && (((in6
)->__u6_addr.__u6_addr8[1] & 0xc0) == 0x80))
||
396 IN6_IS_ADDR_MC_LINKLOCAL(in6)(((in6)->__u6_addr.__u6_addr8[0] == 0xff) && (((in6
)->__u6_addr.__u6_addr8[1] & 0x0f) == 0x02))
||
397 IN6_IS_ADDR_MC_INTFACELOCAL(in6)(((in6)->__u6_addr.__u6_addr8[0] == 0xff) && (((in6
)->__u6_addr.__u6_addr8[1] & 0x0f) == 0x01))
) &&
398 sa6->sin6_scope_id == 0) {
399 /* XXX: override is ok? */
400 sa6->sin6_scope_id = (u_int32_t)ntohs(*(u_short *)(__uint16_t)(__builtin_constant_p(*(u_short *) &in6->__u6_addr
.__u6_addr8[2]) ? (__uint16_t)(((__uint16_t)(*(u_short *) &
in6->__u6_addr.__u6_addr8[2]) & 0xffU) << 8 | ((
__uint16_t)(*(u_short *) &in6->__u6_addr.__u6_addr8[2]
) & 0xff00U) >> 8) : __swap16md(*(u_short *) &in6
->__u6_addr.__u6_addr8[2]))
401 &in6->s6_addr[2])(__uint16_t)(__builtin_constant_p(*(u_short *) &in6->__u6_addr
.__u6_addr8[2]) ? (__uint16_t)(((__uint16_t)(*(u_short *) &
in6->__u6_addr.__u6_addr8[2]) & 0xffU) << 8 | ((
__uint16_t)(*(u_short *) &in6->__u6_addr.__u6_addr8[2]
) & 0xff00U) >> 8) : __swap16md(*(u_short *) &in6
->__u6_addr.__u6_addr8[2]))
;
402 *(u_short *)&in6->s6_addr__u6_addr.__u6_addr8[2] = 0;
403 }
404#endif
405 if (flags & RTF_HOST0x4)
406 cp = routename((struct sockaddr *)sa6);
407 else
408 cp = netname((struct sockaddr *)sa6, mask);
409 break;
410 }
411 case AF_MPLS33:
412 return;
413 default:
414 if ((flags & RTF_HOST0x4) || mask == NULL((void*)0))
415 cp = routename(sa);
416 else
417 cp = netname(sa, mask);
418 break;
419 }
420 if (width < 0)
421 printf("%s", cp);
422 else {
423 if (nflag)
424 printf("%-*s ", width, cp);
425 else
426 printf("%-*.*s ", width, width, cp);
427 }
428}
429
430static char line[HOST_NAME_MAX255+1];
431static char domain[HOST_NAME_MAX255+1];
432
433void
434p_sockaddr_mpls(struct sockaddr *in, struct sockaddr *out, int flags, int width)
435{
436 if (in->sa_family != AF_MPLS33)
437 return;
438
439 if (flags & MPLS_OP_POP0x1 || flags == MPLS_OP_LOCAL0x0) {
440 printf("%-*s ", width, label_print(in));
441 printf("%-*s ", width, label_print(NULL((void*)0)));
442 } else {
443 printf("%-*s ", width, label_print(in));
444 printf("%-*s ", width, label_print(out));
445 }
446
447 printf("%-6s ", mpls_op(flags));
448}
449
450void
451p_flags(int f, char *format)
452{
453 char name[33], *flags;
454 const struct bits *p = bits;
455
456 for (flags = name; p->b_mask && flags < &name[sizeof(name) - 2]; p++)
457 if (p->b_mask & f)
458 *flags++ = p->b_val;
459 *flags = '\0';
460 printf(format, name);
461}
462
463char *
464routename(struct sockaddr *sa)
465{
466 char *cp = NULL((void*)0);
467 static int first = 1;
468
469 if (first) {
470 first = 0;
471 if (gethostname(domain, sizeof(domain)) == 0 &&
472 (cp = strchr(domain, '.')))
473 (void)strlcpy(domain, cp + 1, sizeof(domain));
474 else
475 domain[0] = '\0';
476 cp = NULL((void*)0);
477 }
478
479 if (sa->sa_len == 0) {
480 (void)strlcpy(line, "default", sizeof(line));
481 return (line);
482 }
483
484 switch (sa->sa_family) {
485 case AF_INET2:
486 return
487 (routename4(((struct sockaddr_in *)sa)->sin_addr.s_addr));
488
489 case AF_INET624:
490 {
491 struct sockaddr_in6 sin6;
492
493 memset(&sin6, 0, sizeof(sin6));
494 memcpy(&sin6, sa, sa->sa_len);
495 sin6.sin6_len = sizeof(struct sockaddr_in6);
496 sin6.sin6_family = AF_INET624;
497#ifdef __KAME__
498 if (sa->sa_len == sizeof(struct sockaddr_in6) &&
499 (IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr)(((&sin6.sin6_addr)->__u6_addr.__u6_addr8[0] == 0xfe) &&
(((&sin6.sin6_addr)->__u6_addr.__u6_addr8[1] & 0xc0
) == 0x80))
||
500 IN6_IS_ADDR_MC_LINKLOCAL(&sin6.sin6_addr)(((&sin6.sin6_addr)->__u6_addr.__u6_addr8[0] == 0xff) &&
(((&sin6.sin6_addr)->__u6_addr.__u6_addr8[1] & 0x0f
) == 0x02))
||
501 IN6_IS_ADDR_MC_INTFACELOCAL(&sin6.sin6_addr)(((&sin6.sin6_addr)->__u6_addr.__u6_addr8[0] == 0xff) &&
(((&sin6.sin6_addr)->__u6_addr.__u6_addr8[1] & 0x0f
) == 0x01))
) &&
502 sin6.sin6_scope_id == 0) {
503 sin6.sin6_scope_id =
504 ntohs(*(u_int16_t *)&sin6.sin6_addr.s6_addr[2])(__uint16_t)(__builtin_constant_p(*(u_int16_t *)&sin6.sin6_addr
.__u6_addr.__u6_addr8[2]) ? (__uint16_t)(((__uint16_t)(*(u_int16_t
*)&sin6.sin6_addr.__u6_addr.__u6_addr8[2]) & 0xffU) <<
8 | ((__uint16_t)(*(u_int16_t *)&sin6.sin6_addr.__u6_addr
.__u6_addr8[2]) & 0xff00U) >> 8) : __swap16md(*(u_int16_t
*)&sin6.sin6_addr.__u6_addr.__u6_addr8[2]))
;
505 sin6.sin6_addr.s6_addr__u6_addr.__u6_addr8[2] = 0;
506 sin6.sin6_addr.s6_addr__u6_addr.__u6_addr8[3] = 0;
507 }
508#endif
509 return (routename6(&sin6));
510 }
511
512 case AF_LINK18:
513 return (link_print(sa));
514 case AF_MPLS33:
515 return (label_print(sa));
516 case AF_UNSPEC0:
517 if (sa->sa_len == sizeof(struct sockaddr_rtlabel)) {
518 static char name[RTLABEL_LEN32 + 2];
519 struct sockaddr_rtlabel *sr;
520
521 sr = (struct sockaddr_rtlabel *)sa;
522 snprintf(name, sizeof(name), "\"%s\"", sr->sr_label);
523 return (name);
524 }
525 /* FALLTHROUGH */
526 default:
527 (void)snprintf(line, sizeof(line), "(%d) %s",
528 sa->sa_family, any_ntoa(sa));
529 break;
530 }
531 return (line);
532}
533
534char *
535routename4(in_addr_t in)
536{
537 char *cp = NULL((void*)0);
538 struct in_addr ina;
539 struct hostent *hp;
540
541 if (!cp && !nflag) {
542 if ((hp = gethostbyaddr((char *)&in,
543 sizeof(in), AF_INET2)) != NULL((void*)0)) {
544 if ((cp = strchr(hp->h_name, '.')) &&
545 !strcmp(cp + 1, domain))
546 *cp = '\0';
547 cp = hp->h_name;
548 }
549 }
550 ina.s_addr = in;
551 strlcpy(line, cp ? cp : inet_ntoa(ina), sizeof(line));
552
553 return (line);
554}
555
556char *
557routename6(struct sockaddr_in6 *sin6)
558{
559 int niflags = 0;
560
561 if (nflag)
562 niflags |= NI_NUMERICHOST1;
563 else
564 niflags |= NI_NOFQDN4;
565
566 if (getnameinfo((struct sockaddr *)sin6, sin6->sin6_len,
567 line, sizeof(line), NULL((void*)0), 0, niflags) != 0)
568 strncpy(line, "invalid", sizeof(line));
569
570 return (line);
571}
572
573char *
574netname4(in_addr_t in, struct sockaddr_in *maskp)
575{
576 char *cp = NULL((void*)0);
577 struct hostent *hp;
578 in_addr_t mask;
579 int mbits;
580
581 mask = maskp && maskp->sin_len != 0 ? ntohl(maskp->sin_addr.s_addr)(__uint32_t)(__builtin_constant_p(maskp->sin_addr.s_addr) ?
(__uint32_t)(((__uint32_t)(maskp->sin_addr.s_addr) & 0xff
) << 24 | ((__uint32_t)(maskp->sin_addr.s_addr) &
0xff00) << 8 | ((__uint32_t)(maskp->sin_addr.s_addr
) & 0xff0000) >> 8 | ((__uint32_t)(maskp->sin_addr
.s_addr) & 0xff000000) >> 24) : __swap32md(maskp->
sin_addr.s_addr))
: 0;
582 if (!nflag && in != INADDR_ANY((u_int32_t)(0x00000000))) {
583 if ((hp = gethostbyaddr((char *)&in,
584 sizeof(in), AF_INET2)) != NULL((void*)0))
585 cp = hp->h_name;
586 }
587 if (in == INADDR_ANY((u_int32_t)(0x00000000)) && mask == INADDR_ANY((u_int32_t)(0x00000000)))
588 cp = "default";
589 mbits = mask ? 33 - ffs(mask) : 0;
590 in = ntohl(in)(__uint32_t)(__builtin_constant_p(in) ? (__uint32_t)(((__uint32_t
)(in) & 0xff) << 24 | ((__uint32_t)(in) & 0xff00
) << 8 | ((__uint32_t)(in) & 0xff0000) >> 8 |
((__uint32_t)(in) & 0xff000000) >> 24) : __swap32md
(in))
;
591 if (cp)
592 strlcpy(line, cp, sizeof(line));
593#define C(x) ((x) & 0xff)
594 else if (mbits < 9)
595 snprintf(line, sizeof(line), "%u/%d", C(in >> 24), mbits);
596 else if (mbits < 17)
597 snprintf(line, sizeof(line), "%u.%u/%d",
598 C(in >> 24) , C(in >> 16), mbits);
599 else if (mbits < 25)
600 snprintf(line, sizeof(line), "%u.%u.%u/%d",
601 C(in >> 24), C(in >> 16), C(in >> 8), mbits);
602 else
603 snprintf(line, sizeof(line), "%u.%u.%u.%u/%d", C(in >> 24),
604 C(in >> 16), C(in >> 8), C(in), mbits);
605#undef C
606 return (line);
607}
608
609char *
610netname6(struct sockaddr_in6 *sa6, struct sockaddr_in6 *mask)
611{
612 struct sockaddr_in6 sin6;
613 u_char *p;
614 int masklen, final = 0, illegal = 0;
615 int i, lim, flag, error;
616 char hbuf[NI_MAXHOST256];
617
618 sin6 = *sa6;
619
620 flag = 0;
621 masklen = 0;
622 if (mask) {
623 lim = mask->sin6_len - offsetof(struct sockaddr_in6, sin6_addr)__builtin_offsetof(struct sockaddr_in6, sin6_addr);
624 lim = lim < (int)sizeof(struct in6_addr) ?
625 lim : (int)sizeof(struct in6_addr);
626 for (p = (u_char *)&mask->sin6_addr, i = 0; i < lim; p++) {
627 if (final && *p) {
628 illegal++;
629 sin6.sin6_addr.s6_addr__u6_addr.__u6_addr8[i++] = 0x00;
630 continue;
631 }
632
633 switch (*p & 0xff) {
634 case 0xff:
635 masklen += 8;
636 break;
637 case 0xfe:
638 masklen += 7;
639 final++;
640 break;
641 case 0xfc:
642 masklen += 6;
643 final++;
644 break;
645 case 0xf8:
646 masklen += 5;
647 final++;
648 break;
649 case 0xf0:
650 masklen += 4;
651 final++;
652 break;
653 case 0xe0:
654 masklen += 3;
655 final++;
656 break;
657 case 0xc0:
658 masklen += 2;
659 final++;
660 break;
661 case 0x80:
662 masklen += 1;
663 final++;
664 break;
665 case 0x00:
666 final++;
667 break;
668 default:
669 final++;
670 illegal++;
671 break;
672 }
673
674 if (!illegal)
675 sin6.sin6_addr.s6_addr__u6_addr.__u6_addr8[i++] &= *p;
676 else
677 sin6.sin6_addr.s6_addr__u6_addr.__u6_addr8[i++] = 0x00;
678 }
679 while (i < (int)sizeof(struct in6_addr))
680 sin6.sin6_addr.s6_addr__u6_addr.__u6_addr8[i++] = 0x00;
681 } else
682 masklen = 128;
683
684 if (masklen == 0 && IN6_IS_ADDR_UNSPECIFIED(&sin6.sin6_addr)((*(const u_int32_t *)(const void *)(&(&sin6.sin6_addr
)->__u6_addr.__u6_addr8[0]) == 0) && (*(const u_int32_t
*)(const void *)(&(&sin6.sin6_addr)->__u6_addr.__u6_addr8
[4]) == 0) && (*(const u_int32_t *)(const void *)(&
(&sin6.sin6_addr)->__u6_addr.__u6_addr8[8]) == 0) &&
(*(const u_int32_t *)(const void *)(&(&sin6.sin6_addr
)->__u6_addr.__u6_addr8[12]) == 0))
)
685 return ("default");
686
687 if (illegal)
688 warnx("illegal prefixlen");
689
690 if (nflag)
691 flag |= NI_NUMERICHOST1;
692 error = getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
693 hbuf, sizeof(hbuf), NULL((void*)0), 0, flag);
694 if (error)
695 snprintf(hbuf, sizeof(hbuf), "invalid");
696
697 snprintf(line, sizeof(line), "%s/%d", hbuf, masklen);
698 return (line);
699}
700
701/*
702 * Return the name of the network whose address is given.
703 * The address is assumed to be that of a net or subnet, not a host.
704 */
705char *
706netname(struct sockaddr *sa, struct sockaddr *mask)
707{
708 switch (sa->sa_family) {
709 case AF_INET2:
710 return netname4(((struct sockaddr_in *)sa)->sin_addr.s_addr,
711 (struct sockaddr_in *)mask);
712 case AF_INET624:
713 return netname6((struct sockaddr_in6 *)sa,
714 (struct sockaddr_in6 *)mask);
715 case AF_LINK18:
716 return (link_print(sa));
717 case AF_MPLS33:
718 return (label_print(sa));
719 default:
720 snprintf(line, sizeof(line), "af %d: %s",
721 sa->sa_family, any_ntoa(sa));
722 break;
723 }
724 return (line);
725}
726
727static const char hexlist[] = "0123456789abcdef";
728
729char *
730any_ntoa(const struct sockaddr *sa)
731{
732 static char obuf[240];
733 const char *in = sa->sa_data;
734 char *out = obuf;
735 int len = sa->sa_len - offsetof(struct sockaddr, sa_data)__builtin_offsetof(struct sockaddr, sa_data);
736
737 *out++ = 'Q';
738 do {
739 *out++ = hexlist[(*in >> 4) & 15];
740 *out++ = hexlist[(*in++) & 15];
741 *out++ = '.';
742 } while (--len > 0 && (out + 3) < &obuf[sizeof(obuf) - 1]);
743 out[-1] = '\0';
744 return (obuf);
745}
746
747char *
748link_print(struct sockaddr *sa)
749{
750 struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
751 u_char *lla = (u_char *)sdl->sdl_data + sdl->sdl_nlen;
752
753 if (sdl->sdl_nlen == 0 && sdl->sdl_alen == 0 &&
754 sdl->sdl_slen == 0) {
755 (void)snprintf(line, sizeof(line), "link#%d", sdl->sdl_index);
756 return (line);
757 }
758 switch (sdl->sdl_type) {
759 case IFT_ETHER0x06:
760 case IFT_CARP0xf7:
761 return (ether_ntoa((struct ether_addr *)lla));
762 default:
763 return (link_ntoa(sdl));
764 }
765}
766
767char *
768mpls_op(u_int32_t type)
769{
770 switch (type & (MPLS_OP_PUSH0x2 | MPLS_OP_POP0x1 | MPLS_OP_SWAP0x4)) {
771 case MPLS_OP_LOCAL0x0:
772 return ("LOCAL");
773 case MPLS_OP_POP0x1:
774 return ("POP");
775 case MPLS_OP_SWAP0x4:
776 return ("SWAP");
777 case MPLS_OP_PUSH0x2:
778 return ("PUSH");
779 default:
780 return ("?");
781 }
782}
783
784char *
785label_print(struct sockaddr *sa)
786{
787 struct sockaddr_mpls *smpls = (struct sockaddr_mpls *)sa;
788
789 if (smpls)
790 (void)snprintf(line, sizeof(line), "%u",
791 ntohl(smpls->smpls_label)(__uint32_t)(__builtin_constant_p(smpls->smpls_label) ? (__uint32_t
)(((__uint32_t)(smpls->smpls_label) & 0xff) << 24
| ((__uint32_t)(smpls->smpls_label) & 0xff00) <<
8 | ((__uint32_t)(smpls->smpls_label) & 0xff0000) >>
8 | ((__uint32_t)(smpls->smpls_label) & 0xff000000) >>
24) : __swap32md(smpls->smpls_label))
>> MPLS_LABEL_OFFSET12);
792 else
793 (void)snprintf(line, sizeof(line), "-");
794
795 return (line);
796}