summaryrefslogtreecommitdiff
path: root/lib/libc/rpc/pmap_rmt.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1997-01-22 18:50:42 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1997-01-22 18:50:42 +0000
commit83aa6ffb1f6c7a8377f886aa41d2fbdbe624c173 (patch)
treeffe30a345c58bfa8751a22b72c4fdd184740e78e /lib/libc/rpc/pmap_rmt.c
parent662104b00fb783421a408f996f7d36492f97b450 (diff)
handle SIOCGIFCONF for as many interfaces as provided
Diffstat (limited to 'lib/libc/rpc/pmap_rmt.c')
-rw-r--r--lib/libc/rpc/pmap_rmt.c67
1 files changed, 44 insertions, 23 deletions
diff --git a/lib/libc/rpc/pmap_rmt.c b/lib/libc/rpc/pmap_rmt.c
index 976721e56be..6afb09ada5f 100644
--- a/lib/libc/rpc/pmap_rmt.c
+++ b/lib/libc/rpc/pmap_rmt.c
@@ -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)