Module Name:    src
Committed By:   christos
Date:           Wed Dec 23 16:19:49 UTC 2015

Modified Files:
        src/usr.sbin/mountd: Makefile mountd.c
Added Files:
        src/usr.sbin/mountd: get_net.c mountd.h

Log Message:
Split out get_net function so that it is easily testable. Restore
functionality where 1.2.3/24 -> 1.2.3.0/24 not 1.2.0.3/24 now that
getaddrinfo(3) parses old-style incomplete dotted quads as old
style addresses.


To generate a diff of this commit:
cvs rdiff -u -r1.18 -r1.19 src/usr.sbin/mountd/Makefile
cvs rdiff -u -r0 -r1.1 src/usr.sbin/mountd/get_net.c \
    src/usr.sbin/mountd/mountd.h
cvs rdiff -u -r1.128 -r1.129 src/usr.sbin/mountd/mountd.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.sbin/mountd/Makefile
diff -u src/usr.sbin/mountd/Makefile:1.18 src/usr.sbin/mountd/Makefile:1.19
--- src/usr.sbin/mountd/Makefile:1.18	Mon May 28 08:06:37 2007
+++ src/usr.sbin/mountd/Makefile	Wed Dec 23 11:19:49 2015
@@ -1,10 +1,10 @@
-#	$NetBSD: Makefile,v 1.18 2007/05/28 12:06:37 tls Exp $
+#	$NetBSD: Makefile,v 1.19 2015/12/23 16:19:49 christos Exp $
 #	@(#)Makefile	8.3 (Berkeley) 1/25/94
 
 USE_FORT?= yes	# network server
 
 PROG=	mountd
-SRCS=	mountd.c ipsec.c
+SRCS=	mountd.c ipsec.c get_net.c
 MAN=	exports.5 mountd.8
 
 INETDDIR= ${.CURDIR}/../inetd

Index: src/usr.sbin/mountd/mountd.c
diff -u src/usr.sbin/mountd/mountd.c:1.128 src/usr.sbin/mountd/mountd.c:1.129
--- src/usr.sbin/mountd/mountd.c:1.128	Sun Nov  8 16:03:16 2015
+++ src/usr.sbin/mountd/mountd.c	Wed Dec 23 11:19:49 2015
@@ -1,4 +1,4 @@
-/* 	$NetBSD: mountd.c,v 1.128 2015/11/08 21:03:16 christos Exp $	 */
+/* 	$NetBSD: mountd.c,v 1.129 2015/12/23 16:19:49 christos Exp $	 */
 
 /*
  * Copyright (c) 1989, 1993
@@ -42,7 +42,7 @@ __COPYRIGHT("@(#) Copyright (c) 1989, 19
 #if 0
 static char     sccsid[] = "@(#)mountd.c  8.15 (Berkeley) 5/1/95";
 #else
-__RCSID("$NetBSD: mountd.c,v 1.128 2015/11/08 21:03:16 christos Exp $");
+__RCSID("$NetBSD: mountd.c,v 1.129 2015/12/23 16:19:49 christos Exp $");
 #endif
 #endif				/* not lint */
 
