Do you have a particular usage that needs this?
Some minor nits on this diff
- I would use UINT16_MAX or SHORT_MAX instead of (1<<16)-1.
- Spaces around "=" in "port=0" please.
- Rest of main() uses exit(1) not return (1) and err/errx not fprintf
(aside from for usage) should stay consistent.
- Why do you have a bit under #if 0? It's either needed or not?
- I think you missed updating the synopsis in the man pages.
- UDP and TCP should be uppercase in man page, and I'd say comments and
error messages too.
- Wrap lines to below 80 columns please.
On Wed, Jul 27, 2011 at 11:21:52PM +0200, Christopher Zimmermann wrote:
> Hi,
>
> now here also for rpc.statd and rpc.lockd. But I could only test
> mountd, because I have no clients for lockd. I would really like to
> see this committed in cvs.
>
> Cheers,
> Christopher
>
>
> Index: sbin/mountd/mountd.8
> ===================================================================
> RCS file: /cvs/src/sbin/mountd/mountd.8,v
> retrieving revision 1.16
> diff -u -p -r1.16 mountd.8
> --- sbin/mountd/mountd.8 31 May 2007 19:19:46 -0000 1.16
> +++ sbin/mountd/mountd.8 27 Jul 2011 21:15:12 -0000
> @@ -63,6 +63,8 @@ Enable debugging mode.
> .Nm
> will not detach from the controlling terminal and will print
> debugging messages to stderr.
> +.It Fl n Ar port
> +Specifies which udp and tcp port to bind to.
> .It Fl n
> Do not require that clients make mount requests from reserved ports.
> (Normally, only mount requests from reserved ports are accepted.)
> Index: sbin/mountd/mountd.c
> ===================================================================
> RCS file: /cvs/src/sbin/mountd/mountd.c,v
> retrieving revision 1.71
> diff -u -p -r1.71 mountd.c
> --- sbin/mountd/mountd.c 22 Mar 2010 16:35:27 -0000 1.71
> +++ sbin/mountd/mountd.c 27 Jul 2011 21:15:14 -0000
> @@ -211,11 +211,15 @@ volatile sig_atomic_t gotterm;
> int
> main(int argc, char *argv[])
> {
> + struct sockaddr_in inetaddr;
> + int port=0;
> + int udpsock, tcpsock;
> SVCXPRT *udptransp, *tcptransp;
> FILE *pidfile;
> + const char *errstr = NULL;
> int c;
>
> - while ((c = getopt(argc, argv, "dnr")) != -1)
> + while ((c = getopt(argc, argv, "dnp:r")) != -1)
> switch (c) {
> case 'd':
> debug = 1;
> @@ -223,11 +227,18 @@ main(int argc, char *argv[])
> case 'n':
> resvport_only = 0;
> break;
> + case 'p':
> + port = strtonum(optarg, 1, (1<<16) - 1, &errstr);
> + if (errstr) {
> + fprintf(stderr, "mountd port is %s: %s\n",
> errstr, optarg);
> + return(1);
> + }
> + break;
> case 'r':
> /* Compatibility */
> break;
> default:
> - fprintf(stderr, "usage: mountd [-dn] [exportsfile]\n");
> + fprintf(stderr, "usage: mountd [-dn] [-p port]
> [exportsfile]\n");
> exit(1);
> }
> argc -= optind;
> @@ -273,8 +284,51 @@ main(int argc, char *argv[])
> signal(SIGHUP, (void (*)(int)) new_exportlist);
> signal(SIGTERM, (void (*)(int)) send_umntall);
> signal(SIGSYS, SIG_IGN);
> - if ((udptransp = svcudp_create(RPC_ANYSOCK)) == NULL ||
> - (tcptransp = svctcp_create(RPC_ANYSOCK, 0, 0)) == NULL) {
> +
> + /* Create tcp/udp sockets */
> + if(port == 0)
> + udpsock = tcpsock = RPC_ANYSOCK;
> + else {
> + if ((udpsock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
> + syslog(LOG_ERR, "can't create udp socket");
> + return (1);
> + }
> + memset(&inetaddr, 0, sizeof inetaddr);
> + inetaddr.sin_family = AF_INET;
> + inetaddr.sin_addr.s_addr = INADDR_ANY;
> + inetaddr.sin_port = htons(port);
> + inetaddr.sin_len = sizeof(inetaddr);
> + if (bind(udpsock, (struct sockaddr *)&inetaddr,
> + sizeof(inetaddr)) < 0) {
> + syslog(LOG_ERR, "can't bind udp addr");
> + return (1);
> + }
> +
> +
> + if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
> + syslog(LOG_ERR, "can't create tcp socket");
> + return (1);
> + }
> + memset(&inetaddr, 0, sizeof inetaddr);
> + inetaddr.sin_family = AF_INET;
> + inetaddr.sin_addr.s_addr = INADDR_ANY;
> + inetaddr.sin_port = htons(port);
> + inetaddr.sin_len = sizeof(inetaddr);
> + if (bind(tcpsock, (struct sockaddr *)&inetaddr,
> + sizeof (inetaddr)) < 0) {
> + syslog(LOG_ERR, "can't bind tcp addr");
> + return (1);
> + }
> +#if 0
> + if (listen(tcpsock, 5) < 0) {
> + syslog(LOG_ERR, "listen failed");
> + return (1);
> + }
> +#endif
> + }
> +
> + if ((udptransp = svcudp_create(udpsock)) == NULL ||
> + (tcptransp = svctcp_create(tcpsock, 0, 0)) == NULL) {
> syslog(LOG_ERR, "Can't create socket");
> exit(1);
> }
> Index: usr.sbin/rpc.statd/rpc.statd.8
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpc.statd/rpc.statd.8,v
> retrieving revision 1.2
> diff -u -p -r1.2 rpc.statd.8
> --- usr.sbin/rpc.statd/rpc.statd.8 15 Jun 2008 20:42:42 -0000 1.2
> +++ usr.sbin/rpc.statd/rpc.statd.8 27 Jul 2011 21:15:14 -0000
> @@ -59,6 +59,8 @@ at the time of the crash.
> .Pp
> The options available are:
> .Bl -tag -width Ds
> +.It Fl n Ar port
> +Specifies which udp and tcp port to bind to.
> .It Fl d
> Causes debugging information to be written to
> .Xr syslog 3 ,
> Index: usr.sbin/rpc.statd/statd.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpc.statd/statd.c,v
> retrieving revision 1.1
> diff -u -p -r1.1 statd.c
> --- usr.sbin/rpc.statd/statd.c 15 Jun 2008 04:43:28 -0000 1.1
> +++ usr.sbin/rpc.statd/statd.c 27 Jul 2011 21:15:14 -0000
> @@ -40,6 +40,7 @@
> /* The actual program logic is in the file procs.c */
>
> #include <sys/param.h>
> +#include <sys/socket.h>
> #include <sys/wait.h>
>
> #include <err.h>
> @@ -88,25 +89,73 @@ int main(int, char **);
> int
> main(int argc, char **argv)
> {
> + struct sockaddr_in inetaddr;
> + int port=0;
> + int udpsock, tcpsock;
> SVCXPRT *transp;
> int ch;
> + const char *errstr = NULL;
> struct sigaction nsa;
>
> - while ((ch = getopt(argc, argv, "d")) != (-1)) {
> + while ((ch = getopt(argc, argv, "dp:")) != (-1)) {
> switch (ch) {
> case 'd':
> debug = 1;
> break;
> + case 'p':
> + port = strtonum(optarg, 1, (1<<16) - 1, &errstr);
> + if (errstr) {
> + fprintf(stderr, "mountd port is %s: %s\n",
> errstr, optarg);
> + return(1);
> + }
> + break;
> default:
> case '?':
> - fprintf(stderr, "usage: %s [-d]\n", __progname);
> + fprintf(stderr, "usage: %s [-d] [-p port]\n",
> __progname);
> exit(1);
> /* NOTREACHED */
> }
> }
> +
> + /* Create tcp/udp sockets */
> + if(port == 0)
> + udpsock = tcpsock = RPC_ANYSOCK;
> + else {
> + if ((udpsock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
> + syslog(LOG_ERR, "can't create udp socket");
> + return (1);
> + }
> + memset(&inetaddr, 0, sizeof inetaddr);
> + inetaddr.sin_family = AF_INET;
> + inetaddr.sin_addr.s_addr = INADDR_ANY;
> + inetaddr.sin_port = htons(port);
> + inetaddr.sin_len = sizeof(inetaddr);
> + if (bind(udpsock, (struct sockaddr *)&inetaddr,
> + sizeof(inetaddr)) < 0) {
> + syslog(LOG_ERR, "can't bind udp addr");
> + return (1);
> + }
> +
> +
> + if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
> + syslog(LOG_ERR, "can't create tcp socket");
> + return (1);
> + }
> + memset(&inetaddr, 0, sizeof inetaddr);
> + inetaddr.sin_family = AF_INET;
> + inetaddr.sin_addr.s_addr = INADDR_ANY;
> + inetaddr.sin_port = htons(port);
> + inetaddr.sin_len = sizeof(inetaddr);
> + if (bind(tcpsock, (struct sockaddr *)&inetaddr,
> + sizeof (inetaddr)) < 0) {
> + syslog(LOG_ERR, "can't bind tcp addr");
> + return (1);
> + }
> + }
> +
> pmap_unset(SM_PROG, SM_VERS);
>
> - transp = svcudp_create(RPC_ANYSOCK);
> + transp = svcudp_create(udpsock);
> if (transp == NULL) {
> errx(1, "cannot create udp service.");
> /* NOTREACHED */
> @@ -115,7 +164,7 @@ main(int argc, char **argv)
> errx(1, "unable to register (SM_PROG, SM_VERS, udp).");
> /* NOTREACHED */
> }
> - transp = svctcp_create(RPC_ANYSOCK, 0, 0);
> + transp = svctcp_create(tcpsock, 0, 0);
> if (transp == NULL) {
> errx(1, "cannot create tcp service.");
> /* NOTREACHED */
> Index: usr.sbin/rpc.lockd/lockd.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpc.lockd/lockd.c,v
> retrieving revision 1.12
> diff -u -p -r1.12 lockd.c
> --- usr.sbin/rpc.lockd/lockd.c 15 Nov 2009 09:07:56 -0000 1.12
> +++ usr.sbin/rpc.lockd/lockd.c 27 Jul 2011 21:15:14 -0000
> @@ -68,12 +68,16 @@ static void usage(void);
> int
> main(int argc, char *argv[])
> {
> + struct sockaddr_in inetaddr;
> + int port=0;
> + int udpsock, tcpsock;
> SVCXPRT *transp;
> int ch;
> + const char *errstr = NULL;
> struct sigaction sigchild, sigalarm;
> int grace_period = 30;
>
> - while ((ch = getopt(argc, argv, "d:g:")) != (-1)) {
> + while ((ch = getopt(argc, argv, "d:g:p:")) != (-1)) {
> switch (ch) {
> case 'd':
> debug_level = atoi(optarg);
> @@ -89,6 +93,13 @@ main(int argc, char *argv[])
> /* NOTREACHED */
> }
> break;
> + case 'p':
> + port = strtonum(optarg, 1, (1<<16) - 1, &errstr);
> + if (errstr) {
> + fprintf(stderr, "mountd port is %s: %s\n",
> errstr, optarg);
> + return(1);
> + }
> + break;
> default:
> case '?':
> usage();
> @@ -101,7 +112,43 @@ main(int argc, char *argv[])
> (void) pmap_unset(NLM_PROG, NLM_VERSX);
> (void) pmap_unset(NLM_PROG, NLM_VERS4);
>
> - transp = svcudp_create(RPC_ANYSOCK);
> + /* Create tcp/udp sockets */
> + if(port == 0)
> + udpsock = tcpsock = RPC_ANYSOCK;
> + else {
> + if ((udpsock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
> + syslog(LOG_ERR, "can't create udp socket");
> + return (1);
> + }
> + memset(&inetaddr, 0, sizeof inetaddr);
> + inetaddr.sin_family = AF_INET;
> + inetaddr.sin_addr.s_addr = INADDR_ANY;
> + inetaddr.sin_port = htons(port);
> + inetaddr.sin_len = sizeof(inetaddr);
> + if (bind(udpsock, (struct sockaddr *)&inetaddr,
> + sizeof(inetaddr)) < 0) {
> + syslog(LOG_ERR, "can't bind udp addr");
> + return (1);
> + }
> +
> +
> + if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
> + syslog(LOG_ERR, "can't create tcp socket");
> + return (1);
> + }
> + memset(&inetaddr, 0, sizeof inetaddr);
> + inetaddr.sin_family = AF_INET;
> + inetaddr.sin_addr.s_addr = INADDR_ANY;
> + inetaddr.sin_port = htons(port);
> + inetaddr.sin_len = sizeof(inetaddr);
> + if (bind(tcpsock, (struct sockaddr *)&inetaddr,
> + sizeof (inetaddr)) < 0) {
> + syslog(LOG_ERR, "can't bind tcp addr");
> + return (1);
> + }
> + }
> +
> + transp = svcudp_create(udpsock);
> if (transp == NULL) {
> fprintf(stderr, "cannot create udp service.\n");
> exit(1);
> @@ -126,7 +173,7 @@ main(int argc, char *argv[])
> fprintf(stderr, "unable to register (NLM_PROG, NLM_VERS4,
> udp).\n");
> exit(1);
> }
> - transp = svctcp_create(RPC_ANYSOCK, 0, 0);
> + transp = svctcp_create(tcpsock, 0, 0);
> if (transp == NULL) {
> fprintf(stderr, "cannot create tcp service.\n");
> exit(1);
> @@ -197,5 +244,5 @@ sigalarm_handler(int s)
> static void
> usage()
> {
> - errx(1, "usage: rpc.lockd [-d [debug_level]] [-g grace_period]");
> + errx(1, "usage: rpc.lockd [-d [debug_level]] [-g grace_period] [-p
> port]");
> }
> Index: usr.sbin/rpc.lockd/rpc.lockd.8
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpc.lockd/rpc.lockd.8,v
> retrieving revision 1.13
> diff -u -p -r1.13 rpc.lockd.8
> --- usr.sbin/rpc.lockd/rpc.lockd.8 13 Jun 2008 23:56:28 -0000 1.13
> +++ usr.sbin/rpc.lockd/rpc.lockd.8 27 Jul 2011 21:15:14 -0000
> @@ -69,6 +69,8 @@ During the grace period
> only accepts requests from hosts which are reinitialising locks which
> existed before the server restart.
> The default is 30 seconds.
> +.It Fl n Ar port
> +Specifies which udp and tcp port to bind to.
> .El
> .Pp
> Error conditions are logged to syslog, irrespective of the debug level,