From 38cca967983447b7660f73192a81e23dd9de4fc4 Mon Sep 17 00:00:00 2001 From: gwr Date: Thu, 11 Aug 1994 22:25:32 +0000 Subject: [PATCH] Diskless boot will now bind the local socket to a reserved port to satisfy picky servers. Also fix some missing initializations. (Thanks to Chuck Cranor for PR#394 -- now fixed.) --- sys/nfs/krpc_subr.c | 32 ++++++++++++++++++++++++++++++-- sys/nfs/nfs_boot.c | 9 ++++++--- sys/nfs/nfs_vfsops.c | 3 ++- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/sys/nfs/krpc_subr.c b/sys/nfs/krpc_subr.c index ec3005cc1834..8750fa8e2164 100644 --- a/sys/nfs/krpc_subr.c +++ b/sys/nfs/krpc_subr.c @@ -1,4 +1,4 @@ -/* $NetBSD: krpc_subr.c,v 1.4 1994/06/30 10:45:03 pk Exp $ */ +/* $NetBSD: krpc_subr.c,v 1.5 1994/08/11 22:25:32 gwr Exp $ */ /* * Copyright (c) 1994 Gordon Ross, Adam Glass @@ -186,6 +186,7 @@ krpc_call(sa, prog, vers, func, data) struct uio auio; int error, rcvflg, timo, secs, len; static u_long xid = ~0xFF; + u_short tport; /* * Validate address family. @@ -215,6 +216,29 @@ krpc_call(sa, prog, vers, func, data) if ((error = sosetopt(so, SOL_SOCKET, SO_RCVTIMEO, m))) goto out; + /* + * Bind the local endpoint to a reserved port, + * because some NFS servers refuse requests from + * non-reserved (non-privileged) ports. + */ + m = m_getclr(M_WAIT, MT_SONAME); + sin = mtod(m, struct sockaddr_in *); + sin->sin_len = m->m_len = sizeof(*sin); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = INADDR_ANY; + tport = IPPORT_RESERVED; + do { + tport--; + sin->sin_port = htons(tport); + error = sobind(so, m); + } while (error == EADDRINUSE && + tport > IPPORT_RESERVED / 2); + m_freem(m); + if (error) { + printf("bind failed\n"); + goto out; + } + /* * Setup socket address for the server. */ @@ -332,7 +356,11 @@ krpc_call(sa, prog, vers, func, data) gotreply: /* - * Make result buffer contiguous. + * Pull as much as we can into first mbuf, to make + * result buffer contiguous. Note that if the entire + * resulte won't fit into one mbuf, you're out of luck. + * XXX - Should not rely on making the entire reply + * contiguous (fix callers instead). -gwr */ #ifdef DIAGNOSTIC if ((m->m_flags & M_PKTHDR) == 0) diff --git a/sys/nfs/nfs_boot.c b/sys/nfs/nfs_boot.c index 138f98aac663..e6983a043a75 100644 --- a/sys/nfs/nfs_boot.c +++ b/sys/nfs/nfs_boot.c @@ -1,4 +1,4 @@ -/* $NetBSD: nfs_boot.c,v 1.8 1994/07/19 02:23:27 gwr Exp $ */ +/* $NetBSD: nfs_boot.c,v 1.9 1994/08/11 22:25:35 gwr Exp $ */ /* * Copyright (c) 1994 Adam Glass, Gordon Ross @@ -160,6 +160,7 @@ nfs_boot_init(nd, procp) */ /* Set interface address. */ sin = (struct sockaddr_in *)&ireq.ifr_addr; + bzero((char*)sin, sizeof(*sin)); sin->sin_len = sizeof(*sin); sin->sin_family = AF_INET; sin->sin_addr.s_addr = my_ip.s_addr; @@ -173,6 +174,7 @@ nfs_boot_init(nd, procp) * Get client name and gateway address. * RPC: bootparam/whoami */ + bzero((char*)&bp_sin, sizeof(bp_sin)); bp_sin.sin_len = sizeof(bp_sin); bp_sin.sin_family = AF_INET; bp_sin.sin_addr.s_addr = srv_ip.s_addr; @@ -201,11 +203,11 @@ nfs_boot_init(nd, procp) if (gw_ip.s_addr) { struct sockaddr dst, gw, mask; /* Destination: (default) */ - bzero(&dst, sizeof(dst)); + bzero((char*)&dst, sizeof(dst)); dst.sa_len = sizeof(dst); dst.sa_family = AF_INET; /* Gateway: */ - bzero(&gw, sizeof(gw)); + bzero((char*)&gw, sizeof(gw)); sin = (struct sockaddr_in *)&gw; sin->sin_len = sizeof(gw); sin->sin_family = AF_INET; @@ -520,6 +522,7 @@ bp_getfile(bpsin, key, md_sin, serv_name, pathname) if (bia->atype != htonl(1)) goto bad; sin = md_sin; + bzero((char*)sin, sizeof(*sin)); sin->sin_len = sizeof(*sin); sin->sin_family = AF_INET; q = (u_char*) &sin->sin_addr; diff --git a/sys/nfs/nfs_vfsops.c b/sys/nfs/nfs_vfsops.c index bce70f593b44..5d6df07a9d9d 100644 --- a/sys/nfs/nfs_vfsops.c +++ b/sys/nfs/nfs_vfsops.c @@ -1,4 +1,4 @@ -/* $NetBSD: nfs_vfsops.c,v 1.27 1994/07/03 09:24:01 mycroft Exp $ */ +/* $NetBSD: nfs_vfsops.c,v 1.28 1994/08/11 22:25:38 gwr Exp $ */ /* * Copyright (c) 1989, 1993 @@ -303,6 +303,7 @@ nfs_mount_diskless(ndmntp, mntname, mntflag, vpp) args.sotype = SOCK_DGRAM; args.fh = (nfsv2fh_t *)ndmntp->ndm_fh; args.hostname = ndmntp->ndm_host; + args.flags = NFSMNT_RESVPORT; /* Get mbuf for server sockaddr. */ MGET(m, MT_SONAME, M_DONTWAIT);