xref: /freebsd/usr.bin/netstat/common.c (revision 95968ea7ec8f1cd3c1d03cc56c704cb2392d0d25)
1a6663252SAlexander V. Chernikov /*-
2a6663252SAlexander V. Chernikov  * SPDX-License-Identifier: BSD-3-Clause
3a6663252SAlexander V. Chernikov  *
4a6663252SAlexander V. Chernikov  * Copyright (c) 1983, 1988, 1993
5a6663252SAlexander V. Chernikov  *	The Regents of the University of California.  All rights reserved.
6a6663252SAlexander V. Chernikov  *
7a6663252SAlexander V. Chernikov  * Redistribution and use in source and binary forms, with or without
8a6663252SAlexander V. Chernikov  * modification, are permitted provided that the following conditions
9a6663252SAlexander V. Chernikov  * are met:
10a6663252SAlexander V. Chernikov  * 1. Redistributions of source code must retain the above copyright
11a6663252SAlexander V. Chernikov  *    notice, this list of conditions and the following disclaimer.
12a6663252SAlexander V. Chernikov  * 2. Redistributions in binary form must reproduce the above copyright
13a6663252SAlexander V. Chernikov  *    notice, this list of conditions and the following disclaimer in the
14a6663252SAlexander V. Chernikov  *    documentation and/or other materials provided with the distribution.
15a6663252SAlexander V. Chernikov  * 3. Neither the name of the University nor the names of its contributors
16a6663252SAlexander V. Chernikov  *    may be used to endorse or promote products derived from this software
17a6663252SAlexander V. Chernikov  *    without specific prior written permission.
18a6663252SAlexander V. Chernikov  *
19a6663252SAlexander V. Chernikov  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20a6663252SAlexander V. Chernikov  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21a6663252SAlexander V. Chernikov  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22a6663252SAlexander V. Chernikov  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23a6663252SAlexander V. Chernikov  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24a6663252SAlexander V. Chernikov  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25a6663252SAlexander V. Chernikov  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26a6663252SAlexander V. Chernikov  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27a6663252SAlexander V. Chernikov  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28a6663252SAlexander V. Chernikov  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29a6663252SAlexander V. Chernikov  * SUCH DAMAGE.
30a6663252SAlexander V. Chernikov  */
31a6663252SAlexander V. Chernikov 
32a6663252SAlexander V. Chernikov #include <sys/param.h>
33a6663252SAlexander V. Chernikov #include <sys/protosw.h>
34a6663252SAlexander V. Chernikov #include <sys/socket.h>
35a6663252SAlexander V. Chernikov #include <sys/socketvar.h>
36a6663252SAlexander V. Chernikov #include <sys/sysctl.h>
37a6663252SAlexander V. Chernikov #include <sys/time.h>
38a6663252SAlexander V. Chernikov 
39a6663252SAlexander V. Chernikov #include <net/if.h>
40a6663252SAlexander V. Chernikov #include <net/if_dl.h>
41a6663252SAlexander V. Chernikov #include <arpa/inet.h>
42a6663252SAlexander V. Chernikov #include <ifaddrs.h>
43a6663252SAlexander V. Chernikov #include <libutil.h>
44a6663252SAlexander V. Chernikov #include <netdb.h>
45a6663252SAlexander V. Chernikov #include <stdbool.h>
46a6663252SAlexander V. Chernikov #include <stdint.h>
47a6663252SAlexander V. Chernikov #include <stdio.h>
48a6663252SAlexander V. Chernikov #include <stdlib.h>
49a6663252SAlexander V. Chernikov #include <stdbool.h>
50a6663252SAlexander V. Chernikov #include <string.h>
51a6663252SAlexander V. Chernikov #include <sysexits.h>
52a6663252SAlexander V. Chernikov #include <unistd.h>
53a6663252SAlexander V. Chernikov #include <libxo/xo.h>
54a6663252SAlexander V. Chernikov #include "netstat.h"
55a6663252SAlexander V. Chernikov #include "common.h"
56a6663252SAlexander V. Chernikov 
57a6663252SAlexander V. Chernikov const char *
fmt_flags(const struct bits * p,int f)58a6663252SAlexander V. Chernikov fmt_flags(const struct bits *p, int f)
59a6663252SAlexander V. Chernikov {
60a6663252SAlexander V. Chernikov 	static char name[33];
61a6663252SAlexander V. Chernikov 	char *flags;
62a6663252SAlexander V. Chernikov 
63a6663252SAlexander V. Chernikov 	for (flags = name; p->b_mask; p++)
64a6663252SAlexander V. Chernikov 		if (p->b_mask & f)
65a6663252SAlexander V. Chernikov 			*flags++ = p->b_val;
66a6663252SAlexander V. Chernikov 	*flags = '\0';
67a6663252SAlexander V. Chernikov 	return (name);
68a6663252SAlexander V. Chernikov }
69a6663252SAlexander V. Chernikov 
70a6663252SAlexander V. Chernikov void
print_flags_generic(int flags,const struct bits * pbits,const char * format,const char * tag_name)71a6663252SAlexander V. Chernikov print_flags_generic(int flags, const struct bits *pbits, const char *format,
72a6663252SAlexander V. Chernikov     const char *tag_name)
73a6663252SAlexander V. Chernikov {
74a6663252SAlexander V. Chernikov 	const struct bits *p;
75a6663252SAlexander V. Chernikov 	char tag_fmt[64];
76a6663252SAlexander V. Chernikov 
77a6663252SAlexander V. Chernikov 	xo_emit(format, fmt_flags(pbits, flags));
78a6663252SAlexander V. Chernikov 
79a6663252SAlexander V. Chernikov 	snprintf(tag_fmt, sizeof(tag_fmt), "{le:%s/%%s}", tag_name);
80a6663252SAlexander V. Chernikov 	xo_open_list(tag_name);
81a6663252SAlexander V. Chernikov 	for (p = pbits; p->b_mask; p++)
82a6663252SAlexander V. Chernikov 		if (p->b_mask & flags)
83a6663252SAlexander V. Chernikov 			xo_emit(tag_fmt, p->b_name);
84a6663252SAlexander V. Chernikov 	xo_close_list(tag_name);
85a6663252SAlexander V. Chernikov }
86a6663252SAlexander V. Chernikov 
87a6663252SAlexander V. Chernikov struct ifmap_entry *
prepare_ifmap(size_t * pifmap_size)88a6663252SAlexander V. Chernikov prepare_ifmap(size_t *pifmap_size)
89a6663252SAlexander V. Chernikov {
90a6663252SAlexander V. Chernikov 	int ifindex = 0, size;
91a6663252SAlexander V. Chernikov 	struct ifaddrs *ifap, *ifa;
92a6663252SAlexander V. Chernikov 	struct sockaddr_dl *sdl;
93a6663252SAlexander V. Chernikov 
94a6663252SAlexander V. Chernikov 	struct ifmap_entry *ifmap = NULL;
95a6663252SAlexander V. Chernikov 	int ifmap_size = 0;
96a6663252SAlexander V. Chernikov 
97a6663252SAlexander V. Chernikov 	/*
98a6663252SAlexander V. Chernikov 	 * Retrieve interface list at first
99a6663252SAlexander V. Chernikov 	 * since we need #ifindex -> if_xname match
100a6663252SAlexander V. Chernikov 	 */
101a6663252SAlexander V. Chernikov 	if (getifaddrs(&ifap) != 0)
102*95968ea7SYan-Hao Wang 		xo_err(EX_OSERR, "getifaddrs");
103a6663252SAlexander V. Chernikov 
104a6663252SAlexander V. Chernikov 	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
105a6663252SAlexander V. Chernikov 
106a6663252SAlexander V. Chernikov 		if (ifa->ifa_addr->sa_family != AF_LINK)
107a6663252SAlexander V. Chernikov 			continue;
108a6663252SAlexander V. Chernikov 
109a6663252SAlexander V. Chernikov 		sdl = (struct sockaddr_dl *)ifa->ifa_addr;
110a6663252SAlexander V. Chernikov 		ifindex = sdl->sdl_index;
111a6663252SAlexander V. Chernikov 
112a6663252SAlexander V. Chernikov 		if (ifindex >= ifmap_size) {
113f6b6d216SXin LI 			size = roundup2(ifindex + 1, 32) *
114a6663252SAlexander V. Chernikov 			    sizeof(struct ifmap_entry);
115a6663252SAlexander V. Chernikov 			if ((ifmap = realloc(ifmap, size)) == NULL)
116*95968ea7SYan-Hao Wang 				xo_errx(EX_OSERR, "realloc(%d) failed", size);
117a6663252SAlexander V. Chernikov 			memset(&ifmap[ifmap_size], 0,
118a6663252SAlexander V. Chernikov 			    size - ifmap_size *
119a6663252SAlexander V. Chernikov 			    sizeof(struct ifmap_entry));
120a6663252SAlexander V. Chernikov 
121f6b6d216SXin LI 			ifmap_size = roundup2(ifindex + 1, 32);
122a6663252SAlexander V. Chernikov 		}
123a6663252SAlexander V. Chernikov 
124a6663252SAlexander V. Chernikov 		if (*ifmap[ifindex].ifname != '\0')
125a6663252SAlexander V. Chernikov 			continue;
126a6663252SAlexander V. Chernikov 
127a6663252SAlexander V. Chernikov 		strlcpy(ifmap[ifindex].ifname, ifa->ifa_name, IFNAMSIZ);
128a6663252SAlexander V. Chernikov 	}
129a6663252SAlexander V. Chernikov 
130a6663252SAlexander V. Chernikov 	freeifaddrs(ifap);
131a6663252SAlexander V. Chernikov 
132a6663252SAlexander V. Chernikov 	*pifmap_size = ifmap_size;
133a6663252SAlexander V. Chernikov 
134a6663252SAlexander V. Chernikov 	return (ifmap);
135a6663252SAlexander V. Chernikov }
136a6663252SAlexander V. Chernikov 
137