From 285c193dc94b53763ac8d6f91229eaab37d45fc6 Mon Sep 17 00:00:00 2001
From: Roy Li <rongqing.li@windriver.com>
Date: Wed, 27 Aug 2025 11:24:53 +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>
Signed-off-by: Hongxu Jia <hongxu.jia@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 15b70f9..4a6ffbc 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 adfhilsvw
+.Op Fl adfhpilsvw
 .Sh DESCRIPTION
 The
 .Nm
@@ -96,6 +96,8 @@ will automatically add
 and if IPv6 is enabled,
 .Li ::1
 to the list.
+.It Fl p
+Bind for fixed UDP port number
 If no
 .Fl h
 option is specified,
diff --git a/src/rpcb_svc_com.c b/src/rpcb_svc_com.c
index 1743dad..07a1c75 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 bf7b499..7268907 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;
@@ -959,7 +960,7 @@ parseargs(int argc, char *argv[])
 {
 	int c;
 	oldstyle_local = 1;
-	while ((c = getopt(argc, argv, "adfh:ilsvw")) != -1) {
+	while ((c = getopt(argc, argv, "adfh:p:ilsvw")) != -1) {
 		switch (c) {
 		case 'a':
 			doabort = 1;	/* when debugging, do an abort on */
@@ -977,6 +978,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;
@@ -999,7 +1003,7 @@ parseargs(int argc, char *argv[])
 			break;
 #endif
 		default:	/* error */
-			fprintf(stderr,	"usage: rpcbind [-adfhilsvw]\n");
+			fprintf(stderr,	"usage: rpcbind [-adfhpilsvw]\n");
 			exit (1);
 		}
 	}
-- 
2.34.1

