initrd: Add diff/sdiff back to rescue and fix build
[dragonfly.git] / test / ifconf / ifconf.c
blob66fd11232462d9ebe41309f8c052ca4514a4c7c3
1 #include <sys/types.h>
2 #include <sys/ioctl.h>
3 #include <sys/socket.h>
5 #include <arpa/inet.h>
6 #include <netinet/in.h>
7 #include <net/if.h>
8 #include <net/if_dl.h>
10 #include <err.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <unistd.h>
16 #define NADDRS 128
18 /* XXX _SIZEOF_ADDR_IFREQ should accept ptr */
19 #define _SIZEOF_ADDR_IFREQ1(ifr) \
20 ((ifr)->ifr_addr.sa_len > sizeof(struct sockaddr) ? \
21 (sizeof(struct ifreq) - sizeof(struct sockaddr) + \
22 (ifr)->ifr_addr.sa_len) : sizeof(struct ifreq))
24 static void
25 usage(const char *cmd)
27 fprintf(stderr, "%s [-n naddrs]\n", cmd);
28 exit(1);
31 int
32 main(int argc, char *argv[])
34 struct ifconf ifc;
35 struct ifreq *ifr;
36 caddr_t pos;
37 int s, naddrs, opt;
39 naddrs = NADDRS;
41 while ((opt = getopt(argc, argv, "n:")) != -1) {
42 switch (opt) {
43 case 'n':
44 naddrs = strtol(optarg, NULL, 10);
45 break;
46 default:
47 usage(argv[0]);
50 if (naddrs <= 0)
51 usage(argv[0]);
53 s = socket(AF_INET, SOCK_DGRAM, 0);
54 if (s < 0)
55 err(2, "socket failed");
57 memset(&ifc, 0, sizeof(ifc));
58 ifc.ifc_len = sizeof(struct sockaddr_storage) * naddrs;
59 ifc.ifc_buf = malloc(ifc.ifc_len);
60 if (ifc.ifc_buf == NULL)
61 err(2, "malloc failed");
63 if (ioctl(s, SIOCGIFCONF, &ifc, sizeof(ifc)) < 0)
64 err(2, "ioctl failed");
66 pos = ifc.ifc_buf;
67 while (ifc.ifc_len >= (int)sizeof(*ifr)) {
68 int len;
70 ifr = (struct ifreq *)pos;
71 len = _SIZEOF_ADDR_IFREQ1(ifr);
72 if (ifc.ifc_len < len)
73 err(2, "invalid ifc.ifc_len");
75 if (ifr->ifr_addr.sa_family == AF_UNSPEC) {
76 printf("%s: no address\n", ifr->ifr_name);
77 } else if (ifr->ifr_addr.sa_family == AF_INET ||
78 ifr->ifr_addr.sa_family == AF_INET6) {
79 char addr_str[INET6_ADDRSTRLEN];
80 const void *src;
81 const char *ret;
83 if (ifr->ifr_addr.sa_family == AF_INET) {
84 const struct sockaddr_in *in =
85 (const struct sockaddr_in *)&ifr->ifr_addr;
86 src = &in->sin_addr;
87 } else {
88 const struct sockaddr_in6 *in6 =
89 (const struct sockaddr_in6 *)&ifr->ifr_addr;
90 src = &in6->sin6_addr;
93 ret = inet_ntop(ifr->ifr_addr.sa_family, src,
94 addr_str, sizeof(addr_str));
95 if (ret == NULL)
96 err(2, "inet_ntop failed");
97 printf("%s: inet%c %s\n", ifr->ifr_name,
98 ifr->ifr_addr.sa_family == AF_INET ? '4' : '6',
99 ret);
100 } else if (ifr->ifr_addr.sa_family == AF_LINK) {
101 const struct sockaddr_dl *dl =
102 (const struct sockaddr_dl *)&ifr->ifr_addr;
104 printf("%s: link%d\n", ifr->ifr_name, dl->sdl_index);
105 } else {
106 printf("%s: unknown family %d\n", ifr->ifr_name,
107 ifr->ifr_addr.sa_family);
110 ifc.ifc_len -= len;
111 pos += len;
113 if (ifc.ifc_len != 0)
114 printf("ifc_len left %d\n", ifc.ifc_len);
116 exit(0);