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