From 76f8598fd20727908e760cbb497dd6a17eda4af5 Mon Sep 17 00:00:00 2001
From: Roy Li <rongqing.li@windriver.com>
Date: Wed, 17 Sep 2014 13:22:14 +0800
Subject: [PATCH] add option to make users able to use fixed port number

Upstream-Status: Submitted [https://sourceforge.net/p/rpcbind/discussion/716839/thread/32af721d/]

Signed-off-by: Li Wang <li.wang@windriver.com>
Signed-off-by: Roy Li <rongqing.li@windriver.com>
Signed-off-by: Yi Zhao <yi.zhao@windriver.com>
---
 man/rpcbind.8      |  4 +++-
 src/rpcb_svc_com.c | 17 +++++++++++++++++
 src/rpcbind.c      |  8 ++++++--
 3 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/man/rpcbind.8 b/man/rpcbind.8
index af6200f..2e6146b 100644
--- a/man/rpcbind.8
+++ b/man/rpcbind.8
@@ -11,7 +11,7 @@
 .Nd universal addresses to RPC program number mapper
 .Sh SYNOPSIS
 .Nm
-.Op Fl adhiLls
+.Op Fl adhpiLls
 .Sh DESCRIPTION
 The
 .Nm
@@ -107,6 +107,8 @@ will automatically add
 and if IPv6 is enabled,
 .Li ::1
 to the list.
+.It Fl p
+Bind for fixed UDP port number
 .It Fl i
 .Dq Insecure
 mode.
diff --git a/src/rpcb_svc_com.c b/src/rpcb_svc_com.c
index 8aef9e5..c2632a4 100644
--- a/src/rpcb_svc_com.c
+++ b/src/rpcb_svc_com.c
@@ -48,6 +48,7 @@
 #include <rpc/rpc.h>
 #include <rpc/rpcb_prot.h>
 #include <rpc/svc_dg.h>
+#include <rpc/rpc_com.h>
 #include <netconfig.h>
 #include <errno.h>
 #include <syslog.h>
@@ -497,6 +498,7 @@ xdr_opaque_parms(XDR *xdrs, struct r_rmtcall_args *cap)
 
 static struct rmtcallfd_list *rmthead;
 static struct rmtcallfd_list *rmttail;
+extern unsigned short fixed_port;
 
 int
 create_rmtcall_fd(struct netconfig *nconf)
@@ -504,6 +506,8 @@ create_rmtcall_fd(struct netconfig *nconf)
 	int fd;
 	struct rmtcallfd_list *rmt;
 	SVCXPRT *xprt;
+	struct __rpc_sockinfo si;
+	struct t_bind taddr;
 
 	if ((fd = __rpc_nconf2fd(nconf)) == -1) {
 		if (debugging)
@@ -512,6 +516,19 @@ create_rmtcall_fd(struct netconfig *nconf)
 			nconf->nc_device, errno);
 		return (-1);
 	}
+
+	if (fixed_port) {
+		__rpc_fd2sockinfo(fd, &si);
+		memset(&taddr, 0, sizeof(taddr));
+		taddr.addr.maxlen = taddr.addr.len = si.si_alen;
+		taddr.addr.buf = malloc(si.si_alen);
+		if (taddr.addr.buf == NULL) {
+			return -1;
+		}
+		*(unsigned short *)(&(taddr.addr.buf[0])) = si.si_af;
+		*(unsigned short *)(&(taddr.addr.buf[2])) = htons(fixed_port);
+		xprt = svc_tli_create(fd, nconf, &taddr, RPC_MAXDATASIZE, RPC_MAXDATASIZE);
+	} else
 	xprt = svc_tli_create(fd, 0, (struct t_bind *) 0, 0, 0);
 	if (xprt == NULL) {
 		if (debugging)
diff --git a/src/rpcbind.c b/src/rpcbind.c
index 137011b..dc3d2d6 100644
--- a/src/rpcbind.c
+++ b/src/rpcbind.c
@@ -112,6 +112,7 @@ int runasdaemon = 0;
 int insecure = 0;
 int oldstyle_local = 0;
 int verboselog = 0;
+unsigned short fixed_port = 0;
 
 char **hosts = NULL;
 int nhosts = 0;
@@ -881,7 +882,7 @@ parseargs(int argc, char *argv[])
 {
 	int c;
 	oldstyle_local = 1;
-	while ((c = getopt(argc, argv, "adh:ilswf")) != -1) {
+	while ((c = getopt(argc, argv, "adh:p:ilswf")) != -1) {
 		switch (c) {
 		case 'a':
 			doabort = 1;	/* when debugging, do an abort on */
@@ -899,6 +901,9 @@ parseargs(int argc, char *argv[])
 			if (hosts[nhosts - 1] == NULL)
 				errx(1, "Out of memory");
 			break;
+		case 'p':
+			fixed_port = atoi(optarg);
+			break;
 		case 'i':
 			insecure = 1;
 			break;
@@ -917,7 +917,7 @@ parseargs(int argc, char *argv[])
 			break;
 #endif
 		default:	/* error */
-			fprintf(stderr,	"usage: rpcbind [-adhilswf]\n");
+			fprintf(stderr,	"usage: rpcbind [-adhpilswf]\n");
 			exit (1);
 		}
 	}
-- 
1.9.1