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