X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=interfaces.c;h=27ca4382e61be90a7ad65eb53c340409903942c9;hb=812709a155f4e8ca2a6b6070bad027a372835857;hp=1f1aeae7182b6890d8e1ab8a761d5807ef3a9010;hpb=c2b0b328d4a66431e671fb26b47997033feb5e29;p=debian%2Fsudo diff --git a/interfaces.c b/interfaces.c index 1f1aeae..27ca438 100644 --- a/interfaces.c +++ b/interfaces.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 1996, 1998-2003 Todd C. Miller + * Copyright (c) 1996, 1998-2005, 2007-2008 + * Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -19,7 +20,7 @@ */ /* - * Supress a warning w/ gcc on Digital UN*X. + * Suppress a warning w/ gcc on Digital UN*X. * The system headers should really do this.... */ #if defined(__osf__) && !defined(__cplusplus) @@ -27,7 +28,7 @@ struct mbuf; struct rtentry; #endif -#include "config.h" +#include #include #include @@ -59,12 +60,8 @@ struct rtentry; #ifdef HAVE_UNISTD_H # include #endif /* HAVE_UNISTD_H */ -#ifdef HAVE_ERR_H -# include -#else -# include "emul/err.h" -#endif /* HAVE_ERR_H */ #include +#include #ifdef _ISC # include # include @@ -88,7 +85,7 @@ struct rtentry; #include "interfaces.h" #ifndef lint -static const char rcsid[] = "$Sudo: interfaces.c,v 1.72 2004/02/13 21:36:43 millert Exp $"; +__unused static const char rcsid[] = "$Sudo: interfaces.c,v 1.84 2008/11/09 14:13:12 millert Exp $"; #endif /* lint */ @@ -102,8 +99,10 @@ void load_interfaces() { struct ifaddrs *ifa, *ifaddrs; - /* XXX - sockaddr_in6 sin6; */ struct sockaddr_in *sin; +#ifdef HAVE_IN6_ADDR + struct sockaddr_in6 *sin6; +#endif int i; if (getifaddrs(&ifaddrs)) @@ -117,8 +116,10 @@ load_interfaces() continue; switch(ifa->ifa_addr->sa_family) { - /* XXX - AF_INET6 */ case AF_INET: +#ifdef HAVE_IN6_ADDR + case AF_INET6: +#endif num_interfaces++; break; } @@ -136,7 +137,6 @@ load_interfaces() continue; switch(ifa->ifa_addr->sa_family) { - /* XXX - AF_INET6 */ case AF_INET: sin = (struct sockaddr_in *)ifa->ifa_addr; memcpy(&interfaces[i].addr, &sin->sin_addr, @@ -144,14 +144,27 @@ load_interfaces() sin = (struct sockaddr_in *)ifa->ifa_netmask; memcpy(&interfaces[i].netmask, &sin->sin_addr, sizeof(struct in_addr)); + interfaces[i].family = AF_INET; i++; break; +#ifdef HAVE_IN6_ADDR + case AF_INET6: + sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; + memcpy(&interfaces[i].addr, &sin6->sin6_addr, + sizeof(struct in6_addr)); + sin6 = (struct sockaddr_in6 *)ifa->ifa_netmask; + memcpy(&interfaces[i].netmask, &sin6->sin6_addr, + sizeof(struct in6_addr)); + interfaces[i].family = AF_INET6; + i++; + break; +#endif /* HAVE_IN6_ADDR */ } } #ifdef HAVE_FREEIFADDRS freeifaddrs(ifaddrs); #else - free(ifaddrs); + efree(ifaddrs); #endif } @@ -176,7 +189,7 @@ load_interfaces() sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) - err(1, "cannot open socket"); + error(1, "cannot open socket"); /* * Get interface configuration or return (leaving num_interfaces == 0) @@ -187,14 +200,14 @@ load_interfaces() ifconf->ifc_len = len - sizeof(struct ifconf); ifconf->ifc_buf = (caddr_t) (ifconf_buf + sizeof(struct ifconf)); - /* Networking may not be installed in kernel... */ #ifdef _ISC STRSET(SIOCGIFCONF, (caddr_t) ifconf, len); if (ioctl(sock, I_STR, (caddr_t) &strioctl) < 0) { #else - if (ioctl(sock, SIOCGIFCONF, (caddr_t) ifconf) < 0) { + /* Note that some kernels return EINVAL if the buffer is too small */ + if (ioctl(sock, SIOCGIFCONF, (caddr_t) ifconf) < 0 && errno != EINVAL) { #endif /* _ISC */ - free(ifconf_buf); + efree(ifconf_buf); (void) close(sock); return; } @@ -232,7 +245,7 @@ load_interfaces() continue; #ifdef SIOCGIFFLAGS - memset(&ifr_tmp, 0, sizeof(ifr_tmp)); + zero_bytes(&ifr_tmp, sizeof(ifr_tmp)); strncpy(ifr_tmp.ifr_name, ifr->ifr_name, sizeof(ifr_tmp.ifr_name) - 1); if (ioctl(sock, SIOCGIFFLAGS, (caddr_t) &ifr_tmp) < 0) #endif @@ -244,13 +257,13 @@ load_interfaces() continue; sin = (struct sockaddr_in *) &ifr->ifr_addr; - interfaces[num_interfaces].addr.s_addr = sin->sin_addr.s_addr; + interfaces[num_interfaces].addr.ip4.s_addr = sin->sin_addr.s_addr; /* Stash the name of the interface we saved. */ previfname = ifr->ifr_name; /* Get the netmask. */ - (void) memset(&ifr_tmp, 0, sizeof(ifr_tmp)); + zero_bytes(&ifr_tmp, sizeof(ifr_tmp)); strncpy(ifr_tmp.ifr_name, ifr->ifr_name, sizeof(ifr_tmp.ifr_name) - 1); #ifdef SIOCGIFNETMASK #ifdef _ISC @@ -261,20 +274,21 @@ load_interfaces() #endif /* _ISC */ sin = (struct sockaddr_in *) &ifr_tmp.ifr_addr; - interfaces[num_interfaces].netmask.s_addr = sin->sin_addr.s_addr; + interfaces[num_interfaces].netmask.ip4.s_addr = sin->sin_addr.s_addr; } else { #else { #endif /* SIOCGIFNETMASK */ - if (IN_CLASSC(interfaces[num_interfaces].addr.s_addr)) - interfaces[num_interfaces].netmask.s_addr = htonl(IN_CLASSC_NET); - else if (IN_CLASSB(interfaces[num_interfaces].addr.s_addr)) - interfaces[num_interfaces].netmask.s_addr = htonl(IN_CLASSB_NET); + if (IN_CLASSC(interfaces[num_interfaces].addr.ip4.s_addr)) + interfaces[num_interfaces].netmask.ip4.s_addr = htonl(IN_CLASSC_NET); + else if (IN_CLASSB(interfaces[num_interfaces].addr.ip4.s_addr)) + interfaces[num_interfaces].netmask.ip4.s_addr = htonl(IN_CLASSB_NET); else - interfaces[num_interfaces].netmask.s_addr = htonl(IN_CLASSA_NET); + interfaces[num_interfaces].netmask.ip4.s_addr = htonl(IN_CLASSA_NET); } /* Only now can we be sure it was a good/interesting interface. */ + interfaces[num_interfaces].family = AF_INET; num_interfaces++; } @@ -284,9 +298,9 @@ load_interfaces() interfaces = (struct interface *) erealloc3(interfaces, num_interfaces, sizeof(struct interface)); else - free(interfaces); + efree(interfaces); } - free(ifconf_buf); + efree(ifconf_buf); (void) close(sock); } @@ -307,9 +321,26 @@ void dump_interfaces() { int i; +#ifdef HAVE_IN6_ADDR + char addrbuf[INET6_ADDRSTRLEN], maskbuf[INET6_ADDRSTRLEN]; +#endif puts("Local IP address and netmask pairs:"); - for (i = 0; i < num_interfaces; i++) - printf("\t%s / 0x%x\n", inet_ntoa(interfaces[i].addr), - (unsigned int)ntohl(interfaces[i].netmask.s_addr)); + for (i = 0; i < num_interfaces; i++) { + switch(interfaces[i].family) { + case AF_INET: + printf("\t%s / ", inet_ntoa(interfaces[i].addr.ip4)); + puts(inet_ntoa(interfaces[i].netmask.ip4)); + break; +#ifdef HAVE_IN6_ADDR + case AF_INET6: + inet_ntop(AF_INET6, &interfaces[i].addr.ip6, + addrbuf, sizeof(addrbuf)); + inet_ntop(AF_INET6, &interfaces[i].netmask.ip6, + maskbuf, sizeof(maskbuf)); + printf("\t%s / %s\n", addrbuf, maskbuf); + break; +#endif /* HAVE_IN6_ADDR */ + } + } }