]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/nfs/nfs_boot.c
xnu-2422.90.20.tar.gz
[apple/xnu.git] / bsd / nfs / nfs_boot.c
index a0d9245a6f72706791757fb17f7de7f95c6f62f6..7fcd73beebc883f81ccbbef257573c043daebd8e 100644 (file)
@@ -1,16 +1,19 @@
 /*
 /*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
  *
  *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
+ * @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
  * 
  * 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. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
+ * 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
  * 
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
@@ -20,7 +23,7 @@
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * 
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * 
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /* Copyright (c) 1995, 1997 NeXT Computer, Inc. All Rights Reserved */
 /*
  */
 /* Copyright (c) 1995, 1997 NeXT Computer, Inc. All Rights Reserved */
 /*
 #include <sys/conf.h>
 #include <sys/ioctl.h>
 #include <sys/proc.h>
 #include <sys/conf.h>
 #include <sys/ioctl.h>
 #include <sys/proc.h>
-#include <sys/mount.h>
-#include <sys/mbuf.h>
+#include <sys/mount_internal.h>
+#include <sys/kpi_mbuf.h>
 
 #include <sys/malloc.h>
 #include <sys/socket.h>
 
 #include <sys/malloc.h>
 #include <sys/socket.h>
-#include <sys/reboot.h>
 
 #include <net/if.h>
 #include <net/if_dl.h>
 
 #include <net/if.h>
 #include <net/if_dl.h>
 
 #include <libkern/libkern.h>
 
 
 #include <libkern/libkern.h>
 
-extern char *strchr(const char *str, int ch);
 
 #if NETHER == 0
 
 
 #if NETHER == 0
 
-int nfs_boot_init(nd, procp)
-       struct nfs_diskless *nd;
-       struct proc *procp;
+int nfs_boot_init(__unused struct nfs_diskless *nd)
 {
        panic("nfs_boot_init: no ether");
 }
 
 {
        panic("nfs_boot_init: no ether");
 }
 
-int nfs_boot_getfh(nd, procp, v3)
-       struct nfs_diskless *nd;
-       struct proc *procp;
-       int v3;
+int nfs_boot_getfh(__unused struct nfs_diskless *nd, __unused int v3, __unused int sotype)
 {
        panic("nfs_boot_getfh: no ether");
 }
 {
        panic("nfs_boot_getfh: no ether");
 }
@@ -164,38 +160,30 @@ int nfs_boot_getfh(nd, procp, v3)
  */
 
 /* bootparam RPC */
  */
 
 /* bootparam RPC */
-static int bp_whoami __P((struct sockaddr_in *bpsin,
-       struct in_addr *my_ip, struct in_addr *gw_ip));
-static int bp_getfile __P((struct sockaddr_in *bpsin, char *key,
-       struct sockaddr_in *mdsin, char *servname, char *path));
+static int bp_whoami(struct sockaddr_in *bpsin,
+       struct in_addr *my_ip, struct in_addr *gw_ip);
+static int bp_getfile(struct sockaddr_in *bpsin, const char *key,
+       struct sockaddr_in *mdsin, char *servname, char *path);
 
 /* mountd RPC */
 
 /* mountd RPC */
-static int md_mount __P((struct sockaddr_in *mdsin, char *path, int v3,
-       u_char *fhp, u_long *fhlenp));
+static int md_mount(struct sockaddr_in *mdsin, char *path, int v3, int sotype,
+       u_char *fhp, u_int32_t *fhlenp);
 
 /* other helpers */
 
 /* other helpers */
-static int get_file_handle __P((struct nfs_dlmount *ndmntp));
+static int get_file_handle(struct nfs_dlmount *ndmntp);
 
 
 #define IP_FORMAT      "%d.%d.%d.%d"
 #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]
 
 
 
 #define IP_FORMAT      "%d.%d.%d.%d"
 #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
 
 /*
  * Called with an empty nfs_diskless struct to be filled in.
  */
 int
