Пример #1
0
int
net_mountroot(void)
{

#ifdef DEBUG
	printf("net_mountroot\n");
#endif

	/*
	 * Get info for NFS boot: our IP address, our hostname,
	 * server IP address, and our root path on the server.
	 * There are two ways to do this:  The old, Sun way,
	 * and the more modern, BOOTP way. (RFC951, RFC1048)
	 */

#ifdef	SUN_BOOTPARAMS
	/* Get boot info using RARP and Sun bootparams. */

	/* Get our IP address.  (rarp.c) */
	if (rarp_getipaddress(netdev_sock) == -1)
		return errno;

	printf("boot: client IP address: %s\n", inet_ntoa(myip));

	/* Get our hostname, server IP address. */
	if (bp_whoami(netdev_sock))
		return (errno);

	printf("boot: client name: %s\n", hostname);

	/* Get the root pathname. */
	if (bp_getfile(netdev_sock, "root", &rootip, rootpath))
		return (errno);

#else

	/* Get boot info using BOOTP way. (RFC951, RFC1048) */
	bootp(netdev_sock);

	printf("Using IP address: %s\n", inet_ntoa(myip));

	printf("myip: %s (%s)", hostname, inet_ntoa(myip));
	if (gateip)
		printf(", gateip: %s", inet_ntoa(gateip));
	if (netmask)
		printf(", netmask: %s", intoa(netmask));
	printf("\n");

#endif

	printf("root addr=%s path=%s\n", inet_ntoa(rootip), rootpath);

	/* Get the NFS file handle (mount). */
	if (nfs_mount(netdev_sock, rootip, rootpath) != 0)
		return (errno);
	return 0;
}
Пример #2
0
int
net_mountroot_bootparams(void)
{
	/* Get our IP address.  (rarp.c) */
	if (rarp_getipaddress(netdev_sock) == -1)
		return (errno);

	printf("Using BOOTPARAMS protocol: ");
	printf("ip address: %s", inet_ntoa(myip));

	/* Get our hostname, server IP address. */
	if (bp_whoami(netdev_sock))
		return (errno);

	printf(", hostname: %s\n", hostname);

	/* Get the root pathname. */
	if (bp_getfile(netdev_sock, "root", &rootip, rootpath))
		return (errno);

	return (0);
}
Пример #3
0
static int
net_getparams(int sock)
{
	char buf[MAXHOSTNAMELEN];
	n_long rootaddr, smask;

#ifdef	SUPPORT_BOOTP
	/*
	 * Try to get boot info using BOOTP.  If we succeed, then
	 * the server IP address, gateway, and root path will all
	 * be initialized.  If any remain uninitialized, we will
	 * use RARP and RPC/bootparam (the Sun way) to get them.
	 */
	if (try_bootp)
		bootp(sock, BOOTP_NONE);
	if (myip.s_addr != 0)
		goto exit;
#ifdef	NETIF_DEBUG
	if (debug)
		printf("net_open: BOOTP failed, trying RARP/RPC...\n");
#endif
#endif

	/*
	 * Use RARP to get our IP address.  This also sets our
	 * netmask to the "natural" default for our address.
	 */
	if (rarp_getipaddress(sock)) {
		printf("net_open: RARP failed\n");
		return (EIO);
	}
	printf("net_open: client addr: %s\n", inet_ntoa(myip));

	/* Get our hostname, server IP address, gateway. */
	if (bp_whoami(sock)) {
		printf("net_open: bootparam/whoami RPC failed\n");
		return (EIO);
	}
#ifdef	NETIF_DEBUG
	if (debug)
		printf("net_open: client name: %s\n", hostname);
#endif

	/*
	 * Ignore the gateway from whoami (unreliable).
	 * Use the "gateway" parameter instead.
	 */
	smask = 0;
	gateip.s_addr = 0;
	if (bp_getfile(sock, "gateway", &gateip, buf) == 0) {
		/* Got it!  Parse the netmask. */
		smask = ip_convertaddr(buf);
	}
	if (smask) {
		netmask = smask;
#ifdef	NETIF_DEBUG
		if (debug)
			printf("net_open: subnet mask: %s\n", intoa(netmask));
#endif
	}
#ifdef	NETIF_DEBUG
	if (gateip.s_addr && debug)
		printf("net_open: net gateway: %s\n", inet_ntoa(gateip));
#endif

	/* Get the root server and pathname. */
	if (bp_getfile(sock, "root", &rootip, rootpath)) {
		printf("net_open: bootparam/getfile RPC failed\n");
		return (EIO);
	}
exit:
	if ((rootaddr = net_parse_rootpath()) != INADDR_NONE)
		rootip.s_addr = rootaddr;

#ifdef	NETIF_DEBUG
	if (debug) {
		printf("net_open: server addr: %s\n", inet_ntoa(rootip));
		printf("net_open: server path: %s\n", rootpath);
	}
#endif

	return (0);
}
Пример #4
0
int
netmountroot(struct open_file *f, char *devname)
{
	int error;
	struct iodesc *d;

#ifdef DEBUG
	printf("netmountroot: %s\n", devname);
#endif

	if (netio_ask) {
 get_my_ip:
		printf("My IP address? ");
		bzero(input_line, sizeof(input_line));
		gets(input_line);
		if ((myip.s_addr = inet_addr(input_line)) ==
		    htonl(INADDR_NONE)) {
			printf("invalid IP address: %s\n", input_line);
			goto get_my_ip;
		}

 get_my_netmask:
		printf("My netmask? ");
		bzero(input_line, sizeof(input_line));
		gets(input_line);
		if ((netmask = inet_addr(input_line)) ==
		    htonl(INADDR_NONE)) {
			printf("invalid netmask: %s\n", input_line);
			goto get_my_netmask;
		}

 get_my_gateway:
		printf("My gateway? ");
		bzero(input_line, sizeof(input_line));
		gets(input_line);
		if ((gateip.s_addr = inet_addr(input_line)) ==
		    htonl(INADDR_NONE)) {
			printf("invalid IP address: %s\n", input_line);
			goto get_my_gateway;
		}

 get_server_ip:
		printf("Server IP address? ");
		bzero(input_line, sizeof(input_line));
		gets(input_line);
		if ((rootip.s_addr = inet_addr(input_line)) ==
		    htonl(INADDR_NONE)) {
			printf("invalid IP address: %s\n", input_line);
			goto get_server_ip;
		}

 get_server_path:
		printf("Server path? ");
		bzero(rootpath, sizeof(rootpath));
		gets(rootpath);
		if (rootpath[0] == '\0' || rootpath[0] == '\n')
			goto get_server_path;

		if ((d = socktodesc(netdev_sock)) == NULL)
			return (EMFILE);

		d->myip = myip;

		goto do_nfs_mount;
	}

	/*
	 * Get info for NFS boot: our IP address, our hostname,
	 * server IP address, and our root path on the server.
	 * There are two ways to do this:  The old, Sun way,
	 * and the more modern, BOOTP way. (RFC951, RFC1048)
	 */

#ifdef	SUN_BOOTPARAMS
	/* Get boot info using RARP and Sun bootparams. */

	/* Get our IP address.  (rarp.c) */
	if (rarp_getipaddress(netdev_sock) == -1)
		return (errno);

	printf("boot: client IP address: %s\n", inet_ntoa(myip));

	/* Get our hostname, server IP address. */
	if (bp_whoami(netdev_sock))
		return (errno);

	printf("boot: client name: %s\n", hostname);

	/* Get the root pathname. */
	if (bp_getfile(netdev_sock, "root", &rootip, rootpath))
		return (errno);

#else

	/* Get boot info using BOOTP way. (RFC951, RFC1048) */
	bootp(netdev_sock);

	printf("Using IP address: %s\n", inet_ntoa(myip));

	printf("myip: %s (%s)", hostname, inet_ntoa(myip));
	if (gateip)
		printf(", gateip: %s", inet_ntoa(gateip));
	if (mask)
		printf(", mask: %s", intoa(netmask));
	printf("\n");

#endif /* SUN_BOOTPARAMS */

	printf("root addr=%s path=%s\n", inet_ntoa(rootip), rootpath);

 do_nfs_mount:
	/* Get the NFS file handle (mount). */
	error = nfs_mount(netdev_sock, rootip, rootpath);

	return (error);
}
Пример #5
0
/*
 * Get client name, gateway address, then
 * get root and swap server:pathname info.
 * RPCs: bootparam/whoami, bootparam/getfile
 *
 * Use the old broadcast address for the WHOAMI
 * call because we do not yet know our netmask.
 * The server address returned by the WHOAMI call
 * is used for all subsequent bootparam RPCs.
 */
