Subject: Re: bin/30772: Enable mountd(8) to bind to a fixed, user-given port
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: Christos Zoulas <christos@zoulas.com>
List: netbsd-bugs
Date: 07/18/2005 00:27:10
The following reply was made to PR bin/30772; it has been noted by GNATS.
From: christos@zoulas.com (Christos Zoulas)
To: gnats-bugs@netbsd.org, gnats-admin@netbsd.org,
netbsd-bugs@netbsd.org
Cc:
Subject: Re: bin/30772: Enable mountd(8) to bind to a fixed, user-given port
Date: Sun, 17 Jul 2005 20:26:15 -0400
On Jul 17, 11:36pm, netbsd@wolfnode.de (netbsd@wolfnode.de) wrote:
-- Subject: bin/30772: Enable mountd(8) to bind to a fixed, user-given port
Isn't it a lot simpler to put all this in a single function, rather than
copying the code 4 times?
christos
Index: mountd.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/mountd/mountd.c,v
retrieving revision 1.95
diff -u -u -r1.95 mountd.c
--- mountd.c 2 Jun 2005 06:01:09 -0000 1.95
+++ mountd.c 18 Jul 2005 00:25:12 -0000
@@ -236,6 +236,7 @@
#ifdef ISO
static int get_isoaddr __P((const char *, size_t, char *, struct grouplist *));
#endif
+static void bind_resv_port __P((int, sa_family_t, in_port_t));
static struct exportlist *exphead;
static struct mountlist *mlhead;
static struct grouplist *grphead;
@@ -295,6 +296,7 @@
int xcreated = 0, s;
int c, one = 1;
int maxrec = RPC_MAXDATASIZE;
+ in_port_t forcedport = 0;
#ifdef IPSEC
char *policy = NULL;
#define ADDOPTS "P:"
@@ -302,7 +304,7 @@
#define ADDOPTS
#endif
- while ((c = getopt(argc, argv, "dNnr" ADDOPTS)) != -1)
+ while ((c = getopt(argc, argv, "dNnrp:" ADDOPTS)) != -1)
switch (c) {
#ifdef IPSEC
case 'P':
@@ -310,6 +312,10 @@
errx(1, "Invalid ipsec policy `%s'", policy);
break;
#endif
+ case 'p':
+ /* A forced port "0" will dynamically allocate a port */
+ forcedport = atoi(optarg);
+ break;
case 'd':
debug = 1;
break;
@@ -394,7 +400,7 @@
rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec);
if (udpsock != -1 && udpconf != NULL) {
- bindresvport(udpsock, NULL);
+ bind_resv_port(udpsock, AF_INET, forcedport);
#ifdef IPSEC
if (policy)
ipsecsetup(AF_INET, udpsock, policy);
@@ -414,7 +420,7 @@
}
if (tcpsock != -1 && tcpconf != NULL) {
- bindresvport(tcpsock, NULL);
+ bind_resv_port(tcpsock, AF_INET, forcedport);
#ifdef IPSEC
if (policy)
ipsecsetup(AF_INET, tcpsock, policy);
@@ -436,7 +442,7 @@
}
if (udp6sock != -1 && udp6conf != NULL) {
- bindresvport(udp6sock, NULL);
+ bind_resv_port(udp6sock, AF_INET6, forcedport);
#ifdef IPSEC
if (policy)
ipsecsetup(AF_INET6, tcpsock, policy);
@@ -456,7 +462,7 @@
}
if (tcp6sock != -1 && tcp6conf != NULL) {
- bindresvport(tcp6sock, NULL);
+ bind_resv_port(tcp6sock, AF_INET6, forcedport);
#ifdef IPSEC
if (policy)
ipsecsetup(AF_INET6, tcpsock, policy);
@@ -2680,3 +2686,33 @@
*cp = '/';
return 0;
}
+
+static void
+bind_resv_port(int sock, sa_family_t family, in_port_t port)
+{
+ struct sockaddr *sa;
+ struct sockaddr_in sasin;
+ struct sockaddr_in6 sasin6;
+
+ switch (family) {
+ case AF_INET:
+ (void)memset(&sasin, 0, sizeof(sasin));
+ sasin.sin_len = sizeof(sasin);
+ sasin.sin_family = family;
+ sasin.sin_port = htons(port);
+ sa = (struct sockaddr *)(void *)&sasin;
+ break;
+ case AF_INET6:
+ (void)memset(&sasin6, 0, sizeof(sasin6));
+ sasin6.sin6_len = sizeof(sasin6);
+ sasin6.sin6_family = family;
+ sasin6.sin6_port = htons(port);
+ sa = (struct sockaddr *)(void *)&sasin6;
+ break;
+ default:
+ syslog(LOG_ERR, "Unsupported address family %d", family);
+ return;
+ }
+ if (bindresvport_sa(sock, sa) == -1)
+ syslog(LOG_ERR, "Cannot bind to reserved port %d (%m)", port);
+}