Home | History | Annotate | Line # | Download | only in mount_nfs
      1  1.10  christos /*	$NetBSD: getnfsargs_small.c,v 1.10 2013/06/29 22:56:26 christos Exp $	*/
      2   1.1       dsl 
      3   1.1       dsl /*-
      4   1.1       dsl  * Copyright (c) 2006 The NetBSD Foundation, Inc.
      5   1.1       dsl  * All rights reserved.
      6   1.1       dsl  *
      7   1.1       dsl  * This code is derived from software contributed to The NetBSD Foundation
      8   1.1       dsl  * by David Laight.
      9   1.1       dsl  *
     10   1.1       dsl  * Redistribution and use in source and binary forms, with or without
     11   1.1       dsl  * modification, are permitted provided that the following conditions
     12   1.1       dsl  * are met:
     13   1.1       dsl  * 1. Redistributions of source code must retain the above copyright
     14   1.1       dsl  *    notice, this list of conditions and the following disclaimer.
     15   1.1       dsl  * 2. Redistributions in binary form must reproduce the above copyright
     16   1.1       dsl  *    notice, this list of conditions and the following disclaimer in the
     17   1.1       dsl  *    documentation and/or other materials provided with the distribution.
     18   1.1       dsl  *
     19   1.1       dsl  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20   1.1       dsl  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21   1.1       dsl  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22   1.1       dsl  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23   1.1       dsl  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24   1.1       dsl  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25   1.1       dsl  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26   1.1       dsl  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27   1.1       dsl  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28   1.1       dsl  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29   1.1       dsl  * POSSIBILITY OF SUCH DAMAGE.
     30   1.1       dsl  */
     31   1.1       dsl 
     32   1.2      yamt /*-
     33   1.2      yamt  *  Copyright (c) 1993 John Brezak
     34   1.2      yamt  *  All rights reserved.
     35   1.2      yamt  *
     36   1.2      yamt  *  Redistribution and use in source and binary forms, with or without
     37   1.2      yamt  *  modification, are permitted provided that the following conditions
     38   1.2      yamt  *  are met:
     39   1.2      yamt  *  1. Redistributions of source code must retain the above copyright
     40   1.2      yamt  *     notice, this list of conditions and the following disclaimer.
     41   1.2      yamt  *  2. Redistributions in binary form must reproduce the above copyright
     42   1.2      yamt  *     notice, this list of conditions and the following disclaimer in the
     43   1.2      yamt  *     documentation and/or other materials provided with the distribution.
     44   1.2      yamt  *  3. The name of the author may not be used to endorse or promote products
     45   1.2      yamt  *     derived from this software without specific prior written permission.
     46   1.2      yamt  *
     47   1.2      yamt  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
     48   1.2      yamt  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     49   1.2      yamt  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     50   1.2      yamt  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
     51   1.2      yamt  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     52   1.2      yamt  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     53   1.2      yamt  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     54   1.2      yamt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     55   1.2      yamt  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     56   1.2      yamt  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     57   1.2      yamt  * POSSIBILITY OF SUCH DAMAGE.
     58   1.2      yamt  */
     59   1.2      yamt 
     60   1.2      yamt /*
     61   1.2      yamt  * Copyright (c) 1992, 1993, 1994
     62   1.2      yamt  *	The Regents of the University of California.  All rights reserved.
     63   1.2      yamt  *
     64   1.2      yamt  * This code is derived from software contributed to Berkeley by
     65   1.2      yamt  * Rick Macklem at The University of Guelph.
     66   1.2      yamt  *
     67   1.2      yamt  * Redistribution and use in source and binary forms, with or without
     68   1.2      yamt  * modification, are permitted provided that the following conditions
     69   1.2      yamt  * are met:
     70   1.2      yamt  * 1. Redistributions of source code must retain the above copyright
     71   1.2      yamt  *    notice, this list of conditions and the following disclaimer.
     72   1.2      yamt  * 2. Redistributions in binary form must reproduce the above copyright
     73   1.2      yamt  *    notice, this list of conditions and the following disclaimer in the
     74   1.2      yamt  *    documentation and/or other materials provided with the distribution.
     75   1.2      yamt  * 3. Neither the name of the University nor the names of its contributors
     76   1.2      yamt  *    may be used to endorse or promote products derived from this software
     77   1.2      yamt  *    without specific prior written permission.
     78   1.2      yamt  *
     79   1.2      yamt  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     80   1.2      yamt  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     81   1.2      yamt  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     82   1.2      yamt  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     83   1.2      yamt  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     84   1.2      yamt  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     85   1.2      yamt  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     86   1.2      yamt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     87   1.2      yamt  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     88   1.2      yamt  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     89   1.2      yamt  * SUCH DAMAGE.
     90   1.2      yamt  */
     91   1.2      yamt 
     92   1.1       dsl #include <sys/cdefs.h>
     93  1.10  christos __RCSID("$NetBSD: getnfsargs_small.c,v 1.10 2013/06/29 22:56:26 christos Exp $");
     94   1.1       dsl 
     95   1.1       dsl #include <sys/param.h>
     96   1.1       dsl #include <sys/mount.h>
     97   1.1       dsl #include <sys/socket.h>
     98   1.1       dsl #include <sys/stat.h>
     99   1.1       dsl #include <syslog.h>
    100   1.1       dsl 
    101   1.1       dsl #include <nfs/rpcv2.h>
    102   1.1       dsl #include <nfs/nfsproto.h>
    103   1.1       dsl #include <nfs/nfs.h>
    104   1.1       dsl #include <nfs/nfsmount.h>
    105   1.1       dsl 
    106   1.1       dsl #include <arpa/inet.h>
    107   1.1       dsl 
    108   1.1       dsl #include <err.h>
    109   1.1       dsl #include <errno.h>
    110   1.1       dsl #include <fcntl.h>
    111   1.1       dsl #include <netdb.h>
    112   1.1       dsl #include <signal.h>
    113   1.1       dsl #include <stdio.h>
    114   1.1       dsl #include <stdlib.h>
    115   1.1       dsl #include <string.h>
    116   1.1       dsl #include <unistd.h>
    117   1.1       dsl #include <util.h>
    118   1.1       dsl 
    119   1.1       dsl #include "mount_nfs.h"
    120   1.1       dsl 
    121   1.1       dsl #include "iodesc.h"
    122   1.1       dsl typedef int32_t n_long;
    123   1.1       dsl #include "rpc.h"
    124   1.1       dsl 
    125   1.1       dsl #define RPC_HEADER_WORDS 28	/* more than enough */
    126   1.1       dsl #define FNAME_SIZE 512
    127   1.1       dsl 
    128   1.1       dsl struct nfhret {
    129   1.1       dsl 	long		fhsize;
    130   1.1       dsl 	u_char		nfh[NFSX_V3FHMAX];
    131   1.1       dsl };
    132   1.1       dsl 
    133  1.10  christos int retrycnt = DEF_RETRY;
    134  1.10  christos int opflags = 0;
    135  1.10  christos int force2 = 0;
    136  1.10  christos int force3 = 0;
    137  1.10  christos int mnttcp_ok = 1;
    138  1.10  christos int port = 0;
    139  1.10  christos 
    140   1.1       dsl /* Ripped from src/sys/arch/i386/stand/libsa/nfs.c */
    141   1.1       dsl static int
    142   1.1       dsl nfs_getrootfh(struct iodesc *d, const char *path, int mntvers, struct nfhret *nfhret)
    143   1.1       dsl {
    144   1.1       dsl 	size_t len;
    145   1.1       dsl 	struct args {
    146   1.1       dsl 		uint32_t len;
    147   1.1       dsl 		char	path[FNAME_SIZE];
    148   1.1       dsl 	} *args;
    149   1.1       dsl 	struct repl {
    150   1.1       dsl 		uint32_t errval;
    151   1.1       dsl 		u_char	fh[NFSX_V3FHMAX];
    152   1.1       dsl 	} *repl;
    153   1.1       dsl 	struct {
    154   1.1       dsl 		uint32_t h[RPC_HEADER_WORDS];
    155   1.1       dsl 		struct args d;
    156   1.1       dsl 	} sdata;
    157   1.1       dsl 	struct {
    158   1.1       dsl 		uint32_t h[RPC_HEADER_WORDS];
    159   1.1       dsl 		struct repl d;
    160   1.1       dsl 	} rdata;
    161   1.1       dsl 	ssize_t cc;
    162   1.1       dsl 
    163   1.1       dsl 	args = &sdata.d;
    164   1.1       dsl 	repl = &rdata.d;
    165   1.1       dsl 
    166   1.1       dsl 	memset(args, 0, sizeof(*args));
    167   1.1       dsl 	len = strlen(path);
    168   1.1       dsl 	if (len > sizeof(args->path))
    169   1.1       dsl 		len = sizeof(args->path);
    170   1.1       dsl 	args->len = htonl(len);
    171   1.1       dsl 	memcpy(args->path, path, len);
    172   1.1       dsl 	len = 4 + roundup(len, 4);
    173   1.1       dsl 
    174   1.1       dsl 	cc = rpc_call(d, RPCPROG_MNT, mntvers, RPCMNT_MOUNT,
    175   1.1       dsl 	    args, len, repl, sizeof(*repl));
    176   1.1       dsl 	if (cc == -1) {
    177   1.1       dsl 		/* errno was set by rpc_call */
    178   1.1       dsl 		return errno;
    179   1.1       dsl 	}
    180   1.1       dsl 	if (cc < 4)
    181   1.1       dsl 		return EBADRPC;
    182   1.1       dsl 	if (repl->errval)
    183   1.1       dsl 		return ntohl(repl->errval);
    184   1.1       dsl 	nfhret->fhsize = cc;
    185   1.1       dsl 	memcpy(nfhret->nfh, repl->fh, sizeof(repl->fh));
    186   1.1       dsl 	return 0;
    187   1.1       dsl }
    188   1.1       dsl 
    189   1.1       dsl int
    190   1.1       dsl getnfsargs(char *spec, struct nfs_args *nfsargsp)
    191   1.1       dsl {
    192   1.1       dsl 	struct addrinfo hints, *ai_nfs;
    193   1.1       dsl 	int ecode;
    194   1.1       dsl 	int nfsvers, mntvers;
    195   1.1       dsl 	char *hostp, *delimp;
    196   1.1       dsl 	static struct nfhret nfhret;
    197   1.1       dsl 	static char nam[MNAMELEN + 1];
    198   1.1       dsl 	struct iodesc d;
    199   1.1       dsl 	int nfs_port;
    200   1.1       dsl 
    201   1.5   hubertf 	strlcpy(nam, spec, sizeof(nam));
    202   1.1       dsl 	if ((delimp = strchr(spec, '@')) != NULL) {
    203   1.1       dsl 		hostp = delimp + 1;
    204   1.1       dsl 	} else if ((delimp = strrchr(spec, ':')) != NULL) {
    205   1.1       dsl 		hostp = spec;
    206   1.1       dsl 		spec = delimp + 1;
    207   1.1       dsl 	} else {
    208   1.1       dsl 		warnx("no <host>:<dirpath> or <dirpath>@<host> spec");
    209   1.1       dsl 		return 0;
    210   1.1       dsl 	}
    211   1.1       dsl 	*delimp = '\0';
    212   1.1       dsl 
    213   1.1       dsl 	memset(&hints, 0, sizeof hints);
    214   1.1       dsl 	hints.ai_socktype = nfsargsp->sotype;
    215   1.1       dsl 
    216   1.1       dsl 	if ((ecode = getaddrinfo(hostp, "nfs", &hints, &ai_nfs)) != 0) {
    217   1.1       dsl 		warnx("can't get net id for host \"%s\": %s", hostp,
    218   1.1       dsl 		    gai_strerror(ecode));
    219   1.1       dsl 		return 0;
    220   1.1       dsl 	}
    221   1.1       dsl 
    222   1.4      yamt 	if ((nfsargsp->flags & NFSMNT_NFSV3) != 0) {
    223   1.4      yamt 		nfsvers = NFS_VER3;
    224   1.4      yamt 		mntvers = RPCMNT_VER3;
    225   1.4      yamt 	} else {
    226   1.1       dsl 		nfsvers = NFS_VER2;
    227   1.1       dsl 		mntvers = RPCMNT_VER1;
    228   1.1       dsl 	}
    229   1.1       dsl 
    230   1.1       dsl 	d.socket = -1;
    231   1.1       dsl 	for (d.ai = ai_nfs; ; d.ai = d.ai->ai_next) {
    232   1.1       dsl 		if (d.ai == NULL) {
    233   1.1       dsl 			if (nfsvers == NFS_VER3 && !force3) {
    234   1.1       dsl 				nfsvers = NFS_VER2;
    235   1.1       dsl 				mntvers = RPCMNT_VER1;
    236   1.1       dsl 				d.ai = ai_nfs;
    237   1.1       dsl 				continue;
    238   1.1       dsl 			}
    239   1.1       dsl 			return 0;
    240   1.1       dsl 		}
    241   1.1       dsl 		nfs_port = rpc_getport(&d, RPCPROG_NFS, nfsvers);
    242   1.1       dsl 		if (nfs_port == -1)
    243   1.1       dsl 			continue;
    244   1.1       dsl 		if (nfs_getrootfh(&d, spec, mntvers, &nfhret) == 0)
    245   1.1       dsl 			break;
    246   1.1       dsl 	}
    247   1.1       dsl 
    248   1.1       dsl 	if (port != 0)
    249   1.1       dsl 		nfs_port = port;
    250   1.1       dsl 	set_port(d.ai->ai_addr, htons(nfs_port));
    251   1.1       dsl 
    252   1.1       dsl 	nfsargsp->hostname = nam;
    253   1.1       dsl 	nfsargsp->addr = d.ai->ai_addr;
    254   1.1       dsl 	nfsargsp->addrlen = d.ai->ai_addrlen;
    255   1.1       dsl 
    256   1.1       dsl 	nfsargsp->fh = nfhret.nfh;
    257   1.1       dsl 	if (nfsvers == NFS_VER3) {
    258   1.9       mrg 		nfsargsp->fhsize = be32dec(nfhret.nfh);
    259   1.9       mrg 		nfsargsp->fh += sizeof(uint32_t);
    260   1.1       dsl 	} else {
    261   1.3      yamt 		nfsargsp->fhsize = NFSX_V2FH;
    262   1.1       dsl 		nfsargsp->flags &= ~NFSMNT_NFSV3;
    263   1.1       dsl 	}
    264   1.1       dsl 	return 1;
    265   1.1       dsl }
    266