int
nfs_bootparam(struct nfs_diskless *nd, struct lwp *lwp, int *flags)
{
	struct ifnet *ifp = nd->nd_ifp;
	struct in_addr my_ip, arps_ip, gw_ip;
	struct sockaddr_in bp_sin;
	struct sockaddr_in *sin;
#ifndef NFS_BOOTPARAM_NOGATEWAY
	struct nfs_dlmount *gw_ndm = 0;
	char *p;
	u_int32_t mask;
#endif
	int error;

	/*
	 * Bring up the interface. (just set the "up" flag)
	 */
	error = nfs_boot_ifupdown(ifp, lwp, 1);
	if (error) {
		printf("nfs_boot: SIFFLAGS, error=%d\n", error);
		return (error);
	}

	error = EADDRNOTAVAIL;
#if NARP > 0
	if (ifp->if_type == IFT_ETHER || ifp->if_type == IFT_FDDI) {
		/*
		 * Do RARP for the interface address.
		 */
		error = revarpwhoarewe(ifp, &arps_ip, &my_ip);
	}
#endif
	if (error) {
		printf("revarp failed, error=%d\n", error);
		goto out;
	}

	if (!(*flags & NFS_BOOT_HAS_MYIP)) {
		nd->nd_myip.s_addr = my_ip.s_addr;
		printf("nfs_boot: client_addr=%s", inet_ntoa(my_ip));
		printf(" (RARP from %s)\n", inet_ntoa(arps_ip));
		*flags |= NFS_BOOT_HAS_MYIP;
	}

	/*
	 * Do enough of ifconfig(8) so that the chosen interface
	 * can talk to the servers.  (just set the address)
	 */
	error = nfs_boot_setaddress(ifp, lwp, my_ip.s_addr,
				    INADDR_ANY, INADDR_ANY);
	if (error) {
		printf("nfs_boot: set ifaddr, error=%d\n", error);
		goto out;
	}

	/*
	 * Get client name and gateway address.
	 * RPC: bootparam/whoami
	 * Use the old broadcast address for the WHOAMI
	 * call because we do not yet know our netmask.
	 * The server address returned by the WHOAMI call
	 * is used for all subsequent booptaram RPCs.
	 */
	sin = &bp_sin;
	memset((void *)sin, 0, sizeof(*sin));
	sin->sin_len = sizeof(*sin);
	sin->sin_family = AF_INET;
	sin->sin_addr.s_addr = INADDR_BROADCAST;

	/* Do the RPC/bootparam/whoami. */
	error = bp_whoami(sin, &my_ip, &gw_ip, lwp);
	if (error) {
		printf("nfs_boot: bootparam whoami, error=%d\n", error);
		goto delout;
	}
	*flags |= NFS_BOOT_HAS_SERVADDR | NFS_BOOT_HAS_SERVER;
	printf("nfs_boot: server_addr=%s\n", inet_ntoa(sin->sin_addr));
	printf("nfs_boot: hostname=%s\n", hostname);

	/*
	 * Now fetch the server:pathname strings and server IP
	 * for root and swap.  Missing swap is not fatal.
	 */
	error = bp_getfile(sin, "root", &nd->nd_root, lwp);
	if (error) {
		printf("nfs_boot: bootparam get root: %d\n", error);
		goto delout;
	}
	*flags |= NFS_BOOT_HAS_ROOTPATH;

#ifndef NFS_BOOTPARAM_NOGATEWAY
	gw_ndm = kmem_alloc(sizeof(*gw_ndm), KM_SLEEP);
	memset((void *)gw_ndm, 0, sizeof(*gw_ndm));
	error = bp_getfile(sin, "gateway", gw_ndm, lwp);
	if (error) {
		/* No gateway supplied. No error, but try fallback. */
		error = 0;
		goto nogwrepl;
	}
	sin = (struct sockaddr_in *) &gw_ndm->ndm_saddr;
	if (sin->sin_addr.s_addr == 0)
		goto out;	/* no gateway */

	/* OK, we have a gateway! */
	printf("nfs_boot: gateway=%s\n", inet_ntoa(sin->sin_addr));
	/* Just save it.  Caller adds the route. */
	nd->nd_gwip = sin->sin_addr;
	*flags |= NFS_BOOT_HAS_GWIP;

	/* Look for a mask string after the colon. */
	p = strchr(gw_ndm->ndm_host, ':');
	if (p == 0)
		goto out;	/* no netmask */
	/* have pathname */
	p++;	/* skip ':' */
	mask = inet_addr(p);	/* libkern */
	if (mask == 0)
		goto out;	/* no netmask */

	/* Have a netmask too!  Save it; update the I/F. */
	nd->nd_mask.s_addr = mask;
	*flags |= NFS_BOOT_HAS_MASK;
	printf("nfs_boot: my_mask=%s\n", inet_ntoa(nd->nd_mask));
	(void)  nfs_boot_deladdress(ifp, lwp, my_ip.s_addr);
	error = nfs_boot_setaddress(ifp, lwp, my_ip.s_addr,
				    mask, INADDR_ANY);
	if (error) {
		printf("nfs_boot: set ifmask, error=%d\n", error);
		goto out;
	}
	goto gwok;
nogwrepl:
#endif
#ifdef NFS_BOOT_GATEWAY
	/*
	 * Note: we normally ignore the gateway address returned
	 * by the "bootparam/whoami" RPC above, because many old
	 * bootparam servers supply a bogus gateway value.
	 *
	 * These deficiencies in the bootparam RPC interface are
	 * circumvented by using the bootparam/getfile RPC.  The
	 * parameter "gateway" is requested, and if its returned,
	 * we use the "server" part of the reply as the gateway,
	 * and use the "pathname" part of the reply as the mask.
	 * (The mask comes to us as a string.)
	 */
	if (gw_ip.s_addr) {
		/* Our caller will add the route. */
		nd->nd_gwip = gw_ip;
		*flags |= NFS_BOOT_HAS_GWIP;
	}
#endif

delout:
	if (error)
		(void) nfs_boot_deladdress(ifp, lwp, my_ip.s_addr);
out:
	if (error) {
		(void) nfs_boot_ifupdown(ifp, lwp, 0);
		nfs_boot_flushrt(ifp);
	}
#ifndef NFS_BOOTPARAM_NOGATEWAY
gwok:
	if (gw_ndm)
		kmem_free(gw_ndm, sizeof(*gw_ndm));
#endif
	if ((*flags & NFS_BOOT_ALLINFO) != NFS_BOOT_ALLINFO)
		return error ? error : EADDRNOTAVAIL;

	return (error);
}
Пример #6
0
static int
net_getparams(int sock)
{
    char buf[MAXHOSTNAMELEN];
    char temp[FNAME_SIZE];
    struct iodesc *d;
    int i;
    n_long smask;

#ifdef	SUPPORT_BOOTP
    /*
     * Try to get boot info using BOOTP.  If we succeed, then
     * the server IP address, gateway, and root path will all
     * be initialized.  If any remain uninitialized, we will
     * use RARP and RPC/bootparam (the Sun way) to get them.
     */
    if (try_bootp)
	bootp(sock, BOOTP_NONE);
    if (myip.s_addr != 0)
	goto exit;
    if (debug)
	printf("net_open: BOOTP failed, trying RARP/RPC...\n");
#endif

    /*
     * Use RARP to get our IP address.  This also sets our
     * netmask to the "natural" default for our address.
     */
    if (rarp_getipaddress(sock)) {
	printf("net_open: RARP failed\n");
	return (EIO);
    }
    printf("net_open: client addr: %s\n", inet_ntoa(myip));

    /* Get our hostname, server IP address, gateway. */
    if (bp_whoami(sock)) {
	printf("net_open: bootparam/whoami RPC failed\n");
	return (EIO);
    }
    printf("net_open: client name: %s\n", hostname);

    /*
     * Ignore the gateway from whoami (unreliable).
     * Use the "gateway" parameter instead.
     */
    smask = 0;
    gateip.s_addr = 0;
    if (bp_getfile(sock, "gateway", &gateip, buf) == 0) {
	/* Got it!  Parse the netmask. */
	smask = ip_convertaddr(buf);
    }
    if (smask) {
	netmask = smask;
	printf("net_open: subnet mask: %s\n", intoa(netmask));
    }
    if (gateip.s_addr)
	printf("net_open: net gateway: %s\n", inet_ntoa(gateip));

    /* Get the root server and pathname. */
    if (bp_getfile(sock, "root", &rootip, rootpath)) {
	printf("net_open: bootparam/getfile RPC failed\n");
	return (EIO);
    }
 exit:
    /*  
     * If present, strip the server's address off of the rootpath
     * before passing it along.  This allows us to be compatible with
     * the kernel's diskless (BOOTP_NFSROOT) booting conventions
     */
    for (i = 0; i < FNAME_SIZE && rootpath[i] != '\0'; i++)
	    if (rootpath[i] == ':')
		    break;
    if (i && i != FNAME_SIZE && rootpath[i] == ':') {
	    rootpath[i++] = '\0';
	    if (inet_addr(&rootpath[0]) != INADDR_NONE)
		    rootip.s_addr = inet_addr(&rootpath[0]);
	    memcpy(&temp[0], &rootpath[i], strlen(&rootpath[i])+1);
	    memcpy(&rootpath[0], &temp[0], strlen(&rootpath[i])+1);	    
    }
    printf("net_open: server addr: %s\n", inet_ntoa(rootip));
    printf("net_open: server path: %s\n", rootpath);	    

    d = socktodesc(sock);
    snprintf(temp, sizeof(temp), "%6D", d->myea, ":");
    setenv("boot.netif.ip", inet_ntoa(myip), 1);
    setenv("boot.netif.netmask", intoa(netmask), 1);
    setenv("boot.netif.gateway", inet_ntoa(gateip), 1);
    setenv("boot.netif.hwaddr", temp, 1);
    setenv("boot.nfsroot.server", inet_ntoa(rootip), 1);
    setenv("boot.nfsroot.path", rootpath, 1);

    return (0);
}
Пример #7
0
int
net_devinit(struct open_file *f, struct netif_driver *drv, u_char *eaddr) {
	static struct netif best_if;
	struct iodesc *s;
	int r;

	if (inited)
		return 0;
	/* find a free socket */
	s = &desc;

	memset(s, 0, sizeof(*s));
	best_if.nif_driver = drv;
	s->io_netif = &best_if;
	memcpy(s->myea, eaddr, 6);

	/*
	 * Get info for NFS boot: our IP address, our hostname,
	 * server IP address, and our root path on the server.
	 * There are two ways to do this:  The old, Sun way,
	 * and the more modern, BOOTP way. (RFC951, RFC1048)
	 */

#ifdef SUPPORT_BOOTP

	/* Get boot info using BOOTP way. (RFC951, RFC1048) */
	printf("Trying BOOTP\n");
	bootp(0);

	if (myip.s_addr) {
		printf("Using IP address: %s\n", inet_ntoa(myip));

		printf("myip: %s (%s)\n", hostname, inet_ntoa(myip));
	} else

#endif /* SUPPORT_BOOTP */
	{
#ifdef	SUPPORT_BOOTPARAMS
		/* Get boot info using RARP and Sun bootparams. */

		printf("Trying BOOTPARAMS\n");
		/* Get our IP address.	(rarp.c) */
		if (rarp_getipaddress(0) == -1)
			return (errno);

		printf("boot: client IP address: %s\n", inet_ntoa(myip));

		/* Get our hostname, server IP address. */
		if (bp_whoami(0))
			return (errno);

		printf("boot: client name: %s\n", hostname);

		/* Get the root pathname. */
		if (bp_getfile(0, "root", &rootip, rootpath))
			return (errno);
#endif
	}
	printf("root addr=%s path=%s\n", inet_ntoa(rootip), rootpath);
	f->f_devdata = s;

	/* Get the NFS file handle (mount). */
	r = nfs_mount(0, rootip, rootpath);
	if (r)
		return r;

	inited = 1;
	return 0;
}
Пример #8
0
/*
 * Called by devopen after it sets f->f_dev to our devsw entry.
 * This opens the low-level device and sets f->f_devdata.
 */
