OpenBSD: fix lookup of network interfaces
[openafs.git] / src / rx / rx_getaddr.c
index ad8751c..928ae17 100644 (file)
@@ -10,9 +10,7 @@
 #include <afsconfig.h>
 #include <afs/param.h>
 
-RCSID("$Header$");
 
-#ifndef AFS_DJGPP_ENV
 #ifndef KERNEL
 #ifndef AFS_NT40_ENV
 #include <sys/types.h>
@@ -21,7 +19,8 @@ RCSID("$Header$");
 #include <net/if.h>
 #include <netinet/in.h>
 #include <sys/ioctl.h>
-#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
+#include <string.h>
+#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
 #include <sys/sysctl.h>
 #include <net/route.h>
 #include <net/if_dl.h>
@@ -32,30 +31,39 @@ RCSID("$Header$");
  * the pthreads for solaris requires the socket call to be mapped.
  */
 #include "rx.h"
-#endif
-#else  /* KERNEL */
+#include "rx_globals.h"
+#endif /* AFS_NT40_ENV */
+#else /* KERNEL */
 #ifdef UKERNEL
-#include "../rx/rx_kcommon.h"
+#include "rx/rx_kcommon.h"
 #else /* UKERNEL */
-/* nothing here required yet */
+#include "rx/rx.h"
 #endif /* UKERNEL */
-#endif /* KERNEL */
+#endif /* KERNEL */
 
 #define NIFS           512
 
+#if defined(AFS_USR_DFBSD_ENV)
+#include <net/if.h>
+#include <sys/sockio.h>
+#endif
+
 #ifdef KERNEL
 /* only used for generating random noise */
 
-afs_int32 rxi_tempAddr=0;      /* default attempt */
+afs_uint32 rxi_tempAddr = 0;   /* default attempt */
 
 /* set the advisory noise */
