]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/nfs/nfs_boot.c
xnu-3248.60.10.tar.gz
[apple/xnu.git] / bsd / nfs / nfs_boot.c
index 1dbe1238d724786bfc720ec1dae92280f14d2c0c..7fcd73beebc883f81ccbbef257573c043daebd8e 100644 (file)
@@ -1,31 +1,29 @@
 /*
- * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
  *
- * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
- * This file contains Original Code and/or Modifications of Original Code 
- * as defined in and that are subject to the Apple Public Source License 
- * Version 2.0 (the 'License'). You may not use this file except in 
- * compliance with the License.  The rights granted to you under the 
- * License may not be used to create, or enable the creation or 
- * redistribution of, unlawful or unlicensed copies of an Apple operating 
- * system, or to circumvent, violate, or enable the circumvention or 
- * violation of, any terms of an Apple operating system software license 
- * agreement.
- *
- * Please obtain a copy of the License at 
- * http://www.opensource.apple.com/apsl/ and read it before using this 
- * file.
- *
- * The Original Code and all software distributed under the License are 
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
- * Please see the License for the specific language governing rights and 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ * 
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
  * limitations under the License.
- *
- * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
+ * 
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /* Copyright (c) 1995, 1997 NeXT Computer, Inc. All Rights Reserved */
 /*
 
 #if NETHER == 0
 
-int nfs_boot_init(struct nfs_diskless *nd, proc_t procp)
+int nfs_boot_init(__unused struct nfs_diskless *nd)
 {
        panic("nfs_boot_init: no ether");
 }
 
-int nfs_boot_getfh(struct nfs_diskless *nd, proc_t procp, int v3, int sotype)
+int nfs_boot_getfh(__unused struct nfs_diskless *nd, __unused int v3, __unused int sotype)
 {
        panic("nfs_boot_getfh: no ether");
 }
@@ -169,7 +167,7 @@ static int bp_getfile(struct sockaddr_in *bpsin, const char *key,
 
 /* mountd RPC */
 static int md_mount(struct sockaddr_in *mdsin, char *path, int v3, int sotype,
-       u_char *fhp, u_long *fhlenp);
+       u_char *fhp, u_int32_t *fhlenp);
 
 /* other helpers */
 static int get_file_handle(struct nfs_dlmount *ndmntp);
@@ -179,19 +177,13 @@ static int get_file_handle(struct nfs_dlmount *ndmntp);
 #define IP_CH(ip)      ((u_char *)ip)
 #define IP_LIST(ip)    IP_CH(ip)[0],IP_CH(ip)[1],IP_CH(ip)[2],IP_CH(ip)[3]
 
-extern boolean_t
-netboot_iaddr(struct in_addr * iaddr_p);
-
-extern boolean_t
-netboot_rootpath(struct in_addr * server_ip,
-                char * name, int name_len, 
-                char * path, int path_len);
+#include <sys/netboot.h>
 
 /*
  * Called with an empty nfs_diskless struct to be filled in.
  */
 int
-nfs_boot_init(struct nfs_diskless *nd, __unused proc_t procp)
+nfs_boot_init(struct nfs_diskless *nd)
 {
        struct sockaddr_in      bp_sin;
        boolean_t               do_bpwhoami = TRUE;
@@ -201,7 +193,7 @@ nfs_boot_init(struct nfs_diskless *nd, __unused proc_t procp)
        struct sockaddr_in *    sin_p;
 
        /* make sure mbuf constants are set up */
-       if (!nfs_mbuf_mlen)
+       if (!nfs_mbuf_mhlen)
                nfs_mbuf_init();
 
        /* by this point, networking must already have been configured */
@@ -218,11 +210,17 @@ nfs_boot_init(struct nfs_diskless *nd, __unused proc_t procp)
            error = ENOMEM;
            goto failed;
        }