int
net_open(struct open_file *f, ...)
{
	int error = 0;

#ifdef NET_DEBUG
	if (netdev_sock != -1)
	    panic("net_open");
#endif

	/* Find network interface. */
	if ((netdev_sock = netif_open()) < 0)
		return (ENXIO);

#ifdef SUPPORT_BOOTP
	printf("configure network...trying bootp\n");
	/* Get boot info using BOOTP way. (RFC951, RFC1048) */
	bootp(netdev_sock);
#endif

	if (myip.s_addr != INADDR_ANY) {	/* got bootp reply or
							 * manually set */

#ifdef TFTP_HACK
	    int             num, i;
	    /* XXX (some) tftp servers don't like leading "/" */
	    for (num = 0; bootfile[num] == '/'; num++);
	    for (i = 0; (bootfile[i] = bootfile[i + num]) != 0; i++);
#endif

	    printf("boot: client IP address: %s\n",
		   inet_ntoa(myip));
	    printf("boot: client name: %s\n", hostname);
	} else {

#ifdef SUPPORT_RARP
	    /*
	     * no answer, Get boot info using RARP and Sun
	     * bootparams.
	     */
	    printf("configure network...trying rarp\n");

	    /* Get our IP address.  (rarp.c) */
	    if (rarp_getipaddress(netdev_sock)) {
		error = EIO;
		goto bad;
	    }
	    printf("boot: client IP address: %s\n",
		   inet_ntoa(myip));

#ifdef SUPPORT_BOOTPARAM
	    /* Get our hostname, server IP address. */
	    if (!bp_whoami(netdev_sock)) {
		printf("boot: client name: %s\n", hostname);

		/* Get the root pathname. */
		bp_getfile(netdev_sock, "root", &rootip,
			   rootpath);
	    }
#else
	    /*
	     * else fallback: use rarp server address
	     */
#endif

#else				/* no SUPPORT_RARP */
	    error = EIO;
	    goto bad;
#endif

	}
	printf("boot: server: %s, rootpath: %s, bootfile: %s\n",
	       inet_ntoa(rootip), rootpath, bootfile);

	f->f_devdata = &netdev_sock;
	return (error);

bad:
	printf("net_open failed\n");
	netif_close(netdev_sock);
	return (error);
}
Пример #9
0
/*
 * Called with an empty nfs_diskless struct to be filled in.
 */
