handle SIOCGIFCONF for as many interfaces as provided
authorderaadt <deraadt@openbsd.org>
Wed, 22 Jan 1997 18:50:40 +0000 (18:50 +0000)
committerderaadt <deraadt@openbsd.org>
Wed, 22 Jan 1997 18:50:40 +0000 (18:50 +0000)
lib/libc/rpc/get_myaddress.c
lib/libc/rpc/pmap_rmt.c

index 25efad7..3bb0c45 100644 (file)
@@ -28,7 +28,7 @@
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char *rcsid = "$OpenBSD: get_myaddress.c,v 1.6 1997/01/22 08:52:32 deraadt Exp $";
+static char *rcsid = "$OpenBSD: get_myaddress.c,v 1.7 1997/01/22 18:50:40 deraadt Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 /*
@@ -63,15 +63,15 @@ get_myaddress(addr)
        char *inbuf = NULL;
        struct ifconf ifc;
        struct ifreq ifreq, *ifr;
-       int len = 8192, slop;
+       int len, inbuflen = 8192, slop;
        int loopback = 0, gotit = 0;
 
        if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
                return (-1);
        }
        while (1) {
-               ifc.ifc_len = len;
-               ifc.ifc_buf = inbuf = realloc(inbuf, len);
+               ifc.ifc_len = inbuflen;
+               ifc.ifc_buf = inbuf = realloc(inbuf, inbuflen);
                if (inbuf == NULL) {
                        close(s);
                        return (-1);
@@ -81,9 +81,9 @@ get_myaddress(addr)
                        free(inbuf);
                        return (-1);
                }
-               if (ifc.ifc_len + sizeof(ifreq) < len)
+               if (ifc.ifc_len + sizeof(ifreq) < inbuflen)
                        break;
-               len *= 2;
+               inbuflen *= 2;
        }
 again:
        ifr = ifc.ifc_req;
index 976721e..6afb09a 100644 (file)
@@ -28,7 +28,7 @@
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char *rcsid = "$OpenBSD: pmap_rmt.c,v 1.13 1997/01/02 09:21:07 deraadt Exp $";
+static char *rcsid = "$OpenBSD: pmap_rmt.c,v 1.14 1997/01/22 18:50:41 deraadt Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 /*
@@ -162,37 +162,54 @@ xdr_rmtcallres(xdrs, crp)
  */
 
 static int
-getbroadcastnets(addrs, sock, buf)
-       struct in_addr *addrs;
+newgetbroadcastnets(addrsp, sock)
+       struct in_addr **addrsp;
        int sock;  /* any valid socket will do */
-       char *buf;  /* why allocxate more when we can use existing... */
 {
+       char *inbuf = NULL;
        struct ifconf ifc;
-        struct ifreq ifreq, *ifr;
+       struct ifreq ifreq, *ifr;
        struct sockaddr_in *sin;
-        char *cp, *cplim;
-        int i = 0;
+       char *cp, *cplim;
+       int inbuflen = 256;
+       struct in_addr *addrs;
+       int i = 0;
+
+       while (1) {
+               ifc.ifc_len = inbuflen;
+               ifc.ifc_buf = inbuf = realloc(inbuf, inbuflen);
+               if (inbuf == NULL)
+                       return (0);
+               if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
+                       perror("broadcast: ioctl (get interface configuration)");
+                       free(inbuf);
+                       return (0);
+               }
+               if (ifc.ifc_len + sizeof(ifreq) < inbuflen)
+                       break;
+               inbuflen *= 2;
+       }
+       addrs = (struct in_addr *)malloc((inbuflen / sizeof *sin) * sizeof sin);
+       if (addrs == NULL) {
+               *addrsp = NULL;
+               free(inbuf);
+               return (0);
+       }
 
-        ifc.ifc_len = UDPMSGSIZE;
-        ifc.ifc_buf = buf;
-        if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
-                perror("broadcast: ioctl (get interface configuration)");
-                return (0);
-        }
 #define max(a, b) (a > b ? a : b)
 #define size(p)        max((p).sa_len, sizeof(p))
-       cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */
-       for (cp = buf; cp < cplim;
+       cplim = inbuf + ifc.ifc_len; /*skip over if's with big ifr_addr's */
+       for (cp = inbuf; cp < cplim;
            cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) {
                ifr = (struct ifreq *)cp;
                if (ifr->ifr_addr.sa_family != AF_INET)
                        continue;
                ifreq = *ifr;
-                if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
-                        perror("broadcast: ioctl (get interface flags)");
-                        continue;
-                }
-                if ((ifreq.ifr_flags & IFF_BROADCAST) &&
+               if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
+                       perror("broadcast: ioctl (get interface flags)");
+                       continue;
+               }
+               if ((ifreq.ifr_flags & IFF_BROADCAST) &&
                    (ifreq.ifr_flags & IFF_UP)) {
                        sin = (struct sockaddr_in *)&ifr->ifr_addr;
                        if (ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
@@ -205,6 +222,8 @@ getbroadcastnets(addrs, sock, buf)
                        }
                }
        }
+       free(inbuf);
+       *addrsp = addrs;
        return (i);
 }
 
@@ -233,7 +252,7 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
        bool_t done = FALSE;
        register u_long xid;
        u_long port;
-       struct in_addr addrs[20];
+       struct in_addr *addrs;
        struct sockaddr_in baddr, raddr; /* broadcast and response addresses */
        struct rmtcallargs a;
        struct rmtcallres r;
@@ -271,7 +290,7 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
                FD_ZERO(fds);
        }
 
-       nets = getbroadcastnets(addrs, sock, inbuf);
+       nets = newgetbroadcastnets(&addrs, sock);
        memset(&baddr, 0, sizeof (baddr));
        baddr.sin_len = sizeof(struct sockaddr_in);
        baddr.sin_family = AF_INET;
@@ -331,7 +350,7 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
        recv_again:
                msg.acpted_rply.ar_verf = _null_auth;
                msg.acpted_rply.ar_results.where = (caddr_t)&r;
-                msg.acpted_rply.ar_results.proc = xdr_rmtcallres;
+               msg.acpted_rply.ar_results.proc = xdr_rmtcallres;
 
                /* XXX we know the other bits are still clear */
                FD_SET(sock, fds);
@@ -386,6 +405,8 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
                }
        }
 done_broad:
+       if (addrs)
+               free(addrs);
        if (fds != &readfds)
                free(fds);
        if (sock >= 0)