From cb8c905ae9cee73c8fb9e836f01ef946de1dd1f2 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Sat, 24 Feb 2007 23:55:46 +0000 Subject: [PATCH] use getifaddrs from libc instead of private code Reviewed by: bms MFC after: 1 month --- sbin/ifconfig/af_atalk.c | 20 ++-- sbin/ifconfig/af_inet.c | 24 ++--- sbin/ifconfig/af_inet6.c | 16 ++- sbin/ifconfig/af_ipx.c | 12 +-- sbin/ifconfig/af_link.c | 10 +- sbin/ifconfig/ifconfig.c | 222 +++++++++++++-------------------------- sbin/ifconfig/ifconfig.h | 7 +- 7 files changed, 116 insertions(+), 195 deletions(-) diff --git a/sbin/ifconfig/af_atalk.c b/sbin/ifconfig/af_atalk.c index 0ceb8b92b318..9accc75fdc19 100644 --- a/sbin/ifconfig/af_atalk.c +++ b/sbin/ifconfig/af_atalk.c @@ -36,7 +36,6 @@ static const char rcsid[] = #include #include #include -#include /* for RTX_IFA */ #include @@ -45,6 +44,7 @@ static const char rcsid[] = #include #include #include +#include #include @@ -81,32 +81,30 @@ setatphase(const char *phase, int dummy __unused, int s, } static void -at_status(int s __unused, const struct rt_addrinfo * info) +at_status(int s __unused, const struct ifaddrs *ifa) { struct sockaddr_at *sat, null_sat; struct netrange *nr; memset(&null_sat, 0, sizeof(null_sat)); - sat = (struct sockaddr_at *)info->rti_info[RTAX_IFA]; + sat = (struct sockaddr_at *)ifa->ifa_addr; if (sat == NULL) return; nr = &sat->sat_range.r_netrange; printf("\tatalk %d.%d range %d-%d phase %d", ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node, ntohs(nr->nr_firstnet), ntohs(nr->nr_lastnet), nr->nr_phase); - if (flags & IFF_POINTOPOINT) { - /* note RTAX_BRD overlap with IFF_BROADCAST */ - sat = (struct sockaddr_at *)info->rti_info[RTAX_BRD]; - if (!sat) + if (ifa->ifa_flags & IFF_POINTOPOINT) { + sat = (struct sockaddr_at *)ifa->ifa_dstaddr; + if (sat == NULL) sat = &null_sat; printf("--> %d.%d", ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node); } - if (flags & IFF_BROADCAST) { - /* note RTAX_BRD overlap with IFF_POINTOPOINT */ - sat = (struct sockaddr_at *)info->rti_info[RTAX_BRD]; - if (sat) + if (ifa->ifa_flags & IFF_BROADCAST) { + sat = (struct sockaddr_at *)ifa->ifa_broadaddr; + if (sat != NULL) printf(" broadcast %d.%d", ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node); diff --git a/sbin/ifconfig/af_inet.c b/sbin/ifconfig/af_inet.c index 7678daa1aa97..1720b1981d87 100644 --- a/sbin/ifconfig/af_inet.c +++ b/sbin/ifconfig/af_inet.c @@ -36,13 +36,13 @@ static const char rcsid[] = #include #include #include -#include /* for RTX_IFA */ #include #include #include #include #include +#include #include #include /* for struct ifaddr */ @@ -56,35 +56,33 @@ static struct ifaliasreq in_addreq; static struct ifreq in_ridreq; static void -in_status(int s __unused, const struct rt_addrinfo * info) +in_status(int s __unused, const struct ifaddrs *ifa) { struct sockaddr_in *sin, null_sin; memset(&null_sin, 0, sizeof(null_sin)); - sin = (struct sockaddr_in *)info->rti_info[RTAX_IFA]; + sin = (struct sockaddr_in *)ifa->ifa_addr; if (sin == NULL) return; printf("\tinet %s ", inet_ntoa(sin->sin_addr)); - if (flags & IFF_POINTOPOINT) { - /* note RTAX_BRD overlap with IFF_BROADCAST */ - sin = (struct sockaddr_in *)info->rti_info[RTAX_BRD]; - if (!sin) + if (ifa->ifa_flags & IFF_POINTOPOINT) { + sin = (struct sockaddr_in *)ifa->ifa_dstaddr; + if (sin == NULL) sin = &null_sin; printf("--> %s ", inet_ntoa(sin->sin_addr)); } - sin = (struct sockaddr_in *)info->rti_info[RTAX_NETMASK]; - if (!sin) + sin = (struct sockaddr_in *)ifa->ifa_netmask; + if (sin == NULL) sin = &null_sin; printf("netmask 0x%lx ", (unsigned long)ntohl(sin->sin_addr.s_addr)); - if (flags & IFF_BROADCAST) { - /* note RTAX_BRD overlap with IFF_POINTOPOINT */ - sin = (struct sockaddr_in *)info->rti_info[RTAX_BRD]; - if (sin && sin->sin_addr.s_addr != 0) + if (ifa->ifa_flags & IFF_BROADCAST) { + sin = (struct sockaddr_in *)ifa->ifa_broadaddr; + if (sin != NULL && sin->sin_addr.s_addr != 0) printf("broadcast %s", inet_ntoa(sin->sin_addr)); } putchar('\n'); diff --git a/sbin/ifconfig/af_inet6.c b/sbin/ifconfig/af_inet6.c index 2aae38225235..f1871fb4996c 100644 --- a/sbin/ifconfig/af_inet6.c +++ b/sbin/ifconfig/af_inet6.c @@ -36,7 +36,6 @@ static const char rcsid[] = #include #include #include -#include /* for RTX_IFA */ #include #include @@ -179,7 +178,7 @@ in6_fillscopeid(struct sockaddr_in6 *sin6) } static void -in6_status(int s __unused, const struct rt_addrinfo * info) +in6_status(int s __unused, const struct ifaddrs *ifa) { struct sockaddr_in6 *sin, null_sin; struct in6_ifreq ifr6; @@ -192,7 +191,7 @@ in6_status(int s __unused, const struct rt_addrinfo * info) memset(&null_sin, 0, sizeof(null_sin)); - sin = (struct sockaddr_in6 *)info->rti_info[RTAX_IFA]; + sin = (struct sockaddr_in6 *)ifa->ifa_addr; if (sin == NULL) return; @@ -237,14 +236,13 @@ in6_status(int s __unused, const struct rt_addrinfo * info) sizeof(addr_buf)); printf("\tinet6 %s ", addr_buf); - if (flags & IFF_POINTOPOINT) { - /* note RTAX_BRD overlap with IFF_BROADCAST */ - sin = (struct sockaddr_in6 *)info->rti_info[RTAX_BRD]; + if (ifa->ifa_flags & IFF_POINTOPOINT) { + sin = (struct sockaddr_in6 *)ifa->ifa_dstaddr; /* * some of the interfaces do not have valid destination * address. */ - if (sin && sin->sin6_family == AF_INET6) { + if (sin != NULL && sin->sin6_family == AF_INET6) { int error; /* XXX: embedded link local addr check */ @@ -269,8 +267,8 @@ in6_status(int s __unused, const struct rt_addrinfo * info) } } - sin = (struct sockaddr_in6 *)info->rti_info[RTAX_NETMASK]; - if (!sin) + sin = (struct sockaddr_in6 *)ifa->ifa_netmask; + if (sin == NULL) sin = &null_sin; printf("prefixlen %d ", prefix(&sin->sin6_addr, sizeof(struct in6_addr))); diff --git a/sbin/ifconfig/af_ipx.c b/sbin/ifconfig/af_ipx.c index d16e2eb86d97..3ed0a9bc5ac0 100644 --- a/sbin/ifconfig/af_ipx.c +++ b/sbin/ifconfig/af_ipx.c @@ -36,12 +36,12 @@ static const char rcsid[] = #include #include #include -#include #include #include #include #include +#include #include #define IPXIP @@ -55,19 +55,19 @@ static struct ifaliasreq ipx_addreq; static struct ifreq ipx_ridreq; static void -ipx_status(int s __unused, const struct rt_addrinfo * info) +ipx_status(int s __unused, const struct ifaddrs *ifa) { struct sockaddr_ipx *sipx, null_sipx; - sipx = (struct sockaddr_ipx *)info->rti_info[RTAX_IFA]; + sipx = (struct sockaddr_ipx *)ifa->ifa_addr; if (sipx == NULL) return; printf("\tipx %s ", ipx_ntoa(sipx->sipx_addr)); - if (flags & IFF_POINTOPOINT) { - sipx = (struct sockaddr_ipx *)info->rti_info[RTAX_BRD]; - if (!sipx) { + if (ifa->ifa_flags & IFF_POINTOPOINT) { + sipx = (struct sockaddr_ipx *)ifa->ifa_broadaddr; + if (sipx == NULL) { memset(&null_sipx, 0, sizeof(null_sipx)); sipx = &null_sipx; } diff --git a/sbin/ifconfig/af_link.c b/sbin/ifconfig/af_link.c index d61075065f5b..f77515e5115e 100644 --- a/sbin/ifconfig/af_link.c +++ b/sbin/ifconfig/af_link.c @@ -36,12 +36,12 @@ static const char rcsid[] = #include #include #include -#include /* for RTX_IFA */ #include #include #include #include +#include #include #include @@ -52,16 +52,16 @@ static const char rcsid[] = static struct ifreq link_ridreq; static void -link_status(int s __unused, const struct rt_addrinfo *info) +link_status(int s __unused, const struct ifaddrs *ifa) { - const struct sockaddr_dl *sdl = - (const struct sockaddr_dl *) info->rti_info[RTAX_IFA]; + /* XXX no const 'cuz LLADDR is defined wrong */ + struct sockaddr_dl *sdl = (struct sockaddr_dl *) ifa->ifa_addr; if (sdl != NULL && sdl->sdl_alen > 0) { if (sdl->sdl_type == IFT_ETHER && sdl->sdl_alen == ETHER_ADDR_LEN) printf("\tether %s\n", - ether_ntoa((const struct ether_addr *)LLADDR(sdl))); + ether_ntoa((struct ether_addr *)LLADDR(sdl))); else { int n = sdl->sdl_nlen > 0 ? sdl->sdl_nlen + 1 : 0; diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index 684bf9006828..3860bd5411e9 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -62,6 +62,7 @@ static const char rcsid[] = #include #include +#include #include #include #include @@ -81,7 +82,6 @@ static const char rcsid[] = struct ifreq ifr; char name[IFNAMSIZ]; -int flags; int setaddr; int setipdst; int setmask; @@ -94,9 +94,8 @@ int supmedia = 0; int printkeys = 0; /* Print keying material for interfaces. */ static int ifconfig(int argc, char *const *argv, const struct afswtch *afp); -static void status(const struct afswtch *afp, int addrcount, - struct sockaddr_dl *sdl, struct if_msghdr *ifm, - struct ifa_msghdr *ifam); +static void status(const struct afswtch *afp, const struct sockaddr_dl *sdl, + struct ifaddrs *ifa); static void tunnel_status(int s); static void usage(void); @@ -141,16 +140,13 @@ int main(int argc, char *argv[]) { int c, all, namesonly, downonly, uponly; - int need_nl = 0, count = 0; const struct afswtch *afp = NULL; - int addrcount, ifindex; - struct if_msghdr *ifm, *nextifm; - struct ifa_msghdr *ifam; - struct sockaddr_dl *sdl; - char *buf, *lim, *next; - size_t needed; - int mib[6]; - char options[1024]; + int ifindex; + struct ifaddrs *ifap, *ifa; + struct ifreq paifr; + const struct sockaddr_dl *sdl; + char options[1024], *cp; + const char *ifname; struct option *p; all = downonly = uponly = namesonly = verbose = 0; @@ -213,6 +209,7 @@ main(int argc, char *argv[]) if (argc > 1) usage(); + ifname = NULL; ifindex = 0; if (argc == 1) { afp = af_getbyname(*argv); @@ -227,13 +224,13 @@ main(int argc, char *argv[]) if (argc < 1) usage(); - strncpy(name, *argv, sizeof(name)); + ifname = *argv; argc--, argv++; /* check and maybe load support for this interface */ - ifmaybeload(name); + ifmaybeload(ifname); - ifindex = if_nametoindex(name); + ifindex = if_nametoindex(ifname); if (ifindex == 0) { /* * NOTE: We must special-case the `create' command @@ -245,7 +242,7 @@ main(int argc, char *argv[]) ifconfig(argc, argv, NULL); exit(0); } - errx(1, "interface %s does not exist", name); + errx(1, "interface %s does not exist", ifname); } } @@ -256,106 +253,55 @@ main(int argc, char *argv[]) argc--, argv++; } -retry: - mib[0] = CTL_NET; - mib[1] = PF_ROUTE; - mib[2] = 0; - mib[3] = 0; /* address family */ - mib[4] = NET_RT_IFLIST; - mib[5] = ifindex; /* interface index */ - - /* if particular family specified, only ask about it */ - if (afp != NULL) - mib[3] = afp->af_af; - - if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) - errx(1, "iflist-sysctl-estimate"); - if ((buf = malloc(needed)) == NULL) - errx(1, "malloc"); - if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { - if (errno == ENOMEM && count++ < 10) { - warnx("Routing table grew, retrying"); - free(buf); - sleep(1); - goto retry; - } - errx(1, "actual retrieval of interface table"); - } - lim = buf + needed; - - next = buf; - while (next < lim) { - - ifm = (struct if_msghdr *)next; - - if (ifm->ifm_type == RTM_IFINFO) { - if (ifm->ifm_data.ifi_datalen == 0) - ifm->ifm_data.ifi_datalen = sizeof(struct if_data); - sdl = (struct sockaddr_dl *)((char *)ifm + sizeof(struct if_msghdr) - - sizeof(struct if_data) + ifm->ifm_data.ifi_datalen); - flags = ifm->ifm_flags; - } else { - fprintf(stderr, "out of sync parsing NET_RT_IFLIST\n"); - fprintf(stderr, "expected %d, got %d\n", RTM_IFINFO, - ifm->ifm_type); - fprintf(stderr, "msglen = %d\n", ifm->ifm_msglen); - fprintf(stderr, "buf:%p, next:%p, lim:%p\n", buf, next, - lim); - exit (1); + if (getifaddrs(&ifap) != 0) + err(EXIT_FAILURE, "getifaddrs"); + cp = NULL; + ifindex = 0; + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + memset(&paifr, 0, sizeof(paifr)); + strncpy(paifr.ifr_name, ifa->ifa_name, sizeof(paifr.ifr_name)); + if (sizeof(paifr.ifr_addr) >= ifa->ifa_addr->sa_len) { + memcpy(&paifr.ifr_addr, ifa->ifa_addr, + ifa->ifa_addr->sa_len); } - next += ifm->ifm_msglen; - ifam = NULL; - addrcount = 0; - while (next < lim) { + if (ifname != NULL && strcmp(ifname, ifa->ifa_name) != 0) + continue; + if (ifa->ifa_addr->sa_family == AF_LINK) + sdl = (const struct sockaddr_dl *) ifa->ifa_addr; + else + sdl = NULL; + if (cp != NULL && strcmp(cp, ifa->ifa_name) == 0) + continue; + if (strlcpy(name, ifa->ifa_name, sizeof(name)) >= sizeof(name)) + continue; + cp = ifa->ifa_name; - nextifm = (struct if_msghdr *)next; - - if (nextifm->ifm_type != RTM_NEWADDR) - break; - - if (ifam == NULL) - ifam = (struct ifa_msghdr *)nextifm; - - addrcount++; - next += nextifm->ifm_msglen; - } - memcpy(name, sdl->sdl_data, - sizeof(name) <= sdl->sdl_nlen ? - sizeof(name)-1 : sdl->sdl_nlen); - name[sizeof(name) <= sdl->sdl_nlen ? - sizeof(name)-1 : sdl->sdl_nlen] = '\0'; - - if (all || namesonly) { - if (uponly) - if ((flags & IFF_UP) == 0) - continue; /* not up */ - if (downonly) - if (flags & IFF_UP) - continue; /* not down */ - if (namesonly) { - if (afp == NULL || afp->af_af != AF_LINK || - sdl->sdl_type == IFT_ETHER) { - if (need_nl) - putchar(' '); - fputs(name, stdout); - need_nl++; - } - continue; - } + if (downonly && (ifa->ifa_flags & IFF_UP) != 0) + continue; + if (uponly && (ifa->ifa_flags & IFF_UP) == 0) + continue; + ifindex++; + /* + * Are we just listing the interfaces? + */ + if (namesonly) { + if (ifindex > 1) + printf(" "); + fputs(name, stdout); + continue; } if (argc > 0) ifconfig(argc, argv, afp); else - status(afp, addrcount, sdl, ifm, ifam); + status(afp, sdl, ifa); } - free(buf); + if (namesonly) + printf("\n"); + freeifaddrs(ifap); - if (namesonly && need_nl > 0) - putchar('\n'); - - exit (0); + exit(0); } static struct afswtch *afs = NULL; @@ -698,6 +644,7 @@ static void setifflags(const char *vname, int value, int s, const struct afswtch *afp) { struct ifreq my_ifr; + int flags; bcopy((char *)&ifr, (char *)&my_ifr, sizeof(struct ifreq)); @@ -722,6 +669,7 @@ setifflags(const char *vname, int value, int s, const struct afswtch *afp) void setifcap(const char *vname, int value, int s, const struct afswtch *afp) { + int flags; if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) < 0) { Perror("ioctl (SIOCGIFCAP)"); @@ -780,25 +728,6 @@ setifname(const char *val, int dummy __unused, int s, free(newname); } -/* - * Expand the compacted form of addresses as returned via the - * configuration read via sysctl(). - */ -static void -rt_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo) -{ - struct sockaddr *sa; - int i; - - memset(rtinfo->rti_info, 0, sizeof(rtinfo->rti_info)); - for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) { - if ((rtinfo->rti_addrs & (1 << i)) == 0) - continue; - rtinfo->rti_info[i] = sa = (struct sockaddr *)cp; - cp += SA_SIZE(sa); - } -} - #define IFFBITS \ "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6SMART\7RUNNING" \ "\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2" \ @@ -813,10 +742,10 @@ rt_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo) * specified, show only it; otherwise, show them all. */ static void -status(const struct afswtch *afp, int addrcount, struct sockaddr_dl *sdl, - struct if_msghdr *ifm, struct ifa_msghdr *ifam) +status(const struct afswtch *afp, const struct sockaddr_dl *sdl, + struct ifaddrs *ifa) { - struct rt_addrinfo info; + struct ifaddrs *ift; int allfamilies, s; struct ifstat ifs; @@ -834,11 +763,11 @@ status(const struct afswtch *afp, int addrcount, struct sockaddr_dl *sdl, err(1, "socket(family %u,SOCK_DGRAM)", ifr.ifr_addr.sa_family); printf("%s: ", name); - printb("flags", flags, IFFBITS); - if (ifm->ifm_data.ifi_metric) - printf(" metric %ld", ifm->ifm_data.ifi_metric); - if (ifm->ifm_data.ifi_mtu) - printf(" mtu %ld", ifm->ifm_data.ifi_mtu); + printb("flags", ifa->ifa_flags, IFFBITS); + if (ioctl(s, SIOCGIFMETRIC, &ifr) != -1) + printf(" metric %d", ifr.ifr_metric); + if (ioctl(s, SIOCGIFMTU, &ifr) != -1) + printf(" mtu %d", ifr.ifr_mtu); putchar('\n'); if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) == 0) { @@ -854,22 +783,20 @@ status(const struct afswtch *afp, int addrcount, struct sockaddr_dl *sdl, tunnel_status(s); - while (addrcount > 0) { - info.rti_addrs = ifam->ifam_addrs; - /* Expand the compacted addresses */ - rt_xaddrs((char *)(ifam + 1), ifam->ifam_msglen + (char *)ifam, - &info); - + for (ift = ifa; ift != NULL; ift = ift->ifa_next) { + if (ift->ifa_addr == NULL) + continue; + if (strcmp(ifa->ifa_name, ift->ifa_name) != 0) + continue; if (allfamilies) { const struct afswtch *p; - p = af_getbyfamily(info.rti_info[RTAX_IFA]->sa_family); + p = af_getbyfamily(ift->ifa_addr->sa_family); if (p != NULL && p->af_status != NULL) - p->af_status(s, &info); - } else if (afp->af_af == info.rti_info[RTAX_IFA]->sa_family) - afp->af_status(s, &info); - addrcount--; - ifam = (struct ifa_msghdr *)((char *)ifam + ifam->ifam_msglen); + p->af_status(s, ift); + } else if (afp->af_af == ift->ifa_addr->sa_family) + afp->af_status(s, ift); } +#if 0 if (allfamilies || afp->af_af == AF_LINK) { const struct afswtch *lafp; @@ -885,6 +812,7 @@ status(const struct afswtch *afp, int addrcount, struct sockaddr_dl *sdl, lafp->af_status(s, &info); } } +#endif if (allfamilies) af_other_status(s); else if (afp->af_other_status != NULL) @@ -954,7 +882,7 @@ printb(const char *s, unsigned v, const char *bits) } void -ifmaybeload(char *name) +ifmaybeload(const char *name) { struct module_stat mstat; int fileid, modid; diff --git a/sbin/ifconfig/ifconfig.h b/sbin/ifconfig/ifconfig.h index 79f1fcb4198f..ef7cec5a28af 100644 --- a/sbin/ifconfig/ifconfig.h +++ b/sbin/ifconfig/ifconfig.h @@ -72,7 +72,7 @@ void callback_register(callback_func *, void *); #define DEF_CMD_OPTARG(name, func) { name, OPTARG, { .c_func = func } } #define DEF_CMD_ARG2(name, func) { name, NEXTARG2, { .c_func2 = func } } -struct rt_addrinfo; +struct ifaddrs; struct addrinfo; enum { @@ -94,7 +94,7 @@ struct afswtch { * is defined then it is invoked after all address status * is presented. */ - void (*af_status)(int, const struct rt_addrinfo *); + void (*af_status)(int, const struct ifaddrs *); void (*af_other_status)(int); /* parse address method */ void (*af_getaddr)(const char *, int); @@ -127,7 +127,6 @@ extern char name[IFNAMSIZ]; /* name of interface */ extern int allmedia; extern int supmedia; extern int printkeys; -extern int flags; extern int newaddr; extern int verbose; extern int setipdst; @@ -137,7 +136,7 @@ void setifcap(const char *, int value, int s, const struct afswtch *); void Perror(const char *cmd); void printb(const char *s, unsigned value, const char *bits); -void ifmaybeload(char *name); +void ifmaybeload(const char *name); typedef void clone_callback_func(int, struct ifreq *); void clone_setcallback(clone_callback_func *);