aboutsummaryrefslogtreecommitdiff
path: root/sunrpc
diff options
context:
space:
mode:
Diffstat (limited to 'sunrpc')
-rw-r--r--sunrpc/pmap_clnt.c77
1 files changed, 68 insertions, 9 deletions
diff --git a/sunrpc/pmap_clnt.c b/sunrpc/pmap_clnt.c
index 68bdfab..11e241d 100644
--- a/sunrpc/pmap_clnt.c
+++ b/sunrpc/pmap_clnt.c
@@ -1,4 +1,3 @@
-/* @(#)pmap_clnt.c 2.2 88/08/01 4.0 RPCSRC */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@@ -27,21 +26,81 @@
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
-#if !defined(lint) && defined(SCCSIDS)
-static char sccsid[] = "@(#)pmap_clnt.c 1.37 87/08/11 Copyr 1984 Sun Micro";
-#endif
-
+/*
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
/*
* pmap_clnt.c
* Client interface to pmap rpc service.
- *
- * Copyright (C) 1984, Sun Microsystems, Inc.
*/
+#include <stdio.h>
+#include <unistd.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
#include <rpc/rpc.h>
#include <rpc/pmap_prot.h>
#include <rpc/pmap_clnt.h>
+/*
+ * Same as get_myaddress, but we try to use the loopback
+ * interface. portmap caches interfaces, and on DHCP clients,
+ * it could be that only loopback is started at this time.
+ */
+static void
+__get_myaddress (struct sockaddr_in *addr)
+{
+ int s;
+ char buf[BUFSIZ];
+ struct ifconf ifc;
+ struct ifreq ifreq, *ifr;
+ int len, loopback = 1;
+
+ if ((s = __socket (AF_INET, SOCK_DGRAM, 0)) < 0)
+ {
+ perror ("__get_myaddress: socket");
+ exit (1);
+ }
+ ifc.ifc_len = sizeof (buf);
+ ifc.ifc_buf = buf;
+ if (__ioctl (s, SIOCGIFCONF, (char *) &ifc) < 0)
+ {
+ perror (_("__get_myaddress: ioctl (get interface configuration)"));
+ exit (1);
+ }
+
+ again:
+ ifr = ifc.ifc_req;
+ for (len = ifc.ifc_len; len; len -= sizeof ifreq)
+ {
+ ifreq = *ifr;
+ if (__ioctl (s, SIOCGIFFLAGS, (char *) &ifreq) < 0)
+ {
+ perror ("__get_myaddress: ioctl");
+ exit (1);
+ }
+ if ((ifreq.ifr_flags & IFF_UP) && (ifr->ifr_addr.sa_family == AF_INET)
+ && ((ifreq.ifr_flags & IFF_LOOPBACK) || (loopback == 0)))
+ {
+ *addr = *((struct sockaddr_in *) &ifr->ifr_addr);
+ addr->sin_port = htons (PMAPPORT);
+ __close (s);
+ return;
+ }
+ ifr++;
+ }
+ if (loopback == 1)
+ {
+ loopback = 0;
+ goto again;
+ }
+ __close (s);
+}
+
+
static const struct timeval timeout = {5, 0};
static const struct timeval tottimeout = {60, 0};
@@ -58,7 +117,7 @@ pmap_set (u_long program, u_long version, int protocol, u_short port)
struct pmap parms;
bool_t rslt;
- get_myaddress (&myaddress);
+ __get_myaddress (&myaddress);
client = clntudp_bufcreate (&myaddress, PMAPPROG, PMAPVERS,
timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
if (client == (CLIENT *) NULL)
@@ -92,7 +151,7 @@ pmap_unset (u_long program, u_long version)
struct pmap parms;
bool_t rslt;
- get_myaddress (&myaddress);
+ __get_myaddress (&myaddress);
client = clntudp_bufcreate (&myaddress, PMAPPROG, PMAPVERS,
timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
if (client == (CLIENT *) NULL)