SIOCGIFCONF more carefully
authorderaadt <deraadt@openbsd.org>
Wed, 22 Jan 1997 08:52:32 +0000 (08:52 +0000)
committerderaadt <deraadt@openbsd.org>
Wed, 22 Jan 1997 08:52:32 +0000 (08:52 +0000)
lib/libc/rpc/get_myaddress.c
usr.sbin/ypbind/ypbind.c

index aaa6741..25efad7 100644 (file)
@@ -28,7 +28,7 @@
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char *rcsid = "$OpenBSD: get_myaddress.c,v 1.5 1996/08/19 08:31:31 tholo Exp $";
+static char *rcsid = "$OpenBSD: get_myaddress.c,v 1.6 1997/01/22 08:52:32 deraadt Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 /*
@@ -43,6 +43,7 @@ static char *rcsid = "$OpenBSD: get_myaddress.c,v 1.5 1996/08/19 08:31:31 tholo
 #include <rpc/pmap_prot.h>
 #include <sys/socket.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <net/if.h>
 #include <sys/ioctl.h>
 #include <netinet/in.h>
@@ -59,20 +60,30 @@ get_myaddress(addr)
        struct sockaddr_in *addr;
 {
        int s;
-       char buf[BUFSIZ];
+       char *inbuf = NULL;
        struct ifconf ifc;
        struct ifreq ifreq, *ifr;
-       int len, slop;
+       int len = 8192, slop;
        int loopback = 0, gotit = 0;
 
        if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
                return (-1);
        }
-       ifc.ifc_len = sizeof (buf);
-       ifc.ifc_buf = buf;
-       if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
-               (void) close(s);
-               return (-1);
+       while (1) {
+               ifc.ifc_len = len;
+               ifc.ifc_buf = inbuf = realloc(inbuf, len);
+               if (inbuf == NULL) {
+                       close(s);
+                       return (-1);
+               }
+               if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
+                       (void) close(s);
+                       free(inbuf);
+                       return (-1);
+               }
+               if (ifc.ifc_len + sizeof(ifreq) < len)
+                       break;
+               len *= 2;
        }
 again:
        ifr = ifc.ifc_req;
@@ -80,6 +91,7 @@ again:
                ifreq = *ifr;
                if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
                        (void) close(s);
+                       free(inbuf);
                        return (-1);
                }
                if ((ifreq.ifr_flags & IFF_UP) &&
@@ -105,5 +117,6 @@ again:
                goto again;
        }
        (void) close(s);
+       free (inbuf);
        return (0);
 }
index 633effe..763f5d7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ypbind.c,v 1.13 1996/12/21 05:52:31 deraadt Exp $ */
+/*     $OpenBSD: ypbind.c,v 1.14 1997/01/22 08:54:14 deraadt Exp $ */
 
 /*
  * Copyright (c) 1996 Theo de Raadt <deraadt@theos.com>
@@ -34,7 +34,7 @@
  */
 
 #ifndef LINT
-static char rcsid[] = "$OpenBSD: ypbind.c,v 1.13 1996/12/21 05:52:31 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: ypbind.c,v 1.14 1997/01/22 08:54:14 deraadt Exp $";
 #endif
 
 #include <sys/param.h>
@@ -631,10 +631,10 @@ broadcast(ypdb)
 {
        domainname dom = ypdb->dom_domain;
        struct rpc_msg msg;
-       char buf[1400], inbuf[8192];
+       char buf[1400], *inbuf = NULL;
        char path[MAXPATHLEN];
        enum clnt_stat st;
-       int outlen, i, sock, len;
+       int outlen, i, sock, len, inlen = 8192;
        struct sockaddr_in bindsin;
        struct ifconf ifc;
        struct ifreq ifreq, *ifr;
@@ -712,13 +712,24 @@ broadcast(ypdb)
                return -1;
        }
        
-       ifc.ifc_len = sizeof inbuf;
-       ifc.ifc_buf = inbuf;
-       if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
-               close(sock);
-               perror("ioctl(SIOCGIFCONF)");
-               return -1;
+       while (1) {
+               ifc.ifc_len = inlen;
+               ifc.ifc_buf = inbuf = realloc(inbuf, inlen);
+               if (inbuf == NULL) {
+                       close(sock);
+                       return (-1);
+               }
+               if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
+                       (void) close(sock);
+                       free(inbuf);
+                       perror("ioctl(SIOCGIFCONF)");
+                       return (-1);
+               }
+               if (ifc.ifc_len + sizeof(ifreq) < inlen)
+                       break;
+               inlen *= 2;
        }
+
        ifr = ifc.ifc_req;
        ifreq.ifr_name[0] = '\0';
        for (i = 0; i < ifc.ifc_len; i += len,
@@ -759,6 +770,7 @@ broadcast(ypdb)
                        perror("sendto");
        }
        close(sock);
+       free(inbuf);
        return 0;
 }