-nfs_boot_init(nd, procp)
-       struct nfs_diskless *nd;
-       struct proc *procp;
+nfs_boot_init(struct nfs_diskless *nd)
 {
        struct sockaddr_in      bp_sin;
        boolean_t               do_bpwhoami = TRUE;
 {
        struct sockaddr_in      bp_sin;
        boolean_t               do_bpwhoami = TRUE;
@@ -204,20 +192,35 @@ nfs_boot_init(nd, procp)
        struct in_addr          my_ip;
        struct sockaddr_in *    sin_p;
 
        struct in_addr          my_ip;
        struct sockaddr_in *    sin_p;
 
+       /* make sure mbuf constants are set up */
+       if (!nfs_mbuf_mhlen)
+               nfs_mbuf_init();
+
        /* by this point, networking must already have been configured */
        if (netboot_iaddr(&my_ip) == FALSE) {
            printf("nfs_boot: networking is not initialized\n");
            error = ENXIO;
        /* by this point, networking must already have been configured */
        if (netboot_iaddr(&my_ip) == FALSE) {
            printf("nfs_boot: networking is not initialized\n");
            error = ENXIO;
-           goto failed_noswitch;
+           goto failed;
        }
 
        /* get the root path information */
        MALLOC_ZONE(nd->nd_root.ndm_path, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
        }
 
        /* get the root path information */
        MALLOC_ZONE(nd->nd_root.ndm_path, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
+       if (!nd->nd_root.ndm_path) {
+           printf("nfs_boot: can't allocate root path buffer\n");
+           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;
        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;
                             sizeof(nd->nd_root.ndm_host),
                             nd->nd_root.ndm_path, MAXPATHLEN) == TRUE) {
            do_bpgetfile = FALSE;
@@ -225,8 +228,6 @@ nfs_boot_init(nd, procp)
        }
        nd->nd_private.ndm_saddr.sin_addr.s_addr = 0;
 
        }
        nd->nd_private.ndm_saddr.sin_addr.s_addr = 0;
 
-       thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
-
        if (do_bpwhoami) {
                struct in_addr router;
                /*
        if (do_bpwhoami) {
                struct in_addr router;
                /*
@@ -264,6 +265,17 @@ nfs_boot_init(nd, procp)
 #if !defined(NO_MOUNT_PRIVATE) 
        if (do_bpgetfile) { /* get private path */
                MALLOC_ZONE(nd->nd_private.ndm_path, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
 #if !defined(NO_MOUNT_PRIVATE) 
        if (do_bpgetfile) { /* get private path */
                MALLOC_ZONE(nd->nd_private.ndm_path, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
+               if (!nd->nd_private.ndm_path) {
+                       printf("nfs_boot: can't allocate private path buffer\n");
+                       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,
                error = bp_getfile(&bp_sin, "private", 
                                   &nd->nd_private.ndm_saddr,
                                   nd->nd_private.ndm_host,
@@ -272,10 +284,15 @@ nfs_boot_init(nd, procp)
                        char * check_path = NULL;
                        
                        MALLOC_ZONE(check_path, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
                        char * check_path = NULL;
                        
                        MALLOC_ZONE(check_path, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
+                       if (!check_path) {
+                               printf("nfs_boot: can't allocate check_path buffer\n");
+                               error = ENOMEM;
+                               goto failed;
+                       }
                        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)
                        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;
                        }
                                /* private path is prefix of root path, don't mount */
                                nd->nd_private.ndm_saddr.sin_addr.s_addr = 0;
                        }
@@ -291,8 +308,6 @@ nfs_boot_init(nd, procp)
        }
 #endif /* NO_MOUNT_PRIVATE */
 failed:
        }
 #endif /* NO_MOUNT_PRIVATE */
 failed:
-       thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
-failed_noswitch:
        return (error);
 }
 
        return (error);
 }
 
@@ -301,16 +316,12 @@ failed_noswitch:
  * with file handles to be filled in.
  */
 int
  * with file handles to be filled in.
  */
 int
-nfs_boot_getfh(nd, procp, v3)
-       struct nfs_diskless *nd;
-       struct proc *procp;
-       int v3;
+nfs_boot_getfh(struct nfs_diskless *nd, int v3, int sotype)
 {
        int error = 0;
 
 {
        int error = 0;
 
-       thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
-       
        nd->nd_root.ndm_nfsv3 = v3;
        nd->nd_root.ndm_nfsv3 = v3;
+       nd->nd_root.ndm_sotype = sotype;
        error = get_file_handle(&nd->nd_root);
        if (error) {
                printf("nfs_boot: get_file_handle(v%d) root failed, %d\n",
        error = get_file_handle(&nd->nd_root);
        if (error) {
                printf("nfs_boot: get_file_handle(v%d) root failed, %d\n",
@@ -322,6 +333,7 @@ nfs_boot_getfh(nd, procp, v3)
        if (nd->nd_private.ndm_saddr.sin_addr.s_addr) {
                /* get private file handle */
                nd->nd_private.ndm_nfsv3 = v3;
        if (nd->nd_private.ndm_saddr.sin_addr.s_addr) {
                /* get private file handle */
                nd->nd_private.ndm_nfsv3 = v3;
+               nd->nd_private.ndm_sotype = sotype;
                error = get_file_handle(&nd->nd_private);
                if (error) {
                        printf("nfs_boot: get_file_handle(v%d) private failed, %d\n",
                error = get_file_handle(&nd->nd_private);
                if (error) {
                        printf("nfs_boot: get_file_handle(v%d) private failed, %d\n",
@@ -330,8 +342,7 @@ nfs_boot_getfh(nd, procp, v3)
                }
        }
 #endif /* NO_MOUNT_PRIVATE */
                }
        }
 #endif /* NO_MOUNT_PRIVATE */
- failed:
-       thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
+failed:
        return (error);
 }
 
        return (error);
 }
 
@@ -347,15 +358,17 @@ get_file_handle(ndmntp)
         * using RPC to mountd/mount
         */
        error = md_mount(&ndmntp->ndm_saddr, ndmntp->ndm_path, ndmntp->ndm_nfsv3,
         * using RPC to mountd/mount
         */
        error = md_mount(&ndmntp->ndm_saddr, ndmntp->ndm_path, ndmntp->ndm_nfsv3,
-                       ndmntp->ndm_fh, &ndmntp->ndm_fhlen);
+                       ndmntp->ndm_sotype, ndmntp->ndm_fh, &ndmntp->ndm_fhlen);
        if (error)
                return (error);
 
        /* Construct remote path (for getmntinfo(3)) */
        if (error)
                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';
        for (sp = ndmntp->ndm_path; *sp && dp < endp;)
                *dp++ = *sp++;
        *dp = '\0';
@@ -368,23 +381,25 @@ get_file_handle(ndmntp)
  * Get an mbuf with the given length, and
  * initialize the pkthdr length field.
  */
  * Get an mbuf with the given length, and
  * initialize the pkthdr length field.
  */
-static struct mbuf *
-m_get_len(int msg_len)
+static int
+mbuf_get_with_len(size_t msg_len, mbuf_t *m)
 {
 {
-       struct mbuf *m;
-       m = m_gethdr(M_WAIT, MT_DATA);
-       if (m == NULL)
-               return NULL;
-       if (msg_len > MHLEN) {
-               if (msg_len > MCLBYTES)
+       int error;
+       error = mbuf_gethdr(MBUF_WAITOK, MBUF_TYPE_DATA, m);
+       if (error)
+               return (error);
+       if (msg_len > mbuf_maxlen(*m)) {
+               error = mbuf_mclget(MBUF_WAITOK, MBUF_TYPE_DATA, m);
+               if (error) {
+                       mbuf_freem(*m);
+                       return (error);
+               }
+               if (msg_len > mbuf_maxlen(*m))
                        panic("nfs_boot: msg_len > MCLBYTES");
                        panic("nfs_boot: msg_len > MCLBYTES");
-               MCLGET(m, M_WAIT);
-               if (m == NULL)
-                       return NULL;
        }
        }
-       m->m_len = msg_len;
-       m->m_pkthdr.len = m->m_len;
-       return (m);
+       mbuf_setlen(*m, msg_len);
+       mbuf_pkthdr_setlen(*m, msg_len);
+       return (0);
 }
 
 
 }
 
 
@@ -392,7 +407,7 @@ m_get_len(int msg_len)
  * String representation for RPC.
  */
 struct rpc_string {
  * 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 */
 };
        u_char data[4]; /* data (longer, of course) */
     /* data is padded to a long-word boundary */
 };
@@ -401,11 +416,11 @@ struct rpc_string {
 
 /*
  * Inet address in RPC messages
 
 /*
  * Inet address in RPC messages
- * (Note, really four longs, NOT chars.  Blech.)
+ * (Note, really four 32-bit ints, NOT chars.  Blech.)
  */
 struct bp_inaddr {
  */
 struct bp_inaddr {
-       u_long  atype;
-       long    addr[4];
+       u_int32_t  atype;
+       int32_t addr[4];
 };
 
 
 };
 
 
@@ -432,34 +447,34 @@ bp_whoami(bpsin, my_ip, gw_ip)
 {
        /* RPC structures for PMAPPROC_CALLIT */
        struct whoami_call {
 {
        /* 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;
 
        struct rpc_string *str;
        struct bp_inaddr *bia;
                struct bp_inaddr call_ia;
        } *call;
 
        struct rpc_string *str;
        struct bp_inaddr *bia;
-       struct mbuf *m;
-       struct sockaddr_in *sin;
-       int error, msg_len;
-       int cn_len, dn_len;
+       mbuf_t m;
+       struct sockaddr_in sin;
+       int error;
+       size_t msg_len, cn_len, dn_len;
        u_char *p;
        u_char *p;
-       long *lp;
+       int32_t *lp;
 
        /*
         * Get message buffer of sufficient size.
         */
        msg_len = sizeof(*call);
 
        /*
         * Get message buffer of sufficient size.
         */
        msg_len = sizeof(*call);
-       m = m_get_len(msg_len);
-       if (m == NULL)
-               return ENOBUFS;
+       error = mbuf_get_with_len(msg_len, &m);
+       if (error)
+               return error;
 
        /*
         * Build request message for PMAPPROC_CALLIT.
         */
 
        /*
         * Build request message for PMAPPROC_CALLIT.
         */
-       call = mtod(m, struct whoami_call *);
+       call = mbuf_data(m);
        call->call_prog = htonl(BOOTPARAM_PROG);
        call->call_vers = htonl(BOOTPARAM_VERS);
        call->call_proc = htonl(BOOTPARAM_WHOAMI);
        call->call_prog = htonl(BOOTPARAM_PROG);
        call->call_vers = htonl(BOOTPARAM_VERS);
        call->call_proc = htonl(BOOTPARAM_WHOAMI);
@@ -477,29 +492,28 @@ bp_whoami(bpsin, my_ip, gw_ip)
        /* RPC: portmap/callit */
        bpsin->sin_port = htons(PMAPPORT);
 
        /* RPC: portmap/callit */
        bpsin->sin_port = htons(PMAPPORT);
 
-       error = krpc_call(bpsin, PMAPPROG, PMAPVERS,
-                       PMAPPROC_CALLIT, &m, &sin);
+       error = krpc_call(bpsin, SOCK_DGRAM, PMAPPROG, PMAPVERS, PMAPPROC_CALLIT, &m, &sin);
        if (error)
                return error;
 
        /*
         * Parse result message.
         */
        if (error)
                return error;
 
        /*
         * Parse result message.
         */
-       msg_len = m->m_len;
-       lp = mtod(m, long *);
+       msg_len = mbuf_len(m);
+       lp = mbuf_data(m);
 
        /* bootparam server port (also grab from address). */
        if (msg_len < sizeof(*lp))
                goto bad;
        msg_len -= sizeof(*lp);
        bpsin->sin_port = htons((short)ntohl(*lp++));
 
        /* bootparam server port (also grab from address). */
        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;
+       bpsin->sin_addr.s_addr = sin.sin_addr.s_addr;
 
        /* length of encapsulated results */
        if (msg_len < (ntohl(*lp) + sizeof(*lp)))
                goto bad;
        msg_len = ntohl(*lp++);
 
        /* length of encapsulated results */
        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 < sizeof(*str))
 
        /* client name */
        if (msg_len < sizeof(*str))
@@ -549,10 +563,7 @@ bad:
        error = EBADRPC;
 
 out:
        error = EBADRPC;
 
 out:
-       if (sin)
-           FREE(sin, M_SONAME);
-
-       m_freem(m);
+       mbuf_freem(m);
        return(error);
 }
 
        return(error);
 }
 
@@ -567,13 +578,13 @@ out:
 static int
 bp_getfile(bpsin, key, md_sin, serv_name, pathname)
        struct sockaddr_in *bpsin;
 static int
 bp_getfile(bpsin, key, md_sin, serv_name, pathname)
        struct sockaddr_in *bpsin;
-       char *key;
+       const char *key;
        struct sockaddr_in *md_sin;
        char *serv_name;
        char *pathname;
 {
        struct rpc_string *str;
        struct sockaddr_in *md_sin;
        char *serv_name;
        char *pathname;
 {
        struct rpc_string *str;
-       struct mbuf *m;
+       mbuf_t m;
        struct bp_inaddr *bia;
        struct sockaddr_in *sin;
        u_char *p, *q;
        struct bp_inaddr *bia;
        struct sockaddr_in *sin;
        u_char *p, *q;
@@ -588,14 +599,14 @@ bp_getfile(bpsin, key, md_sin, serv_name, pathname)
        msg_len = 0;
        msg_len += RPC_STR_SIZE(cn_len);
        msg_len += RPC_STR_SIZE(key_len);
        msg_len = 0;
        msg_len += RPC_STR_SIZE(cn_len);
        msg_len += RPC_STR_SIZE(key_len);
-       m = m_get_len(msg_len);
-       if (m == NULL)
-               return ENOBUFS;
+       error = mbuf_get_with_len(msg_len, &m);
+       if (error)
+               return error;
 
        /*
         * Build request message.
         */
 
        /*
         * Build request message.
         */
-       p = mtod(m, u_char *);
+       p = mbuf_data(m);
        bzero(p, msg_len);
        /* client name (hostname) */
        str = (struct rpc_string *)p;
        bzero(p, msg_len);
        /* client name (hostname) */
        str = (struct rpc_string *)p;
@@ -608,7 +619,7 @@ bp_getfile(bpsin, key, md_sin, serv_name, pathname)
        bcopy(key, str->data, key_len);
 
        /* RPC: bootparam/getfile */
        bcopy(key, str->data, key_len);
 
        /* RPC: bootparam/getfile */
-       error = krpc_call(bpsin, BOOTPARAM_PROG, BOOTPARAM_VERS,
+       error = krpc_call(bpsin, SOCK_DGRAM, BOOTPARAM_PROG, BOOTPARAM_VERS,
                        BOOTPARAM_GETFILE, &m, NULL);
        if (error)
                return error;
                        BOOTPARAM_GETFILE, &m, NULL);
        if (error)
                return error;
@@ -616,17 +627,17 @@ bp_getfile(bpsin, key, md_sin, serv_name, pathname)
        /*
         * Parse result message.
         */
        /*
         * Parse result message.
         */
-       p = mtod(m, u_char *);
-       msg_len = m->m_len;
+       p = mbuf_data(m);
+       msg_len = mbuf_len(m);
 
        /* server name */
 
        /* server name */
-       if (msg_len < sizeof(*str))
+       if (msg_len < (int)sizeof(*str))
                goto bad;
        str = (struct rpc_string *)p;
        sn_len = ntohl(str->len);
        if (msg_len < sn_len)
                goto bad;
                goto bad;
        str = (struct rpc_string *)p;
        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';
                goto bad;
        bcopy(str->data, serv_name, sn_len);
        serv_name[sn_len] = '\0';
@@ -634,7 +645,7 @@ bp_getfile(bpsin, key, md_sin, serv_name, pathname)
        msg_len -= RPC_STR_SIZE(sn_len);
 
        /* server IP address (mountd) */
        msg_len -= RPC_STR_SIZE(sn_len);
 
        /* server IP address (mountd) */
-       if (msg_len < sizeof(*bia))
+       if (msg_len < (int)sizeof(*bia))
                goto bad;
        bia = (struct bp_inaddr *)p;
        if (bia->atype != htonl(1))
                goto bad;
        bia = (struct bp_inaddr *)p;
        if (bia->atype != htonl(1))
@@ -652,7 +663,7 @@ bp_getfile(bpsin, key, md_sin, serv_name, pathname)
        msg_len -= sizeof(*bia);
 
        /* server pathname */
        msg_len -= sizeof(*bia);
 
        /* server pathname */
-       if (msg_len < sizeof(*str))
+       if (msg_len < (int)sizeof(*str))
                goto bad;
        str = (struct rpc_string *)p;
        path_len = ntohl(str->len);
                goto bad;
        str = (struct rpc_string *)p;
        path_len = ntohl(str->len);
@@ -669,7 +680,7 @@ bad:
        error = EBADRPC;
 
 out:
        error = EBADRPC;
 
 out:
-       m_freem(m);
+       mbuf_freem(m);
        return(0);
 }
 
        return(0);
 }
 
@@ -680,41 +691,52 @@ out:
  * Also, sets sin->sin_port to the NFS service port.
  */
 static int
  * Also, sets sin->sin_port to the NFS service port.
  */
 static int
-md_mount(mdsin, path, v3, fhp, fhlenp)
+md_mount(mdsin, path, v3, sotype, fhp, fhlenp)
        struct sockaddr_in *mdsin;              /* mountd server address */
        char *path;
        int v3;
        struct sockaddr_in *mdsin;              /* mountd server address */
        char *path;
        int v3;
+       int sotype;
        u_char *fhp;
        u_char *fhp;
-       u_long *fhlenp;
+       u_int32_t *fhlenp;
 {
        /* The RPC structures */
        struct rpc_string *str;
        struct rdata {
 {
        /* 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;
        } *rdata;
-       struct mbuf *m;
+       mbuf_t m;
        int error, mlen, slen;
        int mntversion = v3 ? RPCMNT_VER3 : RPCMNT_VER1;
        int error, mlen, slen;
        int mntversion = v3 ? RPCMNT_VER3 : RPCMNT_VER1;
+       int proto = (sotype == SOCK_STREAM) ? IPPROTO_TCP : IPPROTO_UDP;
+       in_port_t mntport, nfsport;
 
        /* Get port number for MOUNTD. */
 
        /* Get port number for MOUNTD. */
-       error = krpc_portmap(mdsin, RPCPROG_MNT, mntversion,
-                                                &mdsin->sin_port);
-       if (error) return error;
+       error = krpc_portmap(mdsin, RPCPROG_MNT, mntversion, proto, &mntport);
+       if (error)
+               return error;
+
+       /* Get port number for NFS use. */
+       /* (If NFS/proto unavailable, don't bother with the mount call) */
+       error = krpc_portmap(mdsin, NFS_PROG, v3 ? NFS_VER3 : NFS_VER2, proto, &nfsport);
+       if (error)
+               return error;
+
+       /* Set port number for MOUNTD */
+       mdsin->sin_port = mntport;
 
        slen = strlen(path);
        mlen = RPC_STR_SIZE(slen);
 
 
        slen = strlen(path);
        mlen = RPC_STR_SIZE(slen);
 
-       m = m_get_len(mlen);
-       if (m == NULL)
-               return ENOBUFS;
-       str = mtod(m, struct rpc_string *);
+       error = mbuf_get_with_len(mlen, &m);
+       if (error)
+               return error;
+       str = mbuf_data(m);
        str->len = htonl(slen);
        bcopy(path, str->data, slen);
 
        /* Do RPC to mountd. */
        str->len = htonl(slen);
        bcopy(path, str->data, slen);
 
        /* Do RPC to mountd. */
-       error = krpc_call(mdsin, RPCPROG_MNT, mntversion,
-                       RPCMNT_MOUNT, &m, NULL);
+       error = krpc_call(mdsin, sotype, RPCPROG_MNT, mntversion, RPCMNT_MOUNT, &m, NULL);
        if (error)
                return error;   /* message already freed */
 
        if (error)
                return error;   /* message already freed */
 
@@ -723,41 +745,40 @@ md_mount(mdsin, path, v3, fhp, fhlenp)
         * + a v2 filehandle
         * + a v3 filehandle length + a v3 filehandle
         */
         * + a v2 filehandle
         * + a v3 filehandle length + a v3 filehandle
         */
-       mlen = m->m_len;
-       if (mlen < sizeof(u_long))
+       mlen = mbuf_len(m);
+       if (mlen < (int)sizeof(u_int32_t))
                goto bad;
                goto bad;
-       rdata = mtod(m, struct rdata *);
+       rdata = mbuf_data(m);
        error = ntohl(rdata->errno);
        if (error)
                goto out;
        if (v3) {
        error = ntohl(rdata->errno);
        if (error)
                goto out;
        if (v3) {
-               u_long fhlen;
+               u_int32_t fhlen;
                u_char *fh;
                u_char *fh;
-               if (mlen < sizeof(u_long)*2)
+               if (mlen < (int)sizeof(u_int32_t)*2)
                        goto bad;
                        goto bad;
-               fhlen = ntohl(*(u_long*)rdata->data);
-               fh = rdata->data + sizeof(u_long);
-               if (mlen < (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 {
                        goto bad;
                bcopy(fh, fhp, fhlen);
                *fhlenp = fhlen;
        } else {
-               if (mlen < (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;
        }
 
        /* Set port number for NFS use. */
                        goto bad;
                bcopy(rdata->data, fhp, NFSX_V2FH);
                *fhlenp = NFSX_V2FH;
        }
 
        /* Set port number for NFS use. */
-       error = krpc_portmap(mdsin, NFS_PROG, v3 ? NFS_VER3 : NFS_VER2,
-                                                &mdsin->sin_port);
+       mdsin->sin_port = nfsport;
        goto out;
 
 bad:
        error = EBADRPC;
 
 out:
        goto out;
 
 bad:
        error = EBADRPC;
 
 out:
-       m_freem(m);
+       mbuf_freem(m);
        return error;
 }
 
        return error;
 }