Date: Mon, 8 Jul 2002 20:40:35 +0200 (CEST) From: Martin Blapp <mb@imp.ch> To: Doug Barton <dougb@FreeBSD.org> Cc: <freebsd-bugs@FreeBSD.org>, <mbr@FreeBSD.org> Subject: Re: bin/39674: the new rpcbind lacks the -h IPAddrs feature of the portmap d. Message-ID: <20020708200029.U41780-100000@levais.imp.ch> In-Reply-To: <200207062024.g66KOmfo052000@freefall.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Hi,
> Synopsis: the new rpcbind lacks the -h IPAddrs feature of the portmap d.
can you try the following patch (untested). I don't know if
it works for IPv6. I can test this tomorrow.
Index: rpcbind.8
===================================================================
RCS file: /home/ncvs/src/usr.sbin/rpcbind/rpcbind.8,v
retrieving revision 1.2
diff -u -r1.2 rpcbind.8
--- rpcbind.8 20 Aug 2001 00:03:01 -0000 1.2
+++ rpcbind.8 8 Jul 2002 18:35:48 -0000
@@ -72,6 +72,27 @@
during operation, and will abort on certain errors.
With this option, the name-to-address translation consistency
checks are shown in detail.
+.It Fl h
+Specify specific IP addresses to bind to for UDP requests.
+This option
+may be specified multiple times and is typically necessary when running
+on a multi-homed host.
+If no
+.Fl h
+option is specified,
+.Nm
+will bind to
+.Dv INADDR_ANY ,
+which could lead to problems on a multi-homed host due to
+.Nm
+returning a UDP packet from a different IP address than it was
+sent to.
+Note that when specifying IP addresses with
+.Fl h ,
+.Nm
+will automatically add
+.Li 127.0.0.1
+to the list.
.It Fl i
.Dq Insecure
mode.
Index: rpcbind.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/rpcbind/rpcbind.c,v
retrieving revision 1.2
diff -u -r1.2 rpcbind.c
--- rpcbind.c 17 May 2002 05:27:52 -0000 1.2
+++ rpcbind.c 8 Jul 2002 18:35:49 -0000
@@ -86,6 +86,9 @@
int oldstyle_local = 0;
int verboselog = 0;
+char **hosts = NULL;
+int nhosts = 0;
+
#ifdef WARMSTART
/* Local Variable */
static int warmstart = 0; /* Grab a old copy of registrations */
@@ -220,7 +223,9 @@
int status; /* bound checking ? */
int aicode;
int addrlen;
+ int nhostscp;
struct sockaddr *sa;
+ u_int32_t host_addr[4]; /* IPv4 or IPv6 */
struct sockaddr_un sun;
mode_t oldmask;
@@ -271,20 +276,83 @@
hints.ai_family = si.si_af;
hints.ai_socktype = si.si_socktype;
hints.ai_protocol = si.si_proto;
- if ((aicode = getaddrinfo(NULL, servname, &hints, &res)) != 0) {
- syslog(LOG_ERR, "cannot get local address for %s: %s",
- nconf->nc_netid, gai_strerror(aicode));
- return 1;
+ if (nconf->nc_semantics != NC_TPI_CLTS) {
+ if ((aicode = getaddrinfo(NULL, servname, &hints, &res)) != 0) {
+ syslog(LOG_ERR, "cannot get local address for %s: %s",
+ nconf->nc_netid, gai_strerror(aicode));
+ return 1;
+ }
+ addrlen = res->ai_addrlen;
+ sa = (struct sockaddr *)res->ai_addr;
}
- addrlen = res->ai_addrlen;
- sa = (struct sockaddr *)res->ai_addr;
}
oldmask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
- if (bind(fd, sa, addrlen) < 0) {
- syslog(LOG_ERR, "cannot bind %s: %m", nconf->nc_netid);
- if (res != NULL)
- freeaddrinfo(res);
- return 1;
+ if (nconf->nc_semantics == NC_TPI_CLTS) {
+ /*
+ * If no hosts were specified, just bind to INADDR_ANY. Otherwise
+ * make sure 127.0.0.1 is added to the list.
+ */
+ nhostscp = nhosts;
+ ++nhostscp;
+ hosts = realloc(hosts, nhostscp * sizeof(char *));
+ if (nhostscp == 1)
+ hosts[0] = "*";
+ else {
+ if (strcmp(nconf->nc_proto, NC_UDP) == 0) {
+ hosts[nhostscp - 1] = "127.0.0.1";
+ } else {
+ hosts[nhostscp - 1] = "::1";
+ }
+ }
+
+ /*
+ * Add UDP socket(s) - bind to specific IPs if asked to
+ */
+ while (nhostscp > 0) {
+ --nhostscp;
+ switch (hints.ai_family) {
+ case AF_INET:
+ if (inet_pton(AF_INET, hosts[nhosts], host_addr) == 1) {
+ hints.ai_flags = AI_NUMERICHOST;
+ } else {
+ if (inet_pton(AF_INET6, hosts[nhosts],
+ host_addr) == 1)
+ return (1);
+ }
+ break;
+ case AF_INET6:
+ if (inet_pton(AF_INET6, hosts[nhosts], host_addr) == 1) {
+ hints.ai_flags = AI_NUMERICHOST;
+ } else {
+ if (inet_pton(AF_INET, hosts[nhosts],
+ host_addr) == 1)
+ return (1);
+ }
+ break;
+ default:
+ break;
+ }
+ if ((aicode = getaddrinfo(hosts[nhosts], servname, &hints, &res)) != 0) {
+ syslog(LOG_ERR, "cannot get local address for %s: %s",
+ nconf->nc_netid, gai_strerror(aicode));
+ return 1;
+ }
+ addrlen = res->ai_addrlen;
+ sa = (struct sockaddr *)res->ai_addr;
+ if (bind(fd, sa, addrlen) != 0) {
+ syslog(LOG_ERR, "cannot bind %s: %m", nconf->nc_netid);
+ if (res != NULL)
+ freeaddrinfo(res);
+ return 1;
+ }
+ }
+ } else {
+ if (bind(fd, sa, addrlen) < 0) {
+ syslog(LOG_ERR, "cannot bind %s: %m", nconf->nc_netid);
+ if (res != NULL)
+ freeaddrinfo(res);
+ return 1;
+ }
}
(void) umask(oldmask);
@@ -513,7 +581,7 @@
{
int c;
- while ((c = getopt(argc, argv, "dwailLs")) != -1) {
+ while ((c = getopt(argc, argv, "dwahilLs")) != -1) {
switch (c) {
case 'a':
doabort = 1; /* when debugging, do an abort on */
@@ -521,6 +589,15 @@
/* only! */
case 'd':
debugging = 1;
+ break;
+ case 'h':
+ ++nhosts;
+ hosts = realloc(hosts, nhosts * sizeof(char *));
+ if (hosts == NULL)
+ errx(1, "Out of memory");
+ hosts[nhosts - 1] = optarg;
+ if (hosts[nhosts - 1] == NULL)
+ errx(1, "Out of memory");
break;
case 'i':
insecure = 1;
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020708200029.U41780-100000>
