GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/* $OpenBSD: show.c,v 1.108 2016/12/13 08:40:54 mpi 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 <netinet/in.h> |
||
41 |
#include <netinet/if_ether.h> |
||
42 |
#include <netmpls/mpls.h> |
||
43 |
#include <arpa/inet.h> |
||
44 |
|||
45 |
#include <err.h> |
||
46 |
#include <errno.h> |
||
47 |
#include <netdb.h> |
||
48 |
#include <stdio.h> |
||
49 |
#include <stddef.h> |
||
50 |
#include <stdlib.h> |
||
51 |
#include <string.h> |
||
52 |
#include <unistd.h> |
||
53 |
#include <limits.h> |
||
54 |
|||
55 |
#include "show.h" |
||
56 |
|||
57 |
char *any_ntoa(const struct sockaddr *); |
||
58 |
char *link_print(struct sockaddr *); |
||
59 |
char *label_print(struct sockaddr *); |
||
60 |
|||
61 |
#define ROUNDUP(a) \ |
||
62 |
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) |
||
63 |
#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) |
||
64 |
|||
65 |
/* |
||
66 |
* Definitions for showing gateway flags. |
||
67 |
*/ |
||
68 |
struct bits { |
||
69 |
int b_mask; |
||
70 |
char b_val; |
||
71 |
}; |
||
72 |
static const struct bits bits[] = { |
||
73 |
{ RTF_UP, 'U' }, |
||
74 |
{ RTF_GATEWAY, 'G' }, |
||
75 |
{ RTF_HOST, 'H' }, |
||
76 |
{ RTF_REJECT, 'R' }, |
||
77 |
{ RTF_DYNAMIC, 'D' }, |
||
78 |
{ RTF_MODIFIED, 'M' }, |
||
79 |
{ RTF_DONE, 'd' }, /* Completed -- for routing messages only */ |
||
80 |
{ RTF_CLONING, 'C' }, |
||
81 |
{ RTF_MULTICAST,'m' }, |
||
82 |
{ RTF_LLINFO, 'L' }, |
||
83 |
{ RTF_STATIC, 'S' }, |
||
84 |
{ RTF_BLACKHOLE,'B' }, |
||
85 |
{ RTF_PROTO3, '3' }, |
||
86 |
{ RTF_PROTO2, '2' }, |
||
87 |
{ RTF_PROTO1, '1' }, |
||
88 |
{ RTF_CLONED, 'c' }, |
||
89 |
{ RTF_CACHED, 'h' }, |
||
90 |
{ RTF_MPATH, 'P' }, |
||
91 |
{ RTF_MPLS, 'T' }, |
||
92 |
{ RTF_LOCAL, 'l' }, |
||
93 |
{ RTF_BFD, 'F' }, |
||
94 |
{ RTF_BROADCAST,'b' }, |
||
95 |
{ RTF_CONNECTED,'n' }, |
||
96 |
{ 0 } |
||
97 |
}; |
||
98 |
|||
99 |
int WID_DST(int); |
||
100 |
void pr_rthdr(int); |
||
101 |
void p_rtentry(struct rt_msghdr *); |
||
102 |
void pr_family(int); |
||
103 |
void p_sockaddr_mpls(struct sockaddr *, struct sockaddr *, int, int); |
||
104 |
void p_flags(int, char *); |
||
105 |
char *routename4(in_addr_t); |
||
106 |
char *routename6(struct sockaddr_in6 *); |
||
107 |
char *netname4(in_addr_t, struct sockaddr_in *); |
||
108 |
char *netname6(struct sockaddr_in6 *, struct sockaddr_in6 *); |
||
109 |
|||
110 |
/* |
||
111 |
* Print routing tables. |
||
112 |
*/ |
||
113 |
void |
||
114 |
p_rttables(int af, u_int tableid, int hastable, char prio) |
||
115 |
{ |
||
116 |
struct rt_msghdr *rtm; |
||
117 |
char *buf = NULL, *next, *lim = NULL; |
||
118 |
450 |
size_t needed; |
|
119 |
225 |
int mib[7], mcnt; |
|
120 |
struct sockaddr *sa; |
||
121 |
|||
122 |
225 |
mib[0] = CTL_NET; |
|
123 |
225 |
mib[1] = PF_ROUTE; |
|
124 |
225 |
mib[2] = 0; |
|
125 |
225 |
mib[3] = af; |
|
126 |
225 |
mib[4] = NET_RT_DUMP; |
|
127 |
225 |
mib[5] = prio; |
|
128 |
✓✗ | 225 |
if (hastable) { |
129 |
225 |
mib[6] = tableid; |
|
130 |
mcnt = 7; |
||
131 |
225 |
} else |
|
132 |
mcnt = 6; |
||
133 |
|||
134 |
while (1) { |
||
135 |
✗✓ | 225 |
if (sysctl(mib, mcnt, NULL, &needed, NULL, 0) == -1) |
136 |
err(1, "route-sysctl-estimate"); |
||
137 |
✓✗ | 225 |
if (needed == 0) |
138 |
break; |
||
139 |
✗✓ | 225 |
if ((buf = realloc(buf, needed)) == NULL) |
140 |
err(1, NULL); |
||
141 |
✗✓ | 225 |
if (sysctl(mib, mcnt, buf, &needed, NULL, 0) == -1) { |
142 |
if (errno == ENOMEM) |
||
143 |
continue; |
||
144 |
err(1, "sysctl of routing table"); |
||
145 |
} |
||
146 |
225 |
lim = buf + needed; |
|
147 |
225 |
break; |
|
148 |
} |
||
149 |
|||
150 |
✗✓ | 225 |
if (pledge("stdio rpath dns flock cpath wpath", NULL) == -1) |
151 |
err(1, "pledge"); |
||
152 |
|||
153 |
225 |
printf("Routing tables\n"); |
|
154 |
|||
155 |
✓✗ | 225 |
if (buf) { |
156 |
✓✓ | 3744 |
for (next = buf; next < lim; next += rtm->rtm_msglen) { |
157 |
1647 |
rtm = (struct rt_msghdr *)next; |
|
158 |
✓✗ | 1647 |
if (rtm->rtm_version != RTM_VERSION) |
159 |
continue; |
||
160 |
1647 |
sa = (struct sockaddr *)(next + rtm->rtm_hdrlen); |
|
161 |
1647 |
p_rtentry(rtm); |
|
162 |
1647 |
} |
|
163 |
225 |
free(buf); |
|
164 |
buf = NULL; |
||
165 |
225 |
} |
|
166 |
225 |
} |
|
167 |
|||
168 |
/* |
||
169 |
* column widths; each followed by one space |
||
170 |
* width of destination/gateway column |
||
171 |
* strlen("fe80::aaaa:bbbb:cccc:dddd@gif0") == 30, strlen("/128") == 4 |
||
172 |
*/ |
||
173 |
#define WID_GW(af) ((af) == AF_INET6 ? (nflag ? 30 : 18) : 18) |
||
174 |
|||
175 |
int |
||
176 |
WID_DST(int af) |
||
177 |
{ |
||
178 |
|||
179 |
✓✗ | 7488 |
if (nflag) |
180 |
✗✓✓ | 3744 |
switch (af) { |
181 |
case AF_MPLS: |
||
182 |
return 9; |
||
183 |
case AF_INET6: |
||
184 |
504 |
return 34; |
|
185 |
default: |
||
186 |
3240 |
return 18; |
|
187 |
} |
||
188 |
else |
||
189 |
switch (af) { |
||
190 |
case AF_MPLS: |
||
191 |
return 9; |
||
192 |
default: |
||
193 |
return 18; |
||
194 |
} |
||
195 |
3744 |
} |
|
196 |
|||
197 |
/* |
||
198 |
* Print header for routing table columns. |
||
199 |
*/ |
||
200 |
void |
||
201 |
pr_rthdr(int af) |
||
202 |
{ |
||
203 |
✗✗✓ | 450 |
switch (af) { |
204 |
case PF_KEY: |
||
205 |
printf("%-18s %-5s %-18s %-5s %-5s %-22s\n", |
||
206 |
"Source", "Port", "Destination", |
||
207 |
"Port", "Proto", "SA(Address/Proto/Type/Direction)"); |
||
208 |
break; |
||
209 |
case PF_MPLS: |
||
210 |
printf("%-9s %-9s %-6s %-18s %-6.6s %5.5s %8.8s %5.5s %4.4s %s\n", |
||
211 |
"In label", "Out label", "Op", "Gateway", |
||
212 |
"Flags", "Refs", "Use", "Mtu", "Prio", "Interface"); |
||
213 |
break; |
||
214 |
default: |
||
215 |
225 |
printf("%-*.*s %-*.*s %-6.6s %5.5s %8.8s %5.5s %4.4s %s", |
|
216 |
225 |
WID_DST(af), WID_DST(af), "Destination", |
|
217 |
✓✓✓✓ |
711 |
WID_GW(af), WID_GW(af), "Gateway", |
218 |
"Flags", "Refs", "Use", "Mtu", "Prio", "Iface"); |
||
219 |
✗✓ | 225 |
if (verbose) |
220 |
printf(" %s", "Label"); |
||
221 |
✓✗ | 450 |
putchar('\n'); |
222 |
break; |
||
223 |
} |
||
224 |
225 |
} |
|
225 |
|||
226 |
void |
||
227 |
get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info) |
||
228 |
{ |
||
229 |
int i; |
||
230 |
|||
231 |
✓✓ | 54351 |
for (i = 0; i < RTAX_MAX; i++) { |
232 |
✓✓ | 24705 |
if (addrs & (1 << i)) { |
233 |
8235 |
rti_info[i] = sa; |
|
234 |
16470 |
sa = (struct sockaddr *)((char *)(sa) + |
|
235 |
✓✗ | 24705 |
ROUNDUP(sa->sa_len)); |
236 |
8235 |
} else |
|
237 |
16470 |
rti_info[i] = NULL; |
|
238 |
} |
||
239 |
1647 |
} |
|
240 |
|||
241 |
/* |
||
242 |
* Print a routing table entry. |
||
243 |
*/ |
||
244 |
void |
||
245 |
p_rtentry(struct rt_msghdr *rtm) |
||
246 |
{ |
||
247 |
static int old_af = -1; |
||
248 |
3294 |
struct sockaddr *sa = (struct sockaddr *)((char *)rtm + rtm->rtm_hdrlen); |
|
249 |
1647 |
struct sockaddr *mask, *rti_info[RTAX_MAX]; |
|
250 |
1647 |
char ifbuf[IF_NAMESIZE]; |
|
251 |
char *label; |
||
252 |
|||
253 |
✗✓ | 1647 |
if (sa->sa_family == AF_KEY) |
254 |
return; |
||
255 |
|||
256 |
1647 |
get_rtaddrs(rtm->rtm_addrs, sa, rti_info); |
|
257 |
|||
258 |
✓✓✗✓ |
1800 |
if (Fflag && rti_info[RTAX_GATEWAY]->sa_family != sa->sa_family) { |
259 |
return; |
||
260 |
} |
||
261 |
|||
262 |
✗✓ | 1647 |
if (strlen(so_label.rtlabel.sr_label)) { |
263 |
if (!rti_info[RTAX_LABEL]) |
||
264 |
return; |
||
265 |
label = ((struct sockaddr_rtlabel *)rti_info[RTAX_LABEL])-> |
||
266 |
sr_label; |
||
267 |
if (strcmp(label, so_label.rtlabel.sr_label)) |
||
268 |
return; |
||
269 |
} |
||
270 |
|||
271 |
✓✓ | 1647 |
if (old_af != sa->sa_family) { |
272 |
225 |
old_af = sa->sa_family; |
|
273 |
225 |
pr_family(sa->sa_family); |
|
274 |
225 |
pr_rthdr(sa->sa_family); |
|
275 |
225 |
} |
|
276 |
|||
277 |
1647 |
mask = rti_info[RTAX_NETMASK]; |
|
278 |
✗✓ | 1647 |
if ((sa = rti_info[RTAX_DST]) == NULL) |
279 |
return; |
||
280 |
|||
281 |
1647 |
p_sockaddr(sa, mask, rtm->rtm_flags, WID_DST(sa->sa_family)); |
|
282 |
3294 |
p_sockaddr_mpls(sa, rti_info[RTAX_SRC], rtm->rtm_mpls, |
|
283 |
1647 |
WID_DST(sa->sa_family)); |
|
284 |
|||
285 |
3294 |
p_sockaddr(rti_info[RTAX_GATEWAY], NULL, RTF_HOST, |
|
286 |
✓✓ | 3528 |
WID_GW(sa->sa_family)); |
287 |
|||
288 |
1647 |
p_flags(rtm->rtm_flags, "%-6.6s "); |
|
289 |
3294 |
printf("%5u %8llu ", rtm->rtm_rmx.rmx_refcnt, |
|
290 |
1647 |
rtm->rtm_rmx.rmx_pksent); |
|
291 |
✓✓ | 1647 |
if (rtm->rtm_rmx.rmx_mtu) |
292 |
1539 |
printf("%5u ", rtm->rtm_rmx.rmx_mtu); |
|
293 |
else |
||
294 |
108 |
printf("%5s ", "-"); |
|
295 |
✓✗ | 3294 |
putchar((rtm->rtm_rmx.rmx_locks & RTV_MTU) ? 'L' : ' '); |
296 |
3294 |
printf(" %2d %-5.16s", rtm->rtm_priority, |
|
297 |
1647 |
if_indextoname(rtm->rtm_index, ifbuf)); |
|
298 |
✗✓✗✗ |
1647 |
if (verbose && rti_info[RTAX_LABEL]) |
299 |
printf(" %s", routename(rti_info[RTAX_LABEL])); |
||
300 |
✓✗ | 3294 |
putchar('\n'); |
301 |
3294 |
} |
|
302 |
|||
303 |
/* |
||
304 |
* Print address family header before a section of the routing table. |
||
305 |
*/ |
||
306 |
void |
||
307 |
pr_family(int af) |
||
308 |
{ |
||
309 |
char *afname; |
||
310 |
|||
311 |
✓✓✗✗ ✗ |
450 |
switch (af) { |
312 |
case AF_INET: |
||
313 |
afname = "Internet"; |
||
314 |
207 |
break; |
|
315 |
case AF_INET6: |
||
316 |
afname = "Internet6"; |
||
317 |
18 |
break; |
|
318 |
case PF_KEY: |
||
319 |
afname = "Encap"; |
||
320 |
break; |
||
321 |
case AF_MPLS: |
||
322 |
afname = "MPLS"; |
||
323 |
break; |
||
324 |
default: |
||
325 |
afname = NULL; |
||
326 |
break; |
||
327 |
} |
||
328 |
✓✗ | 225 |
if (afname) |
329 |
225 |
printf("\n%s:\n", afname); |
|
330 |
else |
||
331 |
printf("\nProtocol Family %d:\n", af); |
||
332 |
225 |
} |
|
333 |
|||
334 |
void |
||
335 |
p_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags, int width) |
||
336 |
{ |
||
337 |
char *cp; |
||
338 |
|||
339 |
✓✗✓ | 6588 |
switch (sa->sa_family) { |
340 |
case AF_INET6: |
||
341 |
{ |
||
342 |
468 |
struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa; |
|
343 |
468 |
struct in6_addr *in6 = &sa6->sin6_addr; |
|
344 |
|||
345 |
/* |
||
346 |
* XXX: This is a special workaround for KAME kernels. |
||
347 |
* sin6_scope_id field of SA should be set in the future. |
||
348 |
*/ |
||
349 |
✓✓✗✓ ✓✗ |
630 |
if (IN6_IS_ADDR_LINKLOCAL(in6) || |
350 |
✓✓✓✓ |
468 |
IN6_IS_ADDR_MC_LINKLOCAL(in6) || |
351 |
✓✓ | 360 |
IN6_IS_ADDR_MC_INTFACELOCAL(in6)) { |
352 |
/* XXX: override is ok? */ |
||
353 |
216 |
sa6->sin6_scope_id = (u_int32_t)ntohs(*(u_short *) |
|
354 |
&in6->s6_addr[2]); |
||
355 |
216 |
*(u_short *)&in6->s6_addr[2] = 0; |
|
356 |
216 |
} |
|
357 |
✓✓ | 468 |
if (flags & RTF_HOST) |
358 |
360 |
cp = routename((struct sockaddr *)sa6); |
|
359 |
else |
||
360 |
108 |
cp = netname((struct sockaddr *)sa6, mask); |
|
361 |
break; |
||
362 |
} |
||
363 |
case AF_MPLS: |
||
364 |
return; |
||
365 |
default: |
||
366 |
✓✓ | 2826 |
if ((flags & RTF_HOST) || mask == NULL) |
367 |
2313 |
cp = routename(sa); |
|
368 |
else |
||
369 |
513 |
cp = netname(sa, mask); |
|
370 |
break; |
||
371 |
} |
||
372 |
✗✓ | 3294 |
if (width < 0) |
373 |
printf("%s", cp); |
||
374 |
else { |
||
375 |
✓✗ | 3294 |
if (nflag) |
376 |
3294 |
printf("%-*s ", width, cp); |
|
377 |
else |
||
378 |
printf("%-*.*s ", width, width, cp); |
||
379 |
} |
||
380 |
6588 |
} |
|
381 |
|||
382 |
static char line[HOST_NAME_MAX+1]; |
||
383 |
static char domain[HOST_NAME_MAX+1]; |
||
384 |
|||
385 |
void |
||
386 |
p_sockaddr_mpls(struct sockaddr *in, struct sockaddr *out, int flags, int width) |
||
387 |
{ |
||
388 |
✗✓ | 3294 |
if (in->sa_family != AF_MPLS) |
389 |
return; |
||
390 |
|||
391 |
if (flags & MPLS_OP_POP || flags == MPLS_OP_LOCAL) { |
||
392 |
printf("%-*s ", width, label_print(in)); |
||
393 |
printf("%-*s ", width, label_print(NULL)); |
||
394 |
} else { |
||
395 |
printf("%-*s ", width, label_print(in)); |
||
396 |
printf("%-*s ", width, label_print(out)); |
||
397 |
} |
||
398 |
|||
399 |
printf("%-6s ", mpls_op(flags)); |
||
400 |
1647 |
} |
|
401 |
|||
402 |
void |
||
403 |
p_flags(int f, char *format) |
||
404 |
{ |
||
405 |
3294 |
char name[33], *flags; |
|
406 |
const struct bits *p = bits; |
||
407 |
|||
408 |
✓✓ | 79056 |
for (flags = name; p->b_mask && flags < &name[sizeof(name) - 2]; p++) |
409 |
✓✓ | 37881 |
if (p->b_mask & f) |
410 |
5355 |
*flags++ = p->b_val; |
|
411 |
1647 |
*flags = '\0'; |
|
412 |
1647 |
printf(format, name); |
|
413 |
1647 |
} |
|
414 |
|||
415 |
char * |
||
416 |
routename(struct sockaddr *sa) |
||
417 |
{ |
||
418 |
char *cp = NULL; |
||
419 |
static int first = 1; |
||
420 |
|||
421 |
✓✓ | 5436 |
if (first) { |
422 |
234 |
first = 0; |
|
423 |
✓✗✓✗ |
468 |
if (gethostname(domain, sizeof(domain)) == 0 && |
424 |
234 |
(cp = strchr(domain, '.'))) |
|
425 |
234 |
(void)strlcpy(domain, cp + 1, sizeof(domain)); |
|
426 |
else |
||
427 |
domain[0] = '\0'; |
||
428 |
cp = NULL; |
||
429 |
234 |
} |
|
430 |
|||
431 |
✗✓ | 2718 |
if (sa->sa_len == 0) { |
432 |
(void)strlcpy(line, "default", sizeof(line)); |
||
433 |
return (line); |
||
434 |
} |
||
435 |
|||
436 |
✓✓✓✗ ✗✗ |
2718 |
switch (sa->sa_family) { |
437 |
case AF_INET: |
||
438 |
2277 |
return |
|
439 |
2277 |
(routename4(((struct sockaddr_in *)sa)->sin_addr.s_addr)); |
|
440 |
|||
441 |
case AF_INET6: |
||
442 |
{ |
||
443 |
405 |
struct sockaddr_in6 sin6; |
|
444 |
|||
445 |
405 |
memset(&sin6, 0, sizeof(sin6)); |
|
446 |
405 |
memcpy(&sin6, sa, sa->sa_len); |
|
447 |
405 |
sin6.sin6_len = sizeof(struct sockaddr_in6); |
|
448 |
405 |
sin6.sin6_family = AF_INET6; |
|
449 |
✓✗✗✓ |
513 |
if (sa->sa_len == sizeof(struct sockaddr_in6) && |
450 |
✓✓✗✓ |
513 |
(IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr) || |
451 |
✓✓✓✗ |
306 |
IN6_IS_ADDR_MC_LINKLOCAL(&sin6.sin6_addr) || |
452 |
✓✓✗✓ |
306 |
IN6_IS_ADDR_MC_INTFACELOCAL(&sin6.sin6_addr)) && |
453 |
108 |
sin6.sin6_scope_id == 0) { |
|
454 |
sin6.sin6_scope_id = |
||
455 |
ntohs(*(u_int16_t *)&sin6.sin6_addr.s6_addr[2]); |
||
456 |
sin6.sin6_addr.s6_addr[2] = 0; |
||
457 |
sin6.sin6_addr.s6_addr[3] = 0; |
||
458 |
} |
||
459 |
405 |
return (routename6(&sin6)); |
|
460 |
405 |
} |
|
461 |
|||
462 |
case AF_LINK: |
||
463 |
36 |
return (link_print(sa)); |
|
464 |
case AF_MPLS: |
||
465 |
return (label_print(sa)); |
||
466 |
case AF_UNSPEC: |
||
467 |
if (sa->sa_len == sizeof(struct sockaddr_rtlabel)) { |
||
468 |
static char name[RTLABEL_LEN + 2]; |
||
469 |
struct sockaddr_rtlabel *sr; |
||
470 |
|||
471 |
sr = (struct sockaddr_rtlabel *)sa; |
||
472 |
snprintf(name, sizeof(name), "\"%s\"", sr->sr_label); |
||
473 |
return (name); |
||
474 |
} |
||
475 |
/* FALLTHROUGH */ |
||
476 |
default: |
||
477 |
(void)snprintf(line, sizeof(line), "(%d) %s", |
||
478 |
sa->sa_family, any_ntoa(sa)); |
||
479 |
break; |
||
480 |
} |
||
481 |
return (line); |
||
482 |
2718 |
} |
|
483 |
|||
484 |
char * |
||
485 |
routename4(in_addr_t in) |
||
486 |
{ |
||
487 |
char *cp = NULL; |
||
488 |
struct in_addr ina; |
||
489 |
struct hostent *hp; |
||
490 |
|||
491 |
✗✓ | 2277 |
if (in == INADDR_ANY) |
492 |
cp = "default"; |
||
493 |
✗✓ | 2277 |
if (!cp && !nflag) { |
494 |
if ((hp = gethostbyaddr((char *)&in, |
||
495 |
sizeof(in), AF_INET)) != NULL) { |
||
496 |
if ((cp = strchr(hp->h_name, '.')) && |
||
497 |
!strcmp(cp + 1, domain)) |
||
498 |
*cp = '\0'; |
||
499 |
cp = hp->h_name; |
||
500 |
} |
||
501 |
} |
||
502 |
2277 |
ina.s_addr = in; |
|
503 |
✗✓ | 6831 |
strlcpy(line, cp ? cp : inet_ntoa(ina), sizeof(line)); |
504 |
|||
505 |
2277 |
return (line); |
|
506 |
} |
||
507 |
|||
508 |
char * |
||
509 |
routename6(struct sockaddr_in6 *sin6) |
||
510 |
{ |
||
511 |
int niflags = 0; |
||
512 |
|||
513 |
✓✗ | 810 |
if (nflag) |
514 |
405 |
niflags |= NI_NUMERICHOST; |
|
515 |
else |
||
516 |
niflags |= NI_NOFQDN; |
||
517 |
|||
518 |
✗✓ | 810 |
if (getnameinfo((struct sockaddr *)sin6, sin6->sin6_len, |
519 |
405 |
line, sizeof(line), NULL, 0, niflags) != 0) |
|
520 |
strncpy(line, "invalid", sizeof(line)); |
||
521 |
|||
522 |
405 |
return (line); |
|
523 |
} |
||
524 |
|||
525 |
/* |
||
526 |
* Return the name of the network whose address is given. |
||
527 |
* The address is assumed to be that of a net or subnet, not a host. |
||
528 |
*/ |
||
529 |
char * |
||
530 |
netname4(in_addr_t in, struct sockaddr_in *maskp) |
||
531 |
{ |
||
532 |
char *cp = NULL; |
||
533 |
struct netent *np = NULL; |
||
534 |
in_addr_t mask; |
||
535 |
int mbits; |
||
536 |
|||
537 |
1026 |
in = ntohl(in); |
|
538 |
✓✗✓✗ |
2052 |
mask = maskp && maskp->sin_len != 0 ? ntohl(maskp->sin_addr.s_addr) : 0; |
539 |
✗✓ | 513 |
if (!nflag && in != INADDR_ANY) { |
540 |
if ((np = getnetbyaddr(in, AF_INET)) != NULL) |
||
541 |
cp = np->n_name; |
||
542 |
} |
||
543 |
✗✓ | 513 |
if (in == INADDR_ANY && mask == INADDR_ANY) |
544 |
cp = "default"; |
||
545 |
✓✗ | 1539 |
mbits = mask ? 33 - ffs(mask) : 0; |
546 |
✗✓ | 513 |
if (cp) |
547 |
strlcpy(line, cp, sizeof(line)); |
||
548 |
#define C(x) ((x) & 0xff) |
||
549 |
✓✓ | 513 |
else if (mbits < 9) |
550 |
9 |
snprintf(line, sizeof(line), "%u/%d", C(in >> 24), mbits); |
|
551 |
✓✓ | 504 |
else if (mbits < 17) |
552 |
72 |
snprintf(line, sizeof(line), "%u.%u/%d", |
|
553 |
72 |
C(in >> 24) , C(in >> 16), mbits); |
|
554 |
✓✓ | 432 |
else if (mbits < 25) |
555 |
414 |
snprintf(line, sizeof(line), "%u.%u.%u/%d", |
|
556 |
C(in >> 24), C(in >> 16), C(in >> 8), mbits); |
||
557 |
else |
||
558 |
18 |
snprintf(line, sizeof(line), "%u.%u.%u.%u/%d", C(in >> 24), |
|
559 |
18 |
C(in >> 16), C(in >> 8), C(in), mbits); |
|
560 |
#undef C |
||
561 |
513 |
return (line); |
|
562 |
} |
||
563 |
|||
564 |
char * |
||
565 |
netname6(struct sockaddr_in6 *sa6, struct sockaddr_in6 *mask) |
||
566 |
{ |
||
567 |
216 |
struct sockaddr_in6 sin6; |
|
568 |
u_char *p; |
||
569 |
int masklen, final = 0, illegal = 0; |
||
570 |
int i, lim, flag, error; |
||
571 |
108 |
char hbuf[NI_MAXHOST]; |
|
572 |
|||
573 |
108 |
sin6 = *sa6; |
|
574 |
|||
575 |
flag = 0; |
||
576 |
masklen = 0; |
||
577 |
✓✗ | 108 |
if (mask) { |
578 |
108 |
lim = mask->sin6_len - offsetof(struct sockaddr_in6, sin6_addr); |
|
579 |
108 |
lim = lim < (int)sizeof(struct in6_addr) ? |
|
580 |
lim : (int)sizeof(struct in6_addr); |
||
581 |
✓✓ | 3672 |
for (p = (u_char *)&mask->sin6_addr, i = 0; i < lim; p++) { |
582 |
✓✓✗✓ |
2916 |
if (final && *p) { |
583 |
illegal++; |
||
584 |
sin6.sin6_addr.s6_addr[i++] = 0x00; |
||
585 |
continue; |
||
586 |
} |
||
587 |
|||
588 |
✓✗✗✗ ✗✗✗✗ ✓✗ |
1728 |
switch (*p & 0xff) { |
589 |
case 0xff: |
||
590 |
432 |
masklen += 8; |
|
591 |
432 |
break; |
|
592 |
case 0xfe: |
||
593 |
masklen += 7; |
||
594 |
final++; |
||
595 |
break; |
||
596 |
case 0xfc: |
||
597 |
masklen += 6; |
||
598 |
final++; |
||
599 |
break; |
||
600 |
case 0xf8: |
||
601 |
masklen += 5; |
||
602 |
final++; |
||
603 |
break; |
||
604 |
case 0xf0: |
||
605 |
masklen += 4; |
||
606 |
final++; |
||
607 |
break; |
||
608 |
case 0xe0: |
||
609 |
masklen += 3; |
||
610 |
final++; |
||
611 |
break; |
||
612 |
case 0xc0: |
||
613 |
masklen += 2; |
||
614 |
final++; |
||
615 |
break; |
||
616 |
case 0x80: |
||
617 |
masklen += 1; |
||
618 |
final++; |
||
619 |
break; |
||
620 |
case 0x00: |
||
621 |
1296 |
final++; |
|
622 |
1296 |
break; |
|
623 |
default: |
||
624 |
final++; |
||
625 |
illegal++; |
||
626 |
break; |
||
627 |
} |
||
628 |
|||
629 |
✓✗ | 1728 |
if (!illegal) |
630 |
1728 |
sin6.sin6_addr.s6_addr[i++] &= *p; |
|
631 |
else |
||
632 |
sin6.sin6_addr.s6_addr[i++] = 0x00; |
||
633 |
} |
||
634 |
✗✓ | 108 |
while (i < (int)sizeof(struct in6_addr)) |
635 |
sin6.sin6_addr.s6_addr[i++] = 0x00; |
||
636 |
} else |
||
637 |
masklen = 128; |
||
638 |
|||
639 |
✗✓✗✗ ✗✗✗✗ ✗✗ |
108 |
if (masklen == 0 && IN6_IS_ADDR_UNSPECIFIED(&sin6.sin6_addr)) |
640 |
return ("default"); |
||
641 |
|||
642 |
✗✓ | 108 |
if (illegal) |
643 |
warnx("illegal prefixlen"); |
||
644 |
|||
645 |
✓✗ | 108 |
if (nflag) |
646 |
108 |
flag |= NI_NUMERICHOST; |
|
647 |
216 |
error = getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len, |
|
648 |
108 |
hbuf, sizeof(hbuf), NULL, 0, flag); |
|
649 |
✗✓ | 108 |
if (error) |
650 |
snprintf(hbuf, sizeof(hbuf), "invalid"); |
||
651 |
|||
652 |
108 |
snprintf(line, sizeof(line), "%s/%d", hbuf, masklen); |
|
653 |
108 |
return (line); |
|
654 |
108 |
} |
|
655 |
|||
656 |
/* |
||
657 |
* Return the name of the network whose address is given. |
||
658 |
* The address is assumed to be that of a net or subnet, not a host. |
||
659 |
*/ |
||
660 |
char * |
||
661 |
netname(struct sockaddr *sa, struct sockaddr *mask) |
||
662 |
{ |
||
663 |
✓✓✗✗ ✗ |
1242 |
switch (sa->sa_family) { |
664 |
case AF_INET: |
||
665 |
1026 |
return netname4(((struct sockaddr_in *)sa)->sin_addr.s_addr, |
|
666 |
513 |
(struct sockaddr_in *)mask); |
|
667 |
case AF_INET6: |
||
668 |
216 |
return netname6((struct sockaddr_in6 *)sa, |
|
669 |
108 |
(struct sockaddr_in6 *)mask); |
|
670 |
case AF_LINK: |
||
671 |
return (link_print(sa)); |
||
672 |
case AF_MPLS: |
||
673 |
return (label_print(sa)); |
||
674 |
default: |
||
675 |
snprintf(line, sizeof(line), "af %d: %s", |
||
676 |
sa->sa_family, any_ntoa(sa)); |
||
677 |
break; |
||
678 |
} |
||
679 |
return (line); |
||
680 |
621 |
} |
|
681 |
|||
682 |
static const char hexlist[] = "0123456789abcdef"; |
||
683 |
|||
684 |
char * |
||
685 |
any_ntoa(const struct sockaddr *sa) |
||
686 |
{ |
||
687 |
static char obuf[240]; |
||
688 |
const char *in = sa->sa_data; |
||
689 |
char *out = obuf; |
||
690 |
int len = sa->sa_len - offsetof(struct sockaddr, sa_data); |
||
691 |
|||
692 |
*out++ = 'Q'; |
||
693 |
do { |
||
694 |
*out++ = hexlist[(*in >> 4) & 15]; |
||
695 |
*out++ = hexlist[(*in++) & 15]; |
||
696 |
*out++ = '.'; |
||
697 |
} while (--len > 0 && (out + 3) < &obuf[sizeof(obuf) - 1]); |
||
698 |
out[-1] = '\0'; |
||
699 |
return (obuf); |
||
700 |
} |
||
701 |
|||
702 |
char * |
||
703 |
link_print(struct sockaddr *sa) |
||
704 |
{ |
||
705 |
72 |
struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa; |
|
706 |
36 |
u_char *lla = (u_char *)sdl->sdl_data + sdl->sdl_nlen; |
|
707 |
|||
708 |
✗✓✗✗ ✗✗ |
36 |
if (sdl->sdl_nlen == 0 && sdl->sdl_alen == 0 && |
709 |
sdl->sdl_slen == 0) { |
||
710 |
(void)snprintf(line, sizeof(line), "link#%d", sdl->sdl_index); |
||
711 |
return (line); |
||
712 |
} |
||
713 |
✗✓✗ | 36 |
switch (sdl->sdl_type) { |
714 |
case IFT_ETHER: |
||
715 |
case IFT_CARP: |
||
716 |
36 |
return (ether_ntoa((struct ether_addr *)lla)); |
|
717 |
default: |
||
718 |
return (link_ntoa(sdl)); |
||
719 |
} |
||
720 |
36 |
} |
|
721 |
|||
722 |
char * |
||
723 |
mpls_op(u_int32_t type) |
||
724 |
{ |
||
725 |
switch (type & (MPLS_OP_PUSH | MPLS_OP_POP | MPLS_OP_SWAP)) { |
||
726 |
case MPLS_OP_LOCAL: |
||
727 |
return ("LOCAL"); |
||
728 |
case MPLS_OP_POP: |
||
729 |
return ("POP"); |
||
730 |
case MPLS_OP_SWAP: |
||
731 |
return ("SWAP"); |
||
732 |
case MPLS_OP_PUSH: |
||
733 |
return ("PUSH"); |
||
734 |
default: |
||
735 |
return ("?"); |
||
736 |
} |
||
737 |
} |
||
738 |
|||
739 |
char * |
||
740 |
label_print(struct sockaddr *sa) |
||
741 |
{ |
||
742 |
struct sockaddr_mpls *smpls = (struct sockaddr_mpls *)sa; |
||
743 |
|||
744 |
if (smpls) |
||
745 |
(void)snprintf(line, sizeof(line), "%u", |
||
746 |
ntohl(smpls->smpls_label) >> MPLS_LABEL_OFFSET); |
||
747 |
else |
||
748 |
(void)snprintf(line, sizeof(line), "-"); |
||
749 |
|||
750 |
return (line); |
||
751 |
} |
Generated by: GCOVR (Version 3.3) |