-afs_int32 rxi_setaddr(x)
-afs_int32 x;{
+void
+rxi_setaddr(afs_uint32 x)
+{
     rxi_tempAddr = x;
 }
 
 /* get approx to net addr */
-afs_int32 rxi_getaddr() {
+afs_uint32
+rxi_getaddr(void)
+{
     return rxi_tempAddr;
 }
 
@@ -64,10 +72,9 @@ afs_int32 rxi_getaddr() {
 #ifndef KERNEL
 
 /* to satisfy those who call setaddr */
-int
-rxi_setaddr(x)
-afs_int32 x; {
-    return 0;
+void
+rxi_setaddr(afs_uint32 x)
+{
 }
 
 #endif /* !KERNEL */
@@ -83,16 +90,17 @@ afs_int32 x; {
 /* Return our internet address as a long in network byte order.  Returns zero
  * if it can't find one.
  */
-afs_int32 rxi_getaddr ()
+afs_uint32
+rxi_getaddr(void)
 {
-       afs_int32       buffer[1024];
-       int     count;
-
-       count = rx_getAllAddr(buffer, 1024); 
-       if ( count > 0 )
-               return buffer[0]; /* returns the first address */
-       else
-               return count;
+    afs_uint32 buffer[1024];
+    int count;
+
+    count = rx_getAllAddr(buffer, 1024);
+    if (count > 0)
+       return buffer[0];       /* returns the first address */
+    else
+       return count;
 }
 
 #endif /* !KERNEL */
@@ -108,26 +116,24 @@ afs_int32 rxi_getaddr ()
 #undef socket
 #endif /* UKERNEL */
 
-#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
+#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
 #define ROUNDUP(a) \
         ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
 
 static void
-rt_xaddrs(cp, cplim, rtinfo)
-        caddr_t cp, cplim;
-        struct rt_addrinfo *rtinfo;
+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;
-                ADVANCE(cp, sa);
-        }
+    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;
+       ADVANCE(cp, sa);
+    }
 }
 #endif
 
@@ -135,200 +141,244 @@ rt_xaddrs(cp, cplim, rtinfo)
 /* this function returns the total number of interface addresses 
 ** the buffer has to be passed in by the caller
 */
-#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
-int rx_getAllAddr (buffer,maxSize)
-afs_int32      buffer[];
-int    maxSize;        /* sizeof of buffer in afs_int32 units */
+#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
+#if defined(AFS_OBSD42_ENV)
+void
+ifm_fixversion(char *buffer, size_t *size) {
+    struct if_msghdr *ifm;
+    char *b = buffer;
+    char *s, *t;
+
+    if ((t = malloc(*size)) != NULL) {
+       memcpy(t, buffer, *size);
+
+       for (s = t; s < t + *size; s += ifm->ifm_msglen) {
+           ifm = (struct if_msghdr *)s;
+
+           if (ifm->ifm_version == RTM_VERSION) {
+               memcpy(b, ifm, ifm->ifm_msglen);
+               b += ifm->ifm_msglen;
+           }
+       }
+
+       free(t);
+
+       *size = b - buffer;
+    }
+}
+#endif
+
+int
+rx_getAllAddr_internal(afs_uint32 buffer[], int maxSize, int loopbacks)
 {
-     size_t needed;
-     int mib[6];
-     struct  if_msghdr *ifm, *nextifm;
-     struct  ifa_msghdr *ifam;
-     struct  sockaddr_dl *sdl;
-     struct  rt_addrinfo info;
-     char    *buf, *lim, *next;
-     int count=0,addrcount=0;
-     
-     mib[0] = CTL_NET;
-     mib[1] = PF_ROUTE;
-     mib[2] = 0;
-     mib[3] = AF_INET;     /* address family */
-     mib[4] = NET_RT_IFLIST;
-     mib[5] = 0;
-     if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
-          return 0;
-     if ((buf = malloc(needed)) == NULL)
-          return 0;
-     if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
-          free(buf);
-          return 0;
-     }
-     lim = buf + needed;
-     next = buf;
-     while (next < lim) {
-          ifm = (struct if_msghdr *)next;
-          if (ifm->ifm_type != RTM_IFINFO) {
-               printf("out of sync parsing NET_RT_IFLIST\n");
-               free(buf);
-               return 0;
-          }
-          sdl = (struct sockaddr_dl *)(ifm + 1);
-          next += ifm->ifm_msglen;
-          ifam = NULL;
-          addrcount = 0;
-          while (next < lim) {
-               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;
-          }
-          if ((ifm->ifm_flags & IFF_UP) == 0)
-               continue; /* not up */
-          if (ifm->ifm_flags & IFF_LOOPBACK) {
-               continue;        /* skip aliased loopbacks as well. */
-          }
-          while (addrcount > 0) {
-               struct sockaddr_in *a;
-               
-               info.rti_addrs = ifam->ifam_addrs;
-               
-               /* Expand the compacted addresses */
-               rt_xaddrs((char *)(ifam + 1), ifam->ifam_msglen + (char *)ifam,
-                         &info);
-               if (info.rti_info[RTAX_IFA]->sa_family != AF_INET)
-                    continue;
-               a=info.rti_info[RTAX_IFA];
-               
-               if ( count >= maxSize )  /* no more space */
-                    printf("Too many interfaces..ignoring 0x%x\n",
-                           a->sin_addr.s_addr);
-               else
-                    buffer[count++] = a->sin_addr.s_addr;
-               addrcount--;
-               ifam = (struct ifa_msghdr *)((char *)ifam + ifam->ifam_msglen);
-          }
-     }
-     free(buf);
-     return count;
+    size_t needed;
+    int mib[6];
+    struct if_msghdr *ifm, *nextifm;
+    struct ifa_msghdr *ifam;
+    struct sockaddr_dl *sdl;
+    struct rt_addrinfo info;
+    char *buf, *lim, *next;
+    int count = 0, addrcount = 0;
+
+    mib[0] = CTL_NET;
+    mib[1] = PF_ROUTE;
+    mib[2] = 0;
+    mib[3] = AF_INET;          /* address family */
+    mib[4] = NET_RT_IFLIST;
+    mib[5] = 0;
+    if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
+       return 0;
+    if ((buf = malloc(needed)) == NULL)
+       return 0;
+    if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
+       free(buf);
+       return 0;
+    }
+#if defined(AFS_OBSD42_ENV)
+    ifm_fixversion(buf, &needed);
+#endif
+    lim = buf + needed;
+    next = buf;
+    while (next < lim) {
+       ifm = (struct if_msghdr *)next;
+       if (ifm->ifm_type != RTM_IFINFO) {
+           dpf(("out of sync parsing NET_RT_IFLIST\n"));
+           free(buf);
+           return 0;
+       }
+       sdl = (struct sockaddr_dl *)(ifm + 1);
+       next += ifm->ifm_msglen;
+       ifam = NULL;
+       addrcount = 0;
+       while (next < lim) {
+           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;
+       }
+       if ((ifm->ifm_flags & IFF_UP) == 0)
+           continue;           /* not up */
+       while (addrcount > 0) {
+           struct sockaddr_in *a;
+
+           info.rti_addrs = ifam->ifam_addrs;
+
+           /* Expand the compacted addresses */
+           rt_xaddrs((char *)(ifam + 1), ifam->ifam_msglen + (char *)ifam,
+                     &info);
+           if (info.rti_info[RTAX_IFA]->sa_family != AF_INET) {
+               addrcount--;
+               continue;
+           }
+           a = (struct sockaddr_in *) info.rti_info[RTAX_IFA];
+
+           if (count >= maxSize)       /* no more space */
+               dpf(("Too many interfaces..ignoring 0x%x\n",
+                      a->sin_addr.s_addr));
+           else if (!loopbacks && a->sin_addr.s_addr == htonl(0x7f000001)) {
+               addrcount--;
+               continue;       /* skip loopback address as well. */
+           } else if (loopbacks && ifm->ifm_flags & IFF_LOOPBACK) {
+               addrcount--;
+               continue;       /* skip aliased loopbacks as well. */
+           } else
+               buffer[count++] = a->sin_addr.s_addr;
+           addrcount--;
+           ifam = (struct ifa_msghdr *)((char *)ifam + ifam->ifam_msglen);
+       }
+    }
+    free(buf);
+    return count;
 }