+       MALLOC_ZONE(nd->nd_root.ndm_mntfrom, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
+       if (!nd->nd_root.ndm_mntfrom) {
+           printf("nfs_boot: can't allocate root mntfrom buffer\n");
+           error = ENOMEM;
+           goto failed;
+       }
        sin_p = &nd->nd_root.ndm_saddr;
        bzero((caddr_t)sin_p, sizeof(*sin_p));
        sin_p->sin_len = sizeof(*sin_p);
        sin_p->sin_family = AF_INET;
-       if (netboot_rootpath(&sin_p->sin_addr, nd->nd_root.ndm_host, 
+       if (netboot_rootpath(&sin_p->sin_addr, nd->nd_root.ndm_host,
                             sizeof(nd->nd_root.ndm_host),
                             nd->nd_root.ndm_path, MAXPATHLEN) == TRUE) {
            do_bpgetfile = FALSE;
@@ -272,6 +270,12 @@ nfs_boot_init(struct nfs_diskless *nd, __unused proc_t procp)
                        error = ENOMEM;
                        goto failed;
                }
+               MALLOC_ZONE(nd->nd_private.ndm_mntfrom, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
+               if (!nd->nd_private.ndm_mntfrom) {
+                       printf("nfs_boot: can't allocate private host buffer\n");
+                       error = ENOMEM;
+                       goto failed;
+               }
                error = bp_getfile(&bp_sin, "private", 
                                   &nd->nd_private.ndm_saddr,
                                   nd->nd_private.ndm_host,
@@ -288,7 +292,7 @@ nfs_boot_init(struct nfs_diskless *nd, __unused proc_t procp)
                        snprintf(check_path, MAXPATHLEN, "%s/private", nd->nd_root.ndm_path);
                        if ((nd->nd_root.ndm_saddr.sin_addr.s_addr 
                             == nd->nd_private.ndm_saddr.sin_addr.s_addr)
-                           && (strcmp(check_path, nd->nd_private.ndm_path) == 0)) {
+                           && (strncmp(check_path, nd->nd_private.ndm_path, MAXPATHLEN) == 0)) {
                                /* private path is prefix of root path, don't mount */
                                nd->nd_private.ndm_saddr.sin_addr.s_addr = 0;
                        }
@@ -312,7 +316,7 @@ failed:
  * with file handles to be filled in.
  */
 int
-nfs_boot_getfh(struct nfs_diskless *nd, __unused proc_t procp, int v3, int sotype)
+nfs_boot_getfh(struct nfs_diskless *nd, int v3, int sotype)
 {
        int error = 0;
 
@@ -359,10 +363,12 @@ get_file_handle(ndmntp)
                return (error);
 
        /* Construct remote path (for getmntinfo(3)) */
-       dp = ndmntp->ndm_host;
-       endp = dp + MNAMELEN - 1;
-       dp += strlen(dp);
-       *dp++ = ':';
+       dp = ndmntp->ndm_mntfrom;
+       endp = dp + MAXPATHLEN - 1;
+       for (sp = ndmntp->ndm_host; *sp && dp < endp;)
+               *dp++ = *sp++;
+       if (dp < endp)
+               *dp++ = ':';
        for (sp = ndmntp->ndm_path; *sp && dp < endp;)
                *dp++ = *sp++;
        *dp = '\0';
@@ -376,7 +382,7 @@ get_file_handle(ndmntp)
  * initialize the pkthdr length field.
  */
 static int
-mbuf_get_with_len(int msg_len, mbuf_t *m)
+mbuf_get_with_len(size_t msg_len, mbuf_t *m)
 {
        int error;
        error = mbuf_gethdr(MBUF_WAITOK, MBUF_TYPE_DATA, m);
@@ -401,7 +407,7 @@ mbuf_get_with_len(int msg_len, mbuf_t *m)
  * String representation for RPC.
  */
 struct rpc_string {
-       u_long len;             /* length without null or padding */
+       u_int32_t len;          /* length without null or padding */
        u_char data[4]; /* data (longer, of course) */
     /* data is padded to a long-word boundary */
 };
@@ -410,11 +416,11 @@ struct rpc_string {
 
 /*
  * Inet address in RPC messages
- * (Note, really four longs, NOT chars.  Blech.)
+ * (Note, really four 32-bit ints, NOT chars.  Blech.)
  */
 struct bp_inaddr {
-       u_long  atype;
-       long    addr[4];
+       u_int32_t  atype;
+       int32_t addr[4];
 };
 
 
@@ -441,10 +447,10 @@ bp_whoami(bpsin, my_ip, gw_ip)
 {
        /* RPC structures for PMAPPROC_CALLIT */
        struct whoami_call {
-               u_long call_prog;
-               u_long call_vers;
-               u_long call_proc;
-               u_long call_arglen;
+               u_int32_t call_prog;
+               u_int32_t call_vers;
+               u_int32_t call_proc;
+               u_int32_t call_arglen;
                struct bp_inaddr call_ia;
        } *call;
 
@@ -452,10 +458,10 @@ bp_whoami(bpsin, my_ip, gw_ip)
        struct bp_inaddr *bia;
        mbuf_t m;
        struct sockaddr_in sin;
-       int error, msg_len;
-       int cn_len, dn_len;
+       int error;
+       size_t msg_len, cn_len, dn_len;
        u_char *p;
-       long *lp;
+       int32_t *lp;
 
        /*
         * Get message buffer of sufficient size.
@@ -497,20 +503,20 @@ bp_whoami(bpsin, my_ip, gw_ip)
        lp = mbuf_data(m);
 
        /* bootparam server port (also grab from address). */
-       if (msg_len < (int)sizeof(*lp))
+       if (msg_len < sizeof(*lp))
                goto bad;
        msg_len -= sizeof(*lp);
        bpsin->sin_port = htons((short)ntohl(*lp++));
        bpsin->sin_addr.s_addr = sin.sin_addr.s_addr;
 
        /* length of encapsulated results */
-       if (msg_len < (ntohl(*lp) + (int)sizeof(*lp)))
+       if (msg_len < (ntohl(*lp) + sizeof(*lp)))
                goto bad;
        msg_len = ntohl(*lp++);
-       p = (char*)lp;
+       p = (u_char*)lp;
 
        /* client name */
-       if (msg_len < (int)sizeof(*str))
+       if (msg_len < sizeof(*str))
                goto bad;
        str = (struct rpc_string *)p;
        cn_len = ntohl(str->len);
@@ -525,7 +531,7 @@ bp_whoami(bpsin, my_ip, gw_ip)
        msg_len -= RPC_STR_SIZE(cn_len);
 
        /* domain name */
-       if (msg_len < (int)sizeof(*str))
+       if (msg_len < sizeof(*str))
                goto bad;
        str = (struct rpc_string *)p;
        dn_len = ntohl(str->len);
@@ -540,7 +546,7 @@ bp_whoami(bpsin, my_ip, gw_ip)
        msg_len -= RPC_STR_SIZE(dn_len);
 
        /* gateway address */
-       if (msg_len < (int)sizeof(*bia))
+       if (msg_len < sizeof(*bia))
                goto bad;
        bia = (struct bp_inaddr *)p;
        if (bia->atype != htonl(1))
@@ -631,7 +637,7 @@ bp_getfile(bpsin, key, md_sin, serv_name, pathname)
        sn_len = ntohl(str->len);
        if (msg_len < sn_len)
                goto bad;
-       if (sn_len >= MNAMELEN)
+       if (sn_len >= MAXHOSTNAMELEN)
                goto bad;
        bcopy(str->data, serv_name, sn_len);
        serv_name[sn_len] = '\0';
@@ -691,13 +697,13 @@ md_mount(mdsin, path, v3, sotype, fhp, fhlenp)
        int v3;
        int sotype;
        u_char *fhp;
-       u_long *fhlenp;
+       u_int32_t *fhlenp;
 {
        /* The RPC structures */
        struct rpc_string *str;
        struct rdata {
-               u_long  errno;
-               u_char  data[NFSX_V3FHMAX + sizeof(u_long)];
+               u_int32_t       errno;
+               u_char  data[NFSX_V3FHMAX + sizeof(u_int32_t)];
        } *rdata;
        mbuf_t m;
        int error, mlen, slen;
@@ -740,25 +746,25 @@ md_mount(mdsin, path, v3, sotype, fhp, fhlenp)
         * + a v3 filehandle length + a v3 filehandle
         */
        mlen = mbuf_len(m);
-       if (mlen < (int)sizeof(u_long))
+       if (mlen < (int)sizeof(u_int32_t))
                goto bad;
        rdata = mbuf_data(m);
        error = ntohl(rdata->errno);
        if (error)
                goto out;
        if (v3) {
-               u_long fhlen;
+               u_int32_t fhlen;
                u_char *fh;
-               if (mlen < (int)sizeof(u_long)*2)
+               if (mlen < (int)sizeof(u_int32_t)*2)
                        goto bad;
-               fhlen = ntohl(*(u_long*)rdata->data);
-               fh = rdata->data + sizeof(u_long);
-               if (mlen < (int)(sizeof(u_long)*2 + fhlen))
+               fhlen = ntohl(*(u_int32_t*)rdata->data);
+               fh = rdata->data + sizeof(u_int32_t);
+               if (mlen < (int)(sizeof(u_int32_t)*2 + fhlen))
                        goto bad;
                bcopy(fh, fhp, fhlen);
                *fhlenp = fhlen;
        } else {
-               if (mlen < ((int)sizeof(u_long) + NFSX_V2FH))
+               if (mlen < ((int)sizeof(u_int32_t) + NFSX_V2FH))
                        goto bad;
                bcopy(rdata->data, fhp, NFSX_V2FH);
                *fhlenp = NFSX_V2FH;