Skip to content

Commit 457fbaa

Browse files
committed
Make tools/getifaddrs output closer to ifconfig
This is easier to read with a lots of addresses and give more infos
1 parent 74acf44 commit 457fbaa

File tree

2 files changed

+123
-125
lines changed

2 files changed

+123
-125
lines changed

libc/sock/ifaddrs.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "libc/calls/calls.h"
2121
#include "libc/calls/syscall-sysv.internal.h"
2222
#include "libc/dce.h"
23+
#include "libc/intrin/newbie.h"
2324
#include "libc/limits.h"
2425
#include "libc/mem/mem.h"
2526
#include "libc/sock/sock.h"
@@ -222,10 +223,10 @@ int getifaddrs(struct ifaddrs **out_ifpp) {
222223
addr6->netmask.sin6_port = 0;
223224
addr6->netmask.sin6_flowinfo = 0;
224225
addr6->addr.sin6_scope_id = ifr->ifr6_ifindex;
225-
memcpy(&addr6->netmask.sin6_addr, &ifr->ifr6_addr,
226-
sizeof(struct in6_addr));
227-
*((uint128_t *)&(addr6->netmask.sin6_addr)) &=
228-
(UINT128_MAX >> ifr->ifr6_prefixlen);
226+
227+
int prefixlen = ifr->ifr6_prefixlen;
228+
*((uint128_t *)&(addr6->netmask.sin6_addr)) = htobe128(
229+
prefixlen == 0 ? 0 : (UINT128_MAX << (128 - prefixlen)));
229230

230231
if (!ioctl(fd, SIOCGIFFLAGS, ifr)) {
231232
addr6->ifaddrs.ifa_flags = ifr->ifr_flags;

tool/viz/getifaddrs.c

Lines changed: 118 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
╚─────────────────────────────────────────────────────────────────────────────*/
1919
#include "libc/calls/calls.h"
2020
#include "libc/fmt/itoa.h"
21+
#include "libc/intrin/bsr.h"
22+
#include "libc/intrin/newbie.h"
23+
#include "libc/limits.h"
2124
#include "libc/runtime/runtime.h"
2225
#include "libc/sock/ifaddrs.h"
2326
#include "libc/sock/sock.h"
@@ -29,17 +32,23 @@
2932
#include "libc/sysv/consts/iff.h"
3033

3134
/* example output:
32-
33-
eth0
34-
addr: 10.10.10.237
35-
netmask: 255.255.255.0
36-
broadcast: 10.10.10.255
37-
flags: IFF_UP IFF_BROADCAST IFF_MULTICAST IFF_RUNNING
38-
39-
lo
40-
addr: 127.0.0.1
41-
netmask: 255.0.0.0
42-
flags: IFF_UP IFF_LOOPBACK IFF_RUNNING */
35+
vnet0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>
36+
inet6 fe80::fc54:ff:fefe:70d prefixlen 64 flags<128> class 0x20<link> ifidx 38
37+
vnet1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>
38+
inet6 fe80::fc54:ff:fe6a:6545 prefixlen 64 flags<128> class 0x20<link> ifidx 44
39+
enp51s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>
40+
inet6 fe80::ce3f:bd13:34ea:c170 prefixlen 64 flags<128> class 0x20<link> ifidx 43
41+
inet 192.168.1.2 netmask 255.255.255.0 broadcast 192.168.1.255
42+
wlp0s20f3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>
43+
inet6 fe80::9e1f:6462:15e2:2bf7 prefixlen 64 flags<128> class 0x20<link> ifidx 3
44+
inet 192.168.1.95 netmask 255.255.255.0 broadcast 192.168.1.255
45+
lo: flags=73<UP,RUNNING,LOOPBACK>
46+
inet6 ::1 prefixlen 128 flags<128> class 0x10<host>
47+
inet 127.0.0.1 netmask 255.0.0.0
48+
virbr1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>
49+
inet 192.168.121.1 netmask 255.255.255.0 broadcast 192.168.121.255
50+
virbr0: flags=4099<UP,BROADCAST,MULTICAST>
51+
inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255 */
4352

4453
const char *sockaddr2str(const struct sockaddr *sa, char *buf, size_t size) {
4554
if (sa->sa_family == AF_INET) {
@@ -53,133 +62,121 @@ const char *sockaddr2str(const struct sockaddr *sa, char *buf, size_t size) {
5362
}
5463
}
5564

56-
int main(int argc, char *argv[]) {
57-
58-
// get network interface list
59-
struct ifaddrs *ifaddrs;
60-
if (getifaddrs(&ifaddrs)) {
61-
perror("getifaddrs");
62-
exit(1);
63-
}
64-
65-
// print network interface list
66-
for (struct ifaddrs *ifa = ifaddrs; ifa; ifa = ifa->ifa_next) {
67-
tinyprint(1, ifa->ifa_name, "\n", NULL);
68-
69-
char buf[128];
65+
void print_ifaddr(struct ifaddrs *ifa) {
66+
char buf[128];
67+
if (ifa->ifa_addr->sa_family == AF_INET) {
7068
if (sockaddr2str(ifa->ifa_addr, buf, sizeof(buf))) {
71-
tinyprint(1, "addr: ", buf, "\n", NULL);
69+
tinyprint(1, " inet ", buf, NULL);
7270
}
7371
if (sockaddr2str(ifa->ifa_netmask, buf, sizeof(buf))) {
74-
tinyprint(1, "netmask: ", buf, "\n", NULL);
72+
tinyprint(1, " netmask ", buf, NULL);
7573
}
7674
if ((ifa->ifa_flags & IFF_BROADCAST) &&
7775
sockaddr2str(ifa->ifa_broadaddr, buf, sizeof(buf))) {
78-
tinyprint(1, "broadcast: ", buf, "\n", NULL);
76+
tinyprint(1, " broadcast ", buf, NULL);
7977
} else if ((ifa->ifa_flags & IFF_POINTOPOINT) &&
8078
sockaddr2str(ifa->ifa_dstaddr, buf, sizeof(buf))) {
81-
tinyprint(1, "dstaddr: ", buf, "\n", NULL);
79+
tinyprint(1, " dstaddr ", buf, NULL);
80+
}
81+
} else if (ifa->ifa_addr->sa_family == AF_INET6) {
82+
if (sockaddr2str(ifa->ifa_addr, buf, sizeof(buf))) {
83+
tinyprint(1, " inet6 ", buf, NULL);
8284
}
8385

84-
if (ifa->ifa_addr->sa_family == AF_INET6) {
85-
int scope = ((int *)ifa->ifa_data)[0];
86-
int aflags = ((int *)ifa->ifa_data)[1];
87-
// #define IPV6_ADDR_LOOPBACK 0x0010U
88-
// #define IPV6_ADDR_LINKLOCAL 0x0020U
89-
// #define IPV6_ADDR_SITELOCAL 0x0040U
86+
uint128_t netmask = ~be128toh(*((uint128_t *)(&(
87+
((const struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr))));
88+
int prefixlen = 128;
89+
if (netmask > 0) {
90+
uint64_t hi = (uint64_t)(netmask >> 64);
91+
prefixlen = (hi > 0) ? (63 - bsrl(hi)) : (127 - bsrl((uint64_t)netmask));
92+
}
9093

91-
// #define IFA_F_TEMPORARY 0x01
92-
// #define IFA_F_NODAD 0x02
93-
// #define IFA_F_OPTIMISTIC 0x04
94-
// #define IFA_F_DADFAILED 0x08
95-
// #define IFA_F_HOMEADDRESS 0x10
96-
// #define IFA_F_DEPRECATED 0x20
97-
// #define IFA_F_TENTATIVE 0x40
98-
// #define IFA_F_PERMANENT 0x80
99-
// #define IFA_F_MANAGETEMPADDR 0x100
100-
// #define IFA_F_NOPREFIXROUTE 0x200
101-
// #define IFA_F_MCAUTOJOIN 0x400
102-
// #define IFA_F_STABLE_PRIVACY 0x800
103-
tinyprint(1, "scope:", NULL);
104-
if (scope == 0x10) {
105-
tinyprint(1, " loopback", NULL);
106-
}
107-
if (scope == 0x20) {
108-
tinyprint(1, " linklocal", NULL);
109-
}
110-
if (scope == 0x40) {
111-
tinyprint(1, " sitelocal", NULL);
112-
}
113-
if (scope == 0x00) {
114-
tinyprint(1, " global", NULL);
115-
}
116-
tinyprint(1, "\n", NULL);
94+
FormatUint64(buf, prefixlen);
95+
tinyprint(1, " prefixlen ", buf, NULL);
11796

118-
tinyprint(1, "addr flags:", NULL);
119-
if (aflags & 0x01) {
120-
tinyprint(1, " temporary", NULL);
121-
}
122-
if (aflags & 0x02) {
123-
tinyprint(1, " nodad", NULL);
124-
}
125-
if (aflags & 0x04) {
126-
tinyprint(1, " optimistic", NULL);
127-
}
128-
if (aflags & 0x08) {
129-
tinyprint(1, " dadfailed", NULL);
130-
}
131-
if (aflags & 0x10) {
132-
tinyprint(1, " homeaddress", NULL);
133-
}
134-
if (aflags & 0x20) {
135-
tinyprint(1, " deprecated", NULL);
136-
}
137-
if (aflags & 0x40) {
138-
tinyprint(1, " tentative", NULL);
139-
}
140-
if (aflags & 0x80) {
141-
tinyprint(1, " permanent", NULL);
142-
}
143-
if (aflags & 0x100) {
144-
tinyprint(1, " managetempaddr", NULL);
145-
}
146-
if (aflags & 0x200) {
147-
tinyprint(1, " noprefixroute", NULL);
148-
}
149-
if (aflags & 0x400) {
150-
tinyprint(1, " mcautojoin", NULL);
151-
}
152-
if (aflags & 0x800) {
153-
tinyprint(1, " stable_privacy", NULL);
154-
}
155-
tinyprint(1, "\n", NULL);
156-
}
97+
int aflags = ((int *)ifa->ifa_data)[1];
98+
FormatUint64(buf, aflags);
99+
tinyprint(1, " flags<", buf, ">", NULL);
157100

158-
tinyprint(1, "flags:", NULL);
159-
if (ifa->ifa_flags & IFF_UP) {
160-
tinyprint(1, " IFF_UP", NULL);
161-
}
162-
if (ifa->ifa_flags & IFF_DEBUG) {
163-
tinyprint(1, " IFF_DEBUG", NULL);
164-
}
165-
if (ifa->ifa_flags & IFF_LOOPBACK) {
166-
tinyprint(1, " IFF_LOOPBACK", NULL);
167-
}
168-
if (ifa->ifa_flags & IFF_MULTICAST) {
169-
tinyprint(1, " IFF_MULTICAST", NULL);
101+
int scope = ((((int *)ifa->ifa_data)[0]) / 16) % 5;
102+
// #define IPV6_ADDR_GLOBAL 0x0000U
103+
// #define IPV6_ADDR_LOOPBACK 0x0010U
104+
// #define IPV6_ADDR_LINKLOCAL 0x0020U
105+
// #define IPV6_ADDR_SITELOCAL 0x0040U
106+
char *addr_types[] = {"global", "host", "link", "??", "site"};
107+
buf[0] = '0' + scope;
108+
buf[1] = '\0';
109+
tinyprint(1, " class 0x", buf, "0<", addr_types[scope], ">", NULL);
110+
111+
if (scope == 2 || scope == 4) { // linklocal or sitelocal
112+
FormatUint64(buf,
113+
((const struct sockaddr_in6 *)ifa->ifa_addr)->sin6_scope_id);
114+
tinyprint(1, " ifidx ", buf, NULL);
170115
}
171-
if (ifa->ifa_flags & IFF_ALLMULTI) {
172-
tinyprint(1, " IFF_ALLMULTI", NULL);
116+
}
117+
tinyprint(1, "\n", NULL);
118+
}
119+
void print_iface(struct ifaddrs *ifa) {
120+
char buf[32];
121+
FormatUint64(buf, ifa->ifa_flags);
122+
tinyprint(1, ifa->ifa_name, ": flags=", buf, "<", NULL);
123+
char *sflags[] = {"UP", "BROADCAST", "POINTOPOINT", "RUNNING",
124+
"DEBUG", "LOOPBACK", "MULTICAST", "ALLMULTI",
125+
"NOARP", "IPROMISC"};
126+
int iflags[] = {IFF_UP, IFF_BROADCAST, IFF_POINTOPOINT, IFF_RUNNING,
127+
IFF_DEBUG, IFF_LOOPBACK, IFF_MULTICAST, IFF_ALLMULTI,
128+
IFF_NOARP, IFF_PROMISC};
129+
int first = 1;
130+
for (int i = 0; i < (sizeof(sflags) / sizeof(*sflags)); i++) {
131+
if (ifa->ifa_flags & iflags[i]) {
132+
if (!first) {
133+
tinyprint(1, ",", NULL);
134+
}
135+
first = 0;
136+
tinyprint(1, sflags[i], NULL);
173137
}
174-
if (ifa->ifa_flags & IFF_NOARP) {
175-
tinyprint(1, " IFF_NOARP", NULL);
138+
}
139+
tinyprint(1, ">\n", NULL);
140+
}
141+
142+
int main(int argc, char *argv[]) {
143+
// get network interface list
144+
struct ifaddrs *ifaddrs;
145+
if (getifaddrs(&ifaddrs)) {
146+
perror("getifaddrs");
147+
exit(1);
148+
}
149+
150+
struct ifaddrs *ifaddrs_next_if = ifaddrs;
151+
struct ifaddrs *ifaddrs_curr_if = NULL;
152+
struct ifaddrs *ifa = NULL;
153+
int first = 1;
154+
// print network interface list
155+
while (ifa || ifaddrs_next_if) {
156+
if (!ifa) {
157+
if (!first) {
158+
tinyprint(1, "\n", NULL);
159+
first = 0;
160+
}
161+
ifaddrs_curr_if = ifaddrs_next_if;
162+
ifa = ifaddrs_next_if;
163+
ifaddrs_next_if = NULL;
164+
print_iface(ifa);
176165
}
177-
if (ifa->ifa_flags & IFF_PROMISC) {
178-
tinyprint(1, " IFF_PROMISC", NULL);
166+
if (strcmp(ifa->ifa_name, ifaddrs_curr_if->ifa_name)) {
167+
if (!ifaddrs_next_if) {
168+
struct ifaddrs *ifa2 = ifaddrs;
169+
while (ifa2 != ifa && strcmp(ifa->ifa_name, ifa2->ifa_name)) {
170+
ifa2 = ifa2->ifa_next;
171+
}
172+
if (ifa2 == ifa) {
173+
ifaddrs_next_if = ifa;
174+
}
175+
}
176+
} else {
177+
print_ifaddr(ifa);
179178
}
180-
tinyprint(1, "\n", NULL);
181-
182-
tinyprint(1, "\n", NULL);
179+
ifa = ifa->ifa_next;
183180
}
184181

185182
// perform cleanup

0 commit comments

Comments
 (0)