int
nfs_boot_init(struct nfs_diskless *nd)
{
	struct sockaddr_in 	bp_sin;
	boolean_t		do_bpwhoami = TRUE;
	boolean_t		do_bpgetfile = TRUE;
	int 			error = 0;
	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;
	    goto failed;
	}

	/* 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;
	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;
	    do_bpwhoami = FALSE;
	}
	nd->nd_private.ndm_saddr.sin_addr.s_addr = 0;

	if (do_bpwhoami) {
		struct in_addr router;
		/*
		 * Get client name and gateway address.
		 * RPC: bootparam/whoami
		 * Use the old broadcast address for the WHOAMI
		 * call because we do not yet know our netmask.
		 * The server address returned by the WHOAMI call
		 * is used for all subsequent booptaram RPCs.
		 */
		bzero((caddr_t)&bp_sin, sizeof(bp_sin));
		bp_sin.sin_len = sizeof(bp_sin);
		bp_sin.sin_family = AF_INET;
		bp_sin.sin_addr.s_addr = INADDR_BROADCAST;
		hostnamelen = MAXHOSTNAMELEN;
		router.s_addr = 0;
		error = bp_whoami(&bp_sin, &my_ip, &router);
		if (error) {
			printf("nfs_boot: bootparam whoami, error=%d", error);
			goto failed;
		}
		printf("nfs_boot: BOOTPARAMS server " IP_FORMAT "\n", 
		       IP_LIST(&bp_sin.sin_addr));
		printf("nfs_boot: hostname %s\n", hostname);
	}
	if (do_bpgetfile) {
		error = bp_getfile(&bp_sin, "root", &nd->nd_root.ndm_saddr,
				   nd->nd_root.ndm_host, nd->nd_root.ndm_path);
		if (error) {
			printf("nfs_boot: bootparam get root: %d\n", error);
			goto failed;
		}
	}

#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,
				   nd->nd_private.ndm_path);
		if (!error) {
			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)
			    && (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;
			}
			FREE_ZONE(check_path, MAXPATHLEN, M_NAMEI);
		}
		else { 
			/* private key not defined, don't mount */
			nd->nd_private.ndm_saddr.sin_addr.s_addr = 0;
		}
	}
	else {