summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authormatteo <matteo@FreeBSD.org>2007-04-03 21:15:00 +0000
committermatteo <matteo@FreeBSD.org>2007-04-03 21:15:00 +0000
commit3ed55b8adb271c57e480c98d499ff2833acdcdcf (patch)
tree900df04f733e645e6cdaf9fa9d8933c2853e5e0e /usr.sbin
parenta25d27fb0f15b68dc0524ac87960260bf1abdc4e (diff)
downloadFreeBSD-src-3ed55b8adb271c57e480c98d499ff2833acdcdcf.zip
FreeBSD-src-3ed55b8adb271c57e480c98d499ff2833acdcdcf.tar.gz
Add the "-p" option, which allows to specify a port which the daemon
should bind to. PR: bin/94920 Reviewed by: alfred@ MFC after: 1 week
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/rpc.statd/rpc.statd.89
-rw-r--r--usr.sbin/rpc.statd/statd.c119
2 files changed, 119 insertions, 9 deletions
diff --git a/usr.sbin/rpc.statd/rpc.statd.8 b/usr.sbin/rpc.statd/rpc.statd.8
index 37147f5..14d06e1 100644
--- a/usr.sbin/rpc.statd/rpc.statd.8
+++ b/usr.sbin/rpc.statd/rpc.statd.8
@@ -33,7 +33,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 19, 1995
+.Dd April 3, 2007
.Dt RPC.STATD 8
.Os
.Sh NAME
@@ -42,6 +42,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl d
+.Op Fl p Ar port
.Sh DESCRIPTION
The
.Nm
@@ -73,6 +74,12 @@ These messages are logged with level
LOG_DEBUG and facility LOG_DAEMON.
Error conditions are logged irrespective
of this option, using level LOG_ERR.
+.It Fl p
+The
+.Fl p
+option allow to force the daemon to bind to the specified
+.Ar port ,
+for both AF_INET and AF_INET6 address families.
.El
.Pp
The
diff --git a/usr.sbin/rpc.statd/statd.c b/usr.sbin/rpc.statd/statd.c
index b8212ce..e827826 100644
--- a/usr.sbin/rpc.statd/statd.c
+++ b/usr.sbin/rpc.statd/statd.c
@@ -56,18 +56,33 @@ int debug = 0; /* Controls syslog() calls for debug messages */
static void handle_sigchld(int sig);
static void usage(void);
+const char *transports[] = { "udp", "tcp", "udp6", "tcp6" };
+
int
main(int argc, char **argv)
{
+ SVCXPRT *transp;
struct sigaction sa;
- int ch;
+ struct netconfig *nconf;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+ int ch, i, maxindex, r, s, sock;
+ char *endptr;
int maxrec = RPC_MAXDATASIZE;
+ in_port_t svcport = 0;
- while ((ch = getopt(argc, argv, "d")) != -1)
+ while ((ch = getopt(argc, argv, "dp:")) != -1)
switch (ch) {
case 'd':
debug = 1;
break;
+ case 'p':
+ endptr = NULL;
+ svcport = (in_port_t)strtoul(optarg, &endptr, 10);
+ if (endptr == NULL || *endptr != '\0' || svcport == 0 ||
+ svcport >= IPPORT_MAX)
+ usage();
+ break;
default:
usage();
}
@@ -76,13 +91,101 @@ main(int argc, char **argv)
(void)rpcb_unset(SM_PROG, SM_VERS, NULL);
+ /*
+ * Check if IPv6 support is present.
+ */
+ s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+ if (s < 0)
+ maxindex = 2;
+ else {
+ close(s);
+ maxindex = 4;
+ }
+
+ if (svcport != 0) {
+ bzero(&sin, sizeof(struct sockaddr_in));
+ sin.sin_len = sizeof(struct sockaddr_in);
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(svcport);
+
+ bzero(&sin6, sizeof(struct sockaddr_in6));
+ sin6.sin6_len = sizeof(struct sockaddr_in6);
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_port = htons(svcport);
+ }
+
rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec);
- if (!svc_create(sm_prog_1, SM_PROG, SM_VERS, "udp"))
- errx(1, "cannot create udp service");
- if (!svc_create(sm_prog_1, SM_PROG, SM_VERS, "tcp"))
- errx(1, "cannot create tcp service");
- init_file("/var/db/statd.status");
+ for (i = 0; i < maxindex; i++) {
+ nconf = getnetconfigent(transports[i]);
+ if (nconf == NULL)
+ errx(1, "cannot get %s netconf: %s.", transports[i],
+ nc_sperror());
+
+ if (svcport != 0) {
+ if (strcmp(nconf->nc_netid, "udp6") == 0) {
+ sock = socket(AF_INET6, SOCK_DGRAM,
+ IPPROTO_UDP);
+ if (sock != -1) {
+ r = bindresvport_sa(sock,
+ (struct sockaddr *)&sin6);
+ if (r != 0) {
+ syslog(LOG_ERR, "bindresvport: %m");
+ exit(1);
+ }
+ }
+ } else if (strcmp(nconf->nc_netid, "udp") == 0) {
+ sock = socket(AF_INET, SOCK_DGRAM,
+ IPPROTO_UDP);
+ if (sock != -1) {
+ r = bindresvport(sock, &sin);
+ if (r != 0) {
+ syslog(LOG_ERR, "bindresvport: %m");
+ exit(1);
+ }
+ }
+ } else if (strcmp(nconf->nc_netid, "tcp6") == 0) {
+ sock = socket(AF_INET6, SOCK_STREAM,
+ IPPROTO_TCP);
+ if (sock != -1) {
+ r = bindresvport_sa(sock,
+ (struct sockaddr *)&sin6);
+ if (r != 0) {
+ syslog(LOG_ERR, "bindresvport: %m");
+ exit(1);
+ }
+ }
+ } else if (strcmp(nconf->nc_netid, "tcp") == 0) {
+ sock = socket(AF_INET, SOCK_STREAM,
+ IPPROTO_TCP);
+ if (sock != -1) {
+ r = bindresvport(sock, &sin);
+ if (r != 0) {
+ syslog(LOG_ERR, "bindresvport: %m");
+ exit(1);
+ }
+ }
+ }
+
+ transp = svc_tli_create(sock, nconf, NULL,
+ RPC_MAXDATASIZE, RPC_MAXDATASIZE);
+ } else {
+ transp = svc_tli_create(RPC_ANYFD, nconf, NULL,
+ RPC_MAXDATASIZE, RPC_MAXDATASIZE);
+ }
+
+ if (transp == NULL) {
+ errx(1, "cannot create %s service.", transports[i]);
+ /* NOTREACHED */
+ }
+ if (!svc_reg(transp, SM_PROG, SM_VERS, sm_prog_1, nconf)) {
+ errx(1, "unable to register (SM_PROG, NLM_SM, %s)",
+ transports[i]);
+ /* NOTREACHED */
+ }
+ init_file("/var/db/statd.status");
+ freenetconfigent(nconf);
+ }
/* Note that it is NOT sensible to run this program from inetd - the */
/* protocol assumes that it will run immediately at boot time. */
@@ -109,7 +212,7 @@ main(int argc, char **argv)
static void
usage()
{
- fprintf(stderr, "usage: rpc.statd [-d]\n");
+ fprintf(stderr, "usage: rpc.statd [-d] [-p <port>]\n");
exit(1);
}
OpenPOWER on IntegriCloud