-int rxi_getAllAddrMaskMtu (addrBuffer, maskBuffer, mtuBuffer, maxSize)
-   afs_int32   addrBuffer[];   /* the network addrs in net byte order */
-   afs_int32   maskBuffer[];   /* the subnet masks */
-   afs_int32   mtuBuffer[];    /* the MTU sizes */
-   int     maxSize;        /* sizeof of buffer in afs_int32 units */
+
+int
+rx_getAllAddrMaskMtu(afs_uint32 addrBuffer[], afs_uint32 maskBuffer[],
+                    afs_uint32 mtuBuffer[], int maxSize)
 {
-    int     s;
-     
-     size_t needed;
-     int mib[6];
-     struct  if_msghdr *ifm, *nextifm;
-     struct  ifa_msghdr *ifam;
-     struct  sockaddr_dl *sdl;
-     struct  rt_addrinfo info;
-     char    *buf, *lim, *next;
-     int count=0,addrcount=0;
-
-     mib[0] = CTL_NET;
-     mib[1] = PF_ROUTE;
-     mib[2] = 0;
-     mib[3] = AF_INET;     /* address family */
-     mib[4] = NET_RT_IFLIST;
-     mib[5] = 0;
-     if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
-          return 0;
-     if ((buf = malloc(needed)) == NULL)
-          return 0;
-     if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
-          free(buf);
-          return 0;
-     }
-     s=socket(PF_INET, SOCK_DGRAM, 0);
-     if (s < 0)
-          return 0;
-     lim = buf + needed;
-     next = buf;
-     while (next < lim) {
-          ifm = (struct if_msghdr *)next;
-          if (ifm->ifm_type != RTM_IFINFO) {
-               printf("out of sync parsing NET_RT_IFLIST\n");
-               free(buf);
-               return 0;
-          }
-          sdl = (struct sockaddr_dl *)(ifm + 1);
-          next += ifm->ifm_msglen;
-          ifam = NULL;
-          addrcount = 0;
-          while (next < lim) {
-               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;
-          }
-          if ((ifm->ifm_flags & IFF_UP) == 0)
-               continue; /* not up */
-          if (ifm->ifm_flags & IFF_LOOPBACK) {
-               continue;        /* skip aliased loopbacks as well. */
-          }
-          while (addrcount > 0) {
-               struct sockaddr_in *a;
-               
-               info.rti_addrs = ifam->ifam_addrs;
-               
-               /* Expand the compacted addresses */
-               rt_xaddrs((char *)(ifam + 1), ifam->ifam_msglen + (char *)ifam,
-                         &info);
-               if (info.rti_info[RTAX_IFA]->sa_family != AF_INET)
-                    continue;
-               a=info.rti_info[RTAX_IFA];
-               
-               if ( count >= maxSize ) {  /* no more space */
-                    printf("Too many interfaces..ignoring 0x%x\n",
-                           a->sin_addr.s_addr);
-               } else {
-                    struct ifreq ifr;
-                    
-                    addrBuffer[count] = a->sin_addr.s_addr;
-                    a=info.rti_info[RTAX_NETMASK];
-                    if (a)
-                         maskBuffer[count]=a->sin_addr.s_addr;
-                    else
-                         maskBuffer[count] = htonl(0xffffffff);
-                    memset(&ifr, sizeof(ifr), 0);
-                    ifr.ifr_addr.sa_family=AF_INET;
-                    strncpy(ifr.ifr_name, sdl->sdl_data, sdl->sdl_nlen);
-                    if (ioctl(s, SIOCGIFMTU, (caddr_t)&ifr) < 0)
-                         mtuBuffer[count]=1500;
-                    else
-                         mtuBuffer[count]=ifr.ifr_mtu;
-                    count++;
-               }
-               addrcount--;
-               ifam = (struct ifa_msghdr *)((char *)ifam + ifam->ifam_msglen);
-          }
-     }
-     free(buf);
-     return count;
+    int s;
+
+    size_t needed;
+    int mib[6];
+    struct if_msghdr *ifm, *nextifm;
+    struct ifa_msghdr *ifam;
+    struct sockaddr_dl *sdl;
+    struct rt_addrinfo info;
+    char *buf, *lim, *next;
+    int count = 0, addrcount = 0;
+
+    mib[0] = CTL_NET;
+    mib[1] = PF_ROUTE;
+    mib[2] = 0;
+    mib[3] = AF_INET;          /* address family */
+    mib[4] = NET_RT_IFLIST;
+    mib[5] = 0;
+    if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
+       return 0;
+    if ((buf = malloc(needed)) == NULL)
+       return 0;
+    if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
+       free(buf);
+       return 0;
+    }
+#if defined(AFS_OBSD42_ENV)
+    ifm_fixversion(buf, &needed);
+#endif
+    s = socket(PF_INET, SOCK_DGRAM, 0);
+    if (s < 0)
+       return 0;
+    lim = buf + needed;
+    next = buf;
+    while (next < lim) {
+       ifm = (struct if_msghdr *)next;
+       if (ifm->ifm_type != RTM_IFINFO) {
+           dpf(("out of sync parsing NET_RT_IFLIST\n"));
+           free(buf);
+           return 0;
+       }
+       sdl = (struct sockaddr_dl *)(ifm + 1);
+       next += ifm->ifm_msglen;
+       ifam = NULL;
+       addrcount = 0;
+       while (next < lim) {
+           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;
+       }
+       if ((ifm->ifm_flags & IFF_UP) == 0)
+           continue;           /* not up */
+       while (addrcount > 0) {
+           struct sockaddr_in *a;
+
+           info.rti_addrs = ifam->ifam_addrs;
+
+           /* Expand the compacted addresses */
+           rt_xaddrs((char *)(ifam + 1), ifam->ifam_msglen + (char *)ifam,
+                     &info);
+           if (info.rti_info[RTAX_IFA]->sa_family != AF_INET) {
+               addrcount--;
+               continue;
+           }
+           a = (struct sockaddr_in *) info.rti_info[RTAX_IFA];
+
+           if (a->sin_addr.s_addr != htonl(0x7f000001) ) {
+               if (count >= maxSize) { /* no more space */
+                   dpf(("Too many interfaces..ignoring 0x%x\n",
+                          a->sin_addr.s_addr));
+               } else {
+                   struct ifreq ifr;
+                   
+                   addrBuffer[count] = a->sin_addr.s_addr;
+                   a = (struct sockaddr_in *) info.rti_info[RTAX_NETMASK];
+                   if (a)
+                       maskBuffer[count] = a->sin_addr.s_addr;
+                   else
+                       maskBuffer[count] = htonl(0xffffffff);
+                   memset(&ifr, 0, sizeof(ifr));
+                   ifr.ifr_addr.sa_family = AF_INET;
+                   strncpy(ifr.ifr_name, sdl->sdl_data, sdl->sdl_nlen);
+                   if (ioctl(s, SIOCGIFMTU, (caddr_t) & ifr) < 0)
+                       mtuBuffer[count] = htonl(1500);
+                   else
+                       mtuBuffer[count] = htonl(ifr.ifr_mtu);
+                   count++;
+               }
+           }
+           addrcount--;
+           ifam = (struct ifa_msghdr *)((char *)ifam + ifam->ifam_msglen);
+       }
+    }
+    free(buf);
+    return count;
 }
 
