/* $NetBSD: getnfsargs_small.c,v 1.9 2011/07/06 09:02:54 mrg Exp $ */ /*- * Copyright (c) 2006 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by David Laight. * * 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. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. */ /*- * Copyright (c) 1993 John Brezak * All rights reserved. * * 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. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `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 AUTHOR 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. */ /* * Copyright (c) 1992, 1993, 1994 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * 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 __RCSID("$NetBSD: getnfsargs_small.c,v 1.9 2011/07/06 09:02:54 mrg Exp $"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mount_nfs.h" #include "iodesc.h" typedef int32_t n_long; #include "rpc.h" #define RPC_HEADER_WORDS 28 /* more than enough */ #define FNAME_SIZE 512 struct nfhret { long fhsize; u_char nfh[NFSX_V3FHMAX]; }; /* Ripped from src/sys/arch/i386/stand/libsa/nfs.c */ static int nfs_getrootfh(struct iodesc *d, const char *path, int mntvers, struct nfhret *nfhret) { size_t len; struct args { uint32_t len; char path[FNAME_SIZE]; } *args; struct repl { uint32_t errval; u_char fh[NFSX_V3FHMAX]; } *repl; struct { uint32_t h[RPC_HEADER_WORDS]; struct args d; } sdata; struct { uint32_t h[RPC_HEADER_WORDS]; struct repl d; } rdata; ssize_t cc; args = &sdata.d; repl = &rdata.d; memset(args, 0, sizeof(*args)); len = strlen(path); if (len > sizeof(args->path)) len = sizeof(args->path); args->len = htonl(len); memcpy(args->path, path, len); len = 4 + roundup(len, 4); cc = rpc_call(d, RPCPROG_MNT, mntvers, RPCMNT_MOUNT, args, len, repl, sizeof(*repl)); if (cc == -1) { /* errno was set by rpc_call */ return errno; } if (cc < 4) return EBADRPC; if (repl->errval) return ntohl(repl->errval); nfhret->fhsize = cc; memcpy(nfhret->nfh, repl->fh, sizeof(repl->fh)); return 0; } int getnfsargs(char *spec, struct nfs_args *nfsargsp) { struct addrinfo hints, *ai_nfs; int ecode; int nfsvers, mntvers; char *hostp, *delimp; static struct nfhret nfhret; static char nam[MNAMELEN + 1]; struct iodesc d; int nfs_port; strlcpy(nam, spec, sizeof(nam)); if ((delimp = strchr(spec, '@')) != NULL) { hostp = delimp + 1; } else if ((delimp = strrchr(spec, ':')) != NULL) { hostp = spec; spec = delimp + 1; } else { warnx("no : or @ spec"); return 0; } *delimp = '\0'; memset(&hints, 0, sizeof hints); hints.ai_socktype = nfsargsp->sotype; if ((ecode = getaddrinfo(hostp, "nfs", &hints, &ai_nfs)) != 0) { warnx("can't get net id for host \"%s\": %s", hostp, gai_strerror(ecode)); return 0; } if ((nfsargsp->flags & NFSMNT_NFSV3) != 0) { nfsvers = NFS_VER3; mntvers = RPCMNT_VER3; } else { nfsvers = NFS_VER2; mntvers = RPCMNT_VER1; } d.socket = -1; for (d.ai = ai_nfs; ; d.ai = d.ai->ai_next) { if (d.ai == NULL) { if (nfsvers == NFS_VER3 && !force3) { nfsvers = NFS_VER2; mntvers = RPCMNT_VER1; d.ai = ai_nfs; continue; } return 0; } nfs_port = rpc_getport(&d, RPCPROG_NFS, nfsvers); if (nfs_port == -1) continue; if (nfs_getrootfh(&d, spec, mntvers, &nfhret) == 0) break; } if (port != 0) nfs_port = port; set_port(d.ai->ai_addr, htons(nfs_port)); nfsargsp->hostname = nam; nfsargsp->addr = d.ai->ai_addr; nfsargsp->addrlen = d.ai->ai_addrlen; nfsargsp->fh = nfhret.nfh; if (nfsvers == NFS_VER3) { nfsargsp->fhsize = be32dec(nfhret.nfh); nfsargsp->fh += sizeof(uint32_t); } else { nfsargsp->fhsize = NFSX_V2FH; nfsargsp->flags &= ~NFSMNT_NFSV3; } return 1; }