Subject: Updating arp(8) to use getifaddrs (cf. bin/8566)
To: None <tech-net@netbsd.org>
From: Rafal Boni <rafal@attbi.com>
List: tech-net
Date: 11/07/2002 02:12:04
Folks:
Many moons ago, when I added the ability for arp(8) to print the
names of the interfaces particular addresses were associated with,
I did it the hard way (but probably the only way that would have
worked accross the NetBSD versions I was then interested in) by
using the SIOCGIFCONF and walking the twisty maze of packed data
returned by it.
When I made the changes, I promised to update them to use the
getifaddrs() interface; I finally got around to doing that just
now in a fit of insomnia.
The change is appended (as expected, it's mostly code removal),
but I have a portability question -- is conversion this going
to be more of a portability issue due to the non-standardized
nature of getifaddrs(3), or should I "Just Do it" (yes to both
is acceptable as well 8-).
Thanks,
--rafal
Index: arp.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/arp/arp.c,v
retrieving revision 1.34
diff -b -u -p -r1.34 arp.c
--- arp.c 2002/03/02 03:45:07 1.34
+++ arp.c 2002/11/07 07:01:23
@@ -82,6 +82,7 @@ __RCSID("$NetBSD: arp.c,v 1.34 2002/03/0
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <ifaddrs.h>
int delete __P((const char *, const char *));
void dump __P((u_long));
@@ -101,11 +102,8 @@ void usage __P((void));
static int pid;
static int aflag, nflag, vflag;
static int s = -1;
-static int is = -1;
+static struct ifaddrs* ifaddrs = NULL;
-static struct ifconf ifc;
-static char ifconfbuf[8192];
-
int
main(argc, argv)
int argc;
@@ -663,48 +661,24 @@ getifname(ifindex, ifname)
u_int16_t ifindex;
char* ifname;
{
- int i, idx, siz;
- char ifrbuf[8192];
- struct ifreq ifreq, *ifr;
+ int i;
+ struct ifaddrs *addr;
const struct sockaddr_dl *sdl = NULL;
-
- if (is < 0) {
- is = socket(PF_INET, SOCK_DGRAM, 0);
- if (is < 0)
- err(1, "socket");
- ifc.ifc_len = sizeof(ifconfbuf);
- ifc.ifc_buf = ifconfbuf;
-
- if (ioctl(is, SIOCGIFCONF, &ifc) < 0) {
- close(is);
- err(1, "SIOCGIFCONF");
- is = -1;
- }
+ if (ifaddrs == NULL) {
+ i = getifaddrs(&ifaddrs);
+ if (i != 0)
+ err(1, "getifaddrs");
}
-
- ifr = ifc.ifc_req;
- ifreq.ifr_name[0] = '\0';
- for (i = 0, idx = 0; i < ifc.ifc_len; ) {
- ifr = (struct ifreq *)((caddr_t)ifc.ifc_req + i);
- siz = sizeof(ifr->ifr_name) +
- (ifr->ifr_addr.sa_len > sizeof(struct sockaddr)
- ? ifr->ifr_addr.sa_len
- : sizeof(struct sockaddr));
- i += siz;
- /* avoid alignment issue */
- if (sizeof(ifrbuf) < siz)
- errx(1, "ifr too big");
-
- memcpy(ifrbuf, ifr, siz);
- ifr = (struct ifreq *)ifrbuf;
- if (ifr->ifr_addr.sa_family != AF_LINK)
+ for (addr = ifaddrs; addr; addr = addr->ifa_next) {
+ if (addr->ifa_addr == NULL ||
+ addr->ifa_addr->sa_family != AF_LINK)
continue;
- sdl = (const struct sockaddr_dl *) &ifr->ifr_addr;
+ sdl = (const struct sockaddr_dl *) addr->ifa_addr;
if (sdl && sdl->sdl_index == ifindex) {
- (void) strncpy(ifname, ifr->ifr_name, IFNAMSIZ);
+ (void) strncpy(ifname, addr->ifa_name, IFNAMSIZ);
return 0;
}
}
----
Rafal Boni rafal@attbi.com
We are all worms. But I do believe I am a glowworm. -- Winston Churchill