Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 10 Feb 2004 17:00:10 -0800
From:      Brooks Davis <brooks@one-eyed-alien.net>
To:        hackers@freebsd.org
Subject:   [PATCH] make BOOTP not panic working PXE configs
Message-ID:  <20040211010009.GA1211@Odin.AC.HMC.Edu>

next in thread | raw e-mail | index | archive | help

--/04w6evG8XlLl3ft
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

When using the PXE loader and a stock kernel you can specify the root
path as with "option root-path" with a path like
"/usr/diskless/5.2-CURRENT".  The server is then derived from the value
of next-server (the siaddr entry in the dhcp packet).  If you add
options BOOTP to your kernel this configuration causes a panic because
the kernel wants a root path like "10.1.0.1:/usr/diskless/5.2-CURRENT".
This has been annoying me for quite some time so today I took a look at
the problem.  The following patch fixes it.  I'd like to commit it soon,
any objections?

-- Brooks

Index: bootp_subr.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/cvs/src/sys/nfsclient/bootp_subr.c,v
retrieving revision 1.56
diff -u -p -r1.56 bootp_subr.c
--- bootp_subr.c	14 Nov 2003 20:54:08 -0000	1.56
+++ bootp_subr.c	11 Feb 2004 00:48:45 -0000
@@ -216,7 +216,8 @@ SYSCTL_STRING(_kern, OID_AUTO, bootp_coo
 /* mountd RPC */
 static int	md_mount(struct sockaddr_in *mdsin, char *path, u_char *fhp,
 		    int *fhsizep, struct nfs_args *args, struct thread *td);
-static int	setfs(struct sockaddr_in *addr, char *path, char *p);
+static int	setfs(struct sockaddr_in *addr, char *path, char *p,
+		    const struct in_addr *siaddr);
 static int	getdec(char **ptr);
 static char	*substr(char *a, char *b);
 static void	mountopts(struct nfs_args *args, char *p);
@@ -1157,42 +1158,49 @@ bootpc_adjust_interface(struct bootpc_if
 }
=20
 static int
-setfs(struct sockaddr_in *addr, char *path, char *p)
+setfs(struct sockaddr_in *addr, char *path, char *p,
+    const struct in_addr *siaddr)
 {
 	unsigned int ip;
 	int val;
=20
-	ip =3D 0;
-	if (((val =3D getdec(&p)) < 0) || (val > 255))
-		return 0;
-	ip =3D val << 24;
-	if (*p !=3D '.')
-		return 0;
-	p++;
-	if (((val =3D getdec(&p)) < 0) || (val > 255))
-		return 0;
-	ip |=3D (val << 16);
-	if (*p !=3D '.')
-		return 0;
-	p++;
-	if (((val =3D getdec(&p)) < 0) || (val > 255))
-		return 0;
-	ip |=3D (val << 8);
-	if (*p !=3D '.')
-		return 0;
-	p++;
-	if (((val =3D getdec(&p)) < 0) || (val > 255))
-		return 0;
-	ip |=3D val;
-	if (*p !=3D ':')
+	if (*p !=3D '/') {
+		ip =3D 0;
+		if (((val =3D getdec(&p)) < 0) || (val > 255))
+			return 0;
+		ip =3D val << 24;
+		if (*p !=3D '.')
+			return 0;
+		p++;
+		if (((val =3D getdec(&p)) < 0) || (val > 255))
+			return 0;
+		ip |=3D (val << 16);
+		if (*p !=3D '.')
+			return 0;
+		p++;
+		if (((val =3D getdec(&p)) < 0) || (val > 255))
+			return 0;
+		ip |=3D (val << 8);
+		if (*p !=3D '.')
+			return 0;
+		p++;
+		if (((val =3D getdec(&p)) < 0) || (val > 255))
+			return 0;
+		ip |=3D val;
+		if (*p !=3D ':')
+			return 0;
+		p++;
+
+		addr->sin_addr.s_addr =3D htonl(ip);
+	} else if (siaddr !=3D NULL)
+		bcopy(siaddr, &addr->sin_addr.s_addr, sizeof(struct in_addr));
+	else
 		return 0;
-	p++;
=20
-	addr->sin_addr.s_addr =3D htonl(ip);
 	addr->sin_len =3D sizeof(struct sockaddr_in);
 	addr->sin_family =3D AF_INET;
=20
-	strncpy(path, p, MNAMELEN - 1);
+	strlcpy(path, p, MNAMELEN);
 	return 1;
 }
=20
@@ -1551,7 +1559,12 @@ bootpc_decode_reply(struct nfsv3_diskles
 		if (gctx->setrootfs !=3D NULL) {
 			printf("rootfs %s (ignored) ", p);
 		} else 	if (setfs(&nd->root_saddr,
-				  nd->root_hostnam, p)) {
+				  nd->root_hostnam, p, &ifctx->reply.siaddr)) {
+			if (*p =3D=3D '/') {
+				printf("root_server ");
+				print_sin_addr(&nd->root_saddr);
+				printf(" ");
+			}
 			printf("rootfs %s ", p);
 			gctx->gotrootpath =3D 1;
 			ifctx->gotrootpath =3D 1;

--=20
Any statement of the form "X is the one, true Y" is FALSE.
PGP fingerprint 655D 519C 26A7 82E7 2529  9BF0 5D8E 8BE9 F238 1AD4

--/04w6evG8XlLl3ft
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)

iD8DBQFAKX6ZXY6L6fI4GtQRAnBIAKCvuwKfB4jwIDuFK0LSF0QANk0IKgCgyEH1
uyYh9nuI29ndqbmkCJ03UeU=
=y2eu
-----END PGP SIGNATURE-----

--/04w6evG8XlLl3ft--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040211010009.GA1211>