-     
-#else
-int rx_getAllAddr (buffer,maxSize)
-afs_int32      buffer[];
-int    maxSize;        /* sizeof of buffer in afs_int32 units */
+
+int
+rx_getAllAddr(afs_uint32 buffer[], int maxSize)
 {
-    int     s;
-    int     i, len, count=0;
-    struct ifconf   ifc;
-    struct ifreq    ifs[NIFS], *ifr;
+    return rx_getAllAddr_internal(buffer, maxSize, 0);
+}
+/* this function returns the total number of interface addresses
+** the buffer has to be passed in by the caller
+*/
+#else /* UKERNEL indirectly, on DARWIN or XBSD */
+static int
+rx_getAllAddr_internal(afs_uint32 buffer[], int maxSize, int loopbacks)
+{
+    int s;
+    int i, len, count = 0;
+    struct ifconf ifc;
+    struct ifreq ifs[NIFS], *ifr;
     struct sockaddr_in *a;
-#if     defined(AFS_AIX41_ENV) || defined(AFS_USR_AIX_ENV)
-    char       *cp, *cplim;    /* used only for AIX 41 */
+    /* can't ever be AFS_DARWIN_ENV or AFS_XBSD_ENV, no? */
+#if    defined(AFS_AIX41_ENV) || defined (AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
+    char *cp, *cplim, *cpnext; /* used only for AIX 41 */
 #endif
 
     s = socket(AF_INET, SOCK_DGRAM, 0);
@@ -342,35 +392,51 @@ int    maxSize;        /* sizeof of buffer in afs_int32 units */
     len = ifc.ifc_len / sizeof(struct ifreq);
     if (len > NIFS)
        len = NIFS;
-#if    defined(AFS_AIX41_ENV) || defined (AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
-    if ( ifc.ifc_len > sizeof(ifs) )   /* safety check */
-       ifc.ifc_len = sizeof(ifs); 
-    for ( cp = (char *)ifc.ifc_buf, 
-               cplim= ifc.ifc_buf+ifc.ifc_len;
-               cp < cplim;
-#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
-               cp += _SIZEOF_ADDR_IFREQ(*ifr))
+#if    defined(AFS_AIX41_ENV) || defined (AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
+    if (ifc.ifc_len > sizeof(ifs))     /* safety check */
+       ifc.ifc_len = sizeof(ifs);
+    for (cp = (char *)ifc.ifc_buf, cplim = ifc.ifc_buf + ifc.ifc_len;
+        cp < cplim;
+#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
+        cp += _SIZEOF_ADDR_IFREQ(*ifr)
 #else
-                cp += sizeof(ifr->ifr_name) + MAX(a->sin_len, sizeof(*a)))
+#ifdef AFS_AIX51_ENV
+        cp = cpnext
+#else
+        cp += sizeof(ifr->ifr_name) + MAX(a->sin_len, sizeof(*a))
+#endif
 #endif
-       {
+       ) 
+#else
+    for (i = 0; i < len; ++i) 
+#endif
+    {
+#if    defined(AFS_AIX41_ENV) || defined (AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
        ifr = (struct ifreq *)cp;
 #else
-    for (i = 0; i < len; ++i) {
        ifr = &ifs[i];
 #endif
-       a = (struct sockaddr_in *) &ifr->ifr_addr;
-       if (a->sin_addr.s_addr != 0 && a->sin_family == AF_INET) {
-           if ( ioctl(s, SIOCGIFFLAGS, ifr) < 0 ) {
-               perror("SIOCGIFFLAGS");
-               continue; /* ignore this address */
-           }
-           if (ifr->ifr_flags & IFF_LOOPBACK) {
-               continue;        /* skip aliased loopbacks as well. */
+       a = (struct sockaddr_in *)&ifr->ifr_addr;
+#ifdef AFS_AIX51_ENV
+       cpnext = cp + sizeof(ifr->ifr_name) + MAX(a->sin_len, sizeof(*a));
+#endif
+       if (a->sin_family != AF_INET)
+           continue;
+       if (ioctl(s, SIOCGIFFLAGS, ifr) < 0) {
+           perror("SIOCGIFFLAGS");
+           continue;           /* ignore this address */
+       }
+       if (a->sin_addr.s_addr != 0) {
+            if (!loopbacks) {
+                if (a->sin_addr.s_addr == htonl(0x7f000001)) 
+                   continue;   /* skip loopback address as well. */
+            } else {
+                if (ifr->ifr_flags & IFF_LOOPBACK) 
+                   continue;   /* skip aliased loopbacks as well. */
            }
-           if ( count >= maxSize )  /* no more space */
-               printf("Too many interfaces..ignoring 0x%x\n",
-                      a->sin_addr.s_addr);
+           if (count >= maxSize)       /* no more space */
+               dpf(("Too many interfaces..ignoring 0x%x\n",
+                      a->sin_addr.s_addr));
            else
                buffer[count++] = a->sin_addr.s_addr;
        }
@@ -379,112 +445,119 @@ int    maxSize;        /* sizeof of buffer in afs_int32 units */
     return count;
 }
 
+int
+rx_getAllAddr(afs_uint32 buffer[], int maxSize)
+{
+    return rx_getAllAddr_internal(buffer, maxSize, 0);
+}
+
 /* this function returns the total number of interface addresses
  * the buffer has to be passed in by the caller. It also returns
  * the interface mask. If AFS_USERSPACE_IP_ADDR is defined, it
  * gets the mask which is then passed into the kernel and is used
  * by afsi_SetServerIPRank().
  */
-int rxi_getAllAddrMaskMtu (addrBuffer, maskBuffer, mtuBuffer, maxSize)
-   afs_int32   addrBuffer[];   /* the network addrs in net byte order */
-   afs_int32   maskBuffer[];   /* the subnet masks */
-   afs_int32   mtuBuffer[];    /* the MTU sizes */
-   int     maxSize;        /* sizeof of buffer in afs_int32 units */
+int
+rx_getAllAddrMaskMtu(afs_uint32 addrBuffer[], afs_uint32 maskBuffer[],
+                     afs_uint32 mtuBuffer[], int maxSize)
 {
-   int     s;
-   int     i, len, count=0;
-   struct ifconf   ifc;
-   struct ifreq    ifs[NIFS], *ifr;
-   struct sockaddr_in *a;
+    int i, count = 0;
+#if defined(AFS_USERSPACE_IP_ADDR)
+    int s, len;
+    struct ifconf ifc;
+    struct ifreq ifs[NIFS], *ifr;
+    struct sockaddr_in *a;
+#endif
+
 #if     defined(AFS_AIX41_ENV) || defined(AFS_USR_AIX_ENV)
-   char        *cp, *cplim;    /* used only for AIX 41 */
+    char *cp, *cplim;          /* used only for AIX 41 */
 #endif
 
 #if !defined(AFS_USERSPACE_IP_ADDR)
-   count = rx_getAllAddr(addrBuffer, 1024);
-   for (i=0; i<count; i++) {
-      maskBuffer[i] = htonl(0xffffffff);
-      mtuBuffer[i]  = htonl(1500);
-   }
-   return count;
-#else  /* AFS_USERSPACE_IP_ADDR */
-   s = socket(AF_INET, SOCK_DGRAM, 0);
-   if (s < 0) return 0;
-
-   ifc.ifc_len = sizeof(ifs);
-   ifc.ifc_buf = (caddr_t) ifs;
-   i = ioctl(s, SIOCGIFCONF, &ifc);
-   if (i < 0) {
-      close(s);
-      return 0;
-   }
-   len = ifc.ifc_len / sizeof(struct ifreq);
-   if (len > NIFS) len = NIFS;
+    count = rx_getAllAddr_internal(addrBuffer, 1024, 0);
+    for (i = 0; i < count; i++) {
+       maskBuffer[i] = htonl(0xffffffff);
+       mtuBuffer[i] = htonl(1500);
+    }
+    return count;
+#else /* AFS_USERSPACE_IP_ADDR */
+    s = socket(AF_INET, SOCK_DGRAM, 0);
+    if (s < 0)
+       return 0;
+
+    ifc.ifc_len = sizeof(ifs);
+    ifc.ifc_buf = (caddr_t) ifs;
+    i = ioctl(s, SIOCGIFCONF, &ifc);
+    if (i < 0) {
+       close(s);
+       return 0;
+    }
+    len = ifc.ifc_len / sizeof(struct ifreq);
+    if (len > NIFS)
+       len = NIFS;
 
 #if     defined(AFS_AIX41_ENV) || defined(AFS_USR_AIX_ENV)
-   if ( ifc.ifc_len > sizeof(ifs) )    /* safety check */
-     ifc.ifc_len = sizeof(ifs);
-   for ( cp = (char *)ifc.ifc_buf,
-       cplim= ifc.ifc_buf+ifc.ifc_len;
-       cp < cplim;
-       cp += sizeof(ifr->ifr_name) + MAX(a->sin_len, sizeof(*a))) {
-      ifr = (struct ifreq *)cp;
+    if (ifc.ifc_len > sizeof(ifs))     /* safety check */
+       ifc.ifc_len = sizeof(ifs);
+    for (cp = (char *)ifc.ifc_buf, cplim = ifc.ifc_buf + ifc.ifc_len;
+        cp < cplim;
+        cp += sizeof(ifr->ifr_name) + MAX(a->sin_len, sizeof(*a))) {
+       ifr = (struct ifreq *)cp;
 #else
-   for (i = 0; i < len; ++i) {
-      ifr = &ifs[i];
+    for (i = 0; i < len; ++i) {
+       ifr = &ifs[i];
 #endif
-      a = (struct sockaddr_in *) &ifr->ifr_addr;
-      if (a->sin_addr.s_addr != 0 && a->sin_family == AF_INET) {
+       a = (struct sockaddr_in *)&ifr->ifr_addr;
+       if (a->sin_addr.s_addr != 0 && a->sin_family == AF_INET) {
 
-        if ( ioctl(s, SIOCGIFFLAGS, ifr) < 0 ) {
-           perror("SIOCGIFFLAGS");
-           continue; /* ignore this address */
-        }
-        if (ifr->ifr_flags & IFF_LOOPBACK) {
-           continue;    /* skip aliased loopbacks as well. */
-        }
-
-        if ( count >= maxSize ) { /* no more space */
-           printf("Too many interfaces..ignoring 0x%x\n", a->sin_addr.s_addr);
-           continue;
-        }
+           if (ioctl(s, SIOCGIFFLAGS, ifr) < 0) {
+               perror("SIOCGIFFLAGS");
+               continue;       /* ignore this address */
+           }
 
-        addrBuffer[count] = a->sin_addr.s_addr;
+            if (a->sin_addr.s_addr == htonl(0x7f000001) )
+                continue;   /* skip loopback address as well. */
+
+           if (count >= maxSize) {     /* no more space */
+               dpf(("Too many interfaces..ignoring 0x%x\n",
+                      a->sin_addr.s_addr));
+               continue;
+           }
 
-        if ( ioctl(s, SIOCGIFNETMASK, (caddr_t)ifr) < 0 ) {
-           perror("SIOCGIFNETMASK");
-           maskBuffer[count] = htonl(0xffffffff);
-        } else {
-           maskBuffer[count] = (((struct sockaddr_in *)
-                                 (&ifr->ifr_addr))->sin_addr).s_addr;
-        }
+           addrBuffer[count] = a->sin_addr.s_addr;
 
-        mtuBuffer[count] = htonl(1500);
+           if (ioctl(s, SIOCGIFNETMASK, (caddr_t) ifr) < 0) {
+               perror("SIOCGIFNETMASK");
+               maskBuffer[count] = htonl(0xffffffff);
+           } else {
+               maskBuffer[count] = (((struct sockaddr_in *)
+                                     (&ifr->ifr_addr))->sin_addr).s_addr;
+           }
+
+           mtuBuffer[count] = htonl(1500);
 #ifdef SIOCGIFMTU
-        if ( ioctl(s, SIOCGIFMTU, (caddr_t)ifr) < 0) {
-           perror("SIOCGIFMTU");
-        } else {
-           mtuBuffer[count] = ifr->ifr_metric;
-        }
+           if (ioctl(s, SIOCGIFMTU, (caddr_t) ifr) < 0) {
+               perror("SIOCGIFMTU");
+           } else {
+               mtuBuffer[count] = htonl(ifr->ifr_metric);
+           }
 #endif /* SIOCGIFMTU */
 #ifdef SIOCRIPMTU
-        if ( ioctl(s, SIOCRIPMTU, (caddr_t)ifr) < 0) {
-           perror("SIOCRIPMTU");
-        } else {
-           mtuBuffer[count] = ifr->ifr_metric;
-        }
+           if (ioctl(s, SIOCRIPMTU, (caddr_t) ifr) < 0) {
+               perror("SIOCRIPMTU");
+           } else {
+               mtuBuffer[count] = htonl(ifr->ifr_metric);
+           }
 #endif /* SIOCRIPMTU */
 
-        count++;
-      }
-   }
-   close(s);
-   return count;
+           count++;
+       }
+    }
+    close(s);
+    return count;
 #endif /* AFS_USERSPACE_IP_ADDR */
 }
 #endif
 
 #endif /* ! AFS_NT40_ENV */
 #endif /* !KERNEL || UKERNEL */
-
-#endif /* !AFS_DJGPP_ENV */