@@ -105,6 +105,8 @@ __RCSID("$NetBSD: mountd.c,v 1.128 2015/
 #define DEBUGGING 0
 #endif
 
+#include "mountd.h"
+
 /*
  * Structures for keeping the mount list and export list
  */
@@ -140,12 +142,6 @@ struct exportlist {
 /* ex_flag bits */
 #define	EX_LINKED	0x1
 
-struct netmsk {
-	struct sockaddr_storage nt_net;
-	int		nt_len;
-	char           *nt_name;
-};
-
 union grouptypes {
 	struct addrinfo *gt_addrinfo;
 	struct netmsk   gt_net;
@@ -206,7 +202,6 @@ static int get_host(const char *, size_t
     struct grouplist *);
 static struct hostlist *get_ht(void);
 static void get_mountlist(void);
-static int get_net(char *, struct netmsk *, int);
 static void free_exp_grp(struct exportlist *, struct grouplist *);
 static struct grouplist *get_grp(void);
 static void hang_dirp(struct dirlist *, struct grouplist *,
@@ -225,7 +220,6 @@ static int bitcmp(void *, void *, int);
 static int netpartcmp(struct sockaddr *, struct sockaddr *, int);
 static int sacmp(struct sockaddr *, struct sockaddr *);
 static int allones(struct sockaddr_storage *, int);
-static int countones(struct sockaddr *);
 static void bind_resv_port(int, sa_family_t, in_port_t);
 __dead static void no_nfs(int);
 static struct exportlist *exphead;
@@ -240,22 +234,11 @@ static struct uucred def_anon = {
 	{ 0 }
 };
 
-static int      opt_flags;
+int      opt_flags;
 static int	have_v6 = 1;
-static const int ninumeric = NI_NUMERICHOST;
-
-/* Bits for above */
-#define	OP_MAPROOT	0x001
-#define	OP_MAPALL	0x002
-#define	OP_KERB		0x004
-#define	OP_MASK		0x008
-#define	OP_NET		0x010
-#define	OP_ALLDIRS	0x040
-#define OP_NORESPORT	0x080
-#define OP_NORESMNT	0x100
-#define OP_MASKLEN	0x200
+const int ninumeric = NI_NUMERICHOST;
 
-static int      debug = DEBUGGING;
+int      debug = DEBUGGING;
 #if 0
 static void SYSLOG(int, const char *,...);
 #endif
@@ -1590,41 +1573,6 @@ allones(struct sockaddr_storage *ssp, in
 }
 
 static int
-countones(struct sockaddr *sa)
-{
-	void *mask;
-	int i, bits = 0, bytelen;
-	u_int8_t *p;
-
-	switch (sa->sa_family) {
-	case AF_INET:
-		mask = (u_int8_t *)&((struct sockaddr_in *)sa)->sin_addr;
-		bytelen = 4;
-		break;
-	case AF_INET6:
-		mask = (u_int8_t *)&((struct sockaddr_in6 *)sa)->sin6_addr;
-		bytelen = 16;
-		break;
-	default:
-		return 0;
-	}
-
-	p = mask;
-
-	for (i = 0; i < bytelen; i++, p++) {
-		if (*p != 0xff) {
-			for (bits = 0; bits < 8; bits++) {
-				if (!(*p & (1 << (7 - bits))))
-					break;
-			}
-			break;
-		}
-	}
-
-	return (i * 8 + bits);
-}
-
-static int
 sacmp(struct sockaddr *sa1, struct sockaddr *sa2)
 {
 	void *p1, *p2;
@@ -2051,125 +1999,6 @@ skip:
 }
 
 /*
- * Translate a net address.
- */
-static int
-get_net(char *cp, struct netmsk *net, int maskflg)
-{
-	struct netent *np;
-	char *nname, *p, *prefp;
-	struct sockaddr_in sin, *sinp;
-	struct sockaddr *sa;
-	struct addrinfo hints, *ai = NULL;
-	char netname[NI_MAXHOST];
-	long preflen;
-	int ecode;
-
-	(void)memset(&sin, 0, sizeof(sin));
-	if ((opt_flags & OP_MASKLEN) && !maskflg) {
-		p = strchr(cp, '/');
-		*p = '\0';
-		prefp = p + 1;
-	} else {
-		p = NULL;	/* XXXGCC -Wuninitialized */
-		prefp = NULL;	/* XXXGCC -Wuninitialized */
-	}
-
-	if ((np = getnetbyname(cp)) != NULL) {
-		sin.sin_family = AF_INET;
-		sin.sin_len = sizeof sin;
-		sin.sin_addr = inet_makeaddr(np->n_net, 0);
-		sa = (struct sockaddr *)&sin;
-	} else if (isdigit((unsigned char)*cp)) {
-		memset(&hints, 0, sizeof hints);
-		hints.ai_family = AF_UNSPEC;
-		hints.ai_flags = AI_NUMERICHOST;
-		if (getaddrinfo(cp, NULL, &hints, &ai) != 0) {
-			/*
-			 * If getaddrinfo() failed, try the inet4 network
-			 * notation with less than 3 dots.
-			 */
-			sin.sin_family = AF_INET;
-			sin.sin_len = sizeof sin;
-			sin.sin_addr = inet_makeaddr(inet_network(cp),0);
-			if (debug)
-				fprintf(stderr, "get_net: v4 addr %x\n",
-				    sin.sin_addr.s_addr);
-			sa = (struct sockaddr *)&sin;
-		} else
-			sa = ai->ai_addr;
-	} else if (isxdigit((unsigned char)*cp) || *cp == ':') {
-		memset(&hints, 0, sizeof hints);
-		hints.ai_family = AF_UNSPEC;
-		hints.ai_flags = AI_NUMERICHOST;
-		if (getaddrinfo(cp, NULL, &hints, &ai) == 0)
-			sa = ai->ai_addr;
-		else
-			goto fail;
-	} else
-		goto fail;
-
-	/*
-	 * Only allow /pref notation for v6 addresses.
-	 */
-	if (sa->sa_family == AF_INET6 && (!(opt_flags & OP_MASKLEN) || maskflg))
-		return 1;
-
-	ecode = getnameinfo(sa, sa->sa_len, netname, sizeof netname,
-	    NULL, 0, ninumeric);
-	if (ecode != 0)
-		goto fail;
-
-	if (maskflg)
-		net->nt_len = countones(sa);
-	else {
-		if (opt_flags & OP_MASKLEN) {
-			errno = 0;
-			preflen = strtol(prefp, NULL, 10);
-			if (preflen == LONG_MIN && errno == ERANGE)
-				goto fail;
-			net->nt_len = (int)preflen;
-			*p = '/';
-		}
-
-		if (np)
-			nname = np->n_name;
-		else {
-			if (getnameinfo(sa, sa->sa_len, netname, sizeof netname,
-			    NULL, 0, ninumeric) != 0)
-				strlcpy(netname, "?", sizeof(netname));
-			nname = netname;
-		}
-		net->nt_name = estrdup(nname);
-		memcpy(&net->nt_net, sa, sa->sa_len);
-	}
-
-	if (!maskflg && sa->sa_family == AF_INET &&
-	    !(opt_flags & (OP_MASK|OP_MASKLEN))) {
-		sinp = (struct sockaddr_in *)sa;
-		if (IN_CLASSA(sinp->sin_addr.s_addr))
-			net->nt_len = 8;
-		else if (IN_CLASSB(sinp->sin_addr.s_addr))
-			net->nt_len = 16;
-		else if (IN_CLASSC(sinp->sin_addr.s_addr))
-			net->nt_len = 24;
-		else if (IN_CLASSD(sinp->sin_addr.s_addr))
-			net->nt_len = 28;
-		else
-			net->nt_len = 32;	/* XXX */
-	}
-
-	if (ai)
-		freeaddrinfo(ai);
-	return 0;
-
-fail:
-	if (ai)
-		freeaddrinfo(ai);
-	return 1;
-}
-
-/*
  * Parse out the next white space separated field
  */
 static void

Added files:

Index: src/usr.sbin/mountd/get_net.c
diff -u /dev/null src/usr.sbin/mountd/get_net.c:1.1
--- /dev/null	Wed Dec 23 11:19:49 2015
+++ src/usr.sbin/mountd/get_net.c	Wed Dec 23 11:19:49 2015
@@ -0,0 +1,236 @@
+/* 	$NetBSD: get_net.c,v 1.1 2015/12/23 16:19:49 christos Exp $	 */
+
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Herb Hasler and Rick Macklem at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: get_net.c,v 1.1 2015/12/23 16:19:49 christos Exp $");
+
+#include <sys/types.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <limits.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <util.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#include "mountd.h"
+
+#ifdef TEST
+int      opt_flags;
+const int ninumeric = NI_NUMERICHOST;
+int      debug = 1;
+#endif
+
+static int 
+isdottedquad(const char *cp)
+{
+	for (;;)
+		switch (*cp++) {
+		case '\0':
+			return 1;
+		case '.':
+		case '0': case '1': case '2': case '3': case '4':
+		case '5': case '6': case '7': case '8': case '9':
+			continue;
+		default:
+			return 0;
+		}
+}
+
+static int
+countones(struct sockaddr *sa)
+{
+	void *mask;
+	int i, bits = 0, bytelen;
+	u_int8_t *p;
+
+	switch (sa->sa_family) {
+	case AF_INET:
+		mask = (u_int8_t *)&((struct sockaddr_in *)sa)->sin_addr;
+		bytelen = 4;
+		break;
+	case AF_INET6:
+		mask = (u_int8_t *)&((struct sockaddr_in6 *)sa)->sin6_addr;
+		bytelen = 16;
+		break;
+	default:
+		return 0;
+	}
+
+	p = mask;
+
+	for (i = 0; i < bytelen; i++, p++) {
+		if (*p != 0xff) {
+			for (bits = 0; bits < 8; bits++) {
+				if (!(*p & (1 << (7 - bits))))
+					break;
+			}
+			break;
+		}
+	}
+
+	return (i * 8 + bits);
+}
+
+/*
+ * Translate a net address.
+ */
+int
+get_net(char *cp, struct netmsk *net, int maskflg)
+{
+	struct netent *np;
+	char *nname, *p, *prefp;
+	struct sockaddr_in sin, *sinp;
+	struct sockaddr *sa;
+	struct addrinfo hints, *ai = NULL;
+	char netname[NI_MAXHOST];
+	long preflen;
+	int ecode;
+
+	(void)memset(&sin, 0, sizeof(sin));
+	if ((opt_flags & OP_MASKLEN) && !maskflg) {
+		p = strchr(cp, '/');
+		*p = '\0';
+		prefp = p + 1;
+	} else {
+		p = NULL;	/* XXXGCC -Wuninitialized */
+		prefp = NULL;	/* XXXGCC -Wuninitialized */
+	}
+
+	if ((np = getnetbyname(cp)) != NULL) {
+		sin.sin_family = AF_INET;
+		sin.sin_len = sizeof sin;
+		sin.sin_addr = inet_makeaddr(np->n_net, 0);
+		sa = (struct sockaddr *)&sin;
+	} else if (isdottedquad(cp)) {
+		/*
+		 * Handle dotted quad [or less than quad] notation specially
+		 * because getaddrinfo() will parse them in the old style:
+		 * i.e. 1.2.3 -> 1.2.0.3 not 1.2.3.0
+		 */
+		sin.sin_family = AF_INET;
+		sin.sin_len = sizeof sin;
+		sin.sin_addr = inet_makeaddr(inet_network(cp), 0);
+		if (debug)
+			fprintf(stderr, "get_net: '%s' v4 addr %x\n",
+			    cp, sin.sin_addr.s_addr);
+		sa = (struct sockaddr *)&sin;
+	} else {
+		memset(&hints, 0, sizeof hints);
+		hints.ai_family = AF_UNSPEC;
+		hints.ai_flags = AI_NUMERICHOST;
+		if (getaddrinfo(cp, NULL, &hints, &ai) == 0)
+			sa = ai->ai_addr;
+		else
+			goto fail;
+	}
+
+	/*
+	 * Only allow /pref notation for v6 addresses.
+	 */
+	if (sa->sa_family == AF_INET6 && (!(opt_flags & OP_MASKLEN) || maskflg))
+		return 1;
+
+	ecode = getnameinfo(sa, sa->sa_len, netname, sizeof netname,
+	    NULL, 0, ninumeric);
+	if (ecode != 0)
+		goto fail;
+
+	if (maskflg)
+		net->nt_len = countones(sa);
+	else {
+		if (opt_flags & OP_MASKLEN) {
+			errno = 0;
+			preflen = strtol(prefp, NULL, 10);
+			if (preflen == LONG_MIN && errno == ERANGE)
+				goto fail;
+			net->nt_len = (int)preflen;
+			*p = '/';
+		}
+
+		if (np)
+			nname = np->n_name;
+		else {
+			if (getnameinfo(sa, sa->sa_len, netname, sizeof netname,
+			    NULL, 0, ninumeric) != 0)
+				strlcpy(netname, "?", sizeof(netname));
+			nname = netname;
+		}
+		net->nt_name = estrdup(nname);
+		memcpy(&net->nt_net, sa, sa->sa_len);
+	}
+
+	if (!maskflg && sa->sa_family == AF_INET &&
+	    !(opt_flags & (OP_MASK|OP_MASKLEN))) {
+		sinp = (struct sockaddr_in *)sa;
+		if (IN_CLASSA(sinp->sin_addr.s_addr))
+			net->nt_len = 8;
+		else if (IN_CLASSB(sinp->sin_addr.s_addr))
+			net->nt_len = 16;
+		else if (IN_CLASSC(sinp->sin_addr.s_addr))
+			net->nt_len = 24;
+		else if (IN_CLASSD(sinp->sin_addr.s_addr))
+			net->nt_len = 28;
+		else
+			net->nt_len = 32;	/* XXX */
+	}
+
+	if (ai)
+		freeaddrinfo(ai);
+	return 0;
+
+fail:
+	if (ai)
+		freeaddrinfo(ai);
+	return 1;
+}
+
+#ifdef TEST
+int
+main(int argc, char *argv[])
+{
+	char buf[1024];
+	struct netmsk nm;
+
+	if (get_net(argv[1], &nm, 0))
+		errx(EXIT_FAILURE, "get_net failed");
+
+	sockaddr_snprintf(buf, sizeof(buf), "%a:%p", (void *)&nm.nt_net);
+	printf("%s %d %s\n", buf, nm.nt_len, nm.nt_name);
+	return 0;
+}
+#endif
Index: src/usr.sbin/mountd/mountd.h
diff -u /dev/null src/usr.sbin/mountd/mountd.h:1.1
--- /dev/null	Wed Dec 23 11:19:49 2015
+++ src/usr.sbin/mountd/mountd.h	Wed Dec 23 11:19:49 2015
@@ -0,0 +1,22 @@
+
+#define	OP_MAPROOT	0x001
+#define	OP_MAPALL	0x002
+#define	OP_KERB		0x004
+#define	OP_MASK		0x008
+#define	OP_NET		0x010
+#define	OP_ALLDIRS	0x040
+#define OP_NORESPORT	0x080
+#define OP_NORESMNT	0x100
+#define OP_MASKLEN	0x200
+
+extern int opt_flags;
+extern int debug;
+extern const int ninumeric;
+
+struct netmsk {
+	struct sockaddr_storage nt_net;
+	int		nt_len;
+	char           *nt_name;
+};
+
+int get_net(char *, struct netmsk *, int);

Reply via email to