Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.sbin/mountd Split out get_net function so that it is eas...



details:   https://anonhg.NetBSD.org/src/rev/d16bd5b52091
branches:  trunk
changeset: 342472:d16bd5b52091
user:      christos <christos%NetBSD.org@localhost>
date:      Wed Dec 23 16:19:49 2015 +0000

description:
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.

diffstat:

 usr.sbin/mountd/Makefile  |    4 +-
 usr.sbin/mountd/get_net.c |  236 ++++++++++++++++++++++++++++++++++++++++++++++
 usr.sbin/mountd/mountd.c  |  185 +----------------------------------
 usr.sbin/mountd/mountd.h  |   22 ++++
 4 files changed, 267 insertions(+), 180 deletions(-)

diffs (truncated from 532 to 300 lines):

diff -r 7f45279e5735 -r d16bd5b52091 usr.sbin/mountd/Makefile
--- a/usr.sbin/mountd/Makefile  Wed Dec 23 13:42:24 2015 +0000
+++ b/usr.sbin/mountd/Makefile  Wed Dec 23 16:19:49 2015 +0000
@@ -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
diff -r 7f45279e5735 -r d16bd5b52091 usr.sbin/mountd/get_net.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.sbin/mountd/get_net.c Wed Dec 23 16:19:49 2015 +0000
@@ -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
diff -r 7f45279e5735 -r d16bd5b52091 usr.sbin/mountd/mountd.c
--- a/usr.sbin/mountd/mountd.c  Wed Dec 23 13:42:24 2015 +0000
+++ b/usr.sbin/mountd/mountd.c  Wed Dec 23 16:19:49 2015 +0000
@@ -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 @@
 #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 @@
 #define DEBUGGING 0
 #endif
 
+#include "mountd.h"
+
 /*
  * Structures for keeping the mount list and export list
  */
@@ -140,12 +142,6 @@
 /* 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 @@
     struct grouplist *);
 static struct hostlist *get_ht(void);
 static void get_mountlist(void);



Home | Main Index | Thread Index | Old Index