[PATCH] make BOOTP not panic working PXE configs

Brooks Davis brooks at one-eyed-alien.net
Tue Feb 10 17:00:22 PST 2004


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
===================================================================
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
 }
 
 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;
 
-	ip = 0;
-	if (((val = getdec(&p)) < 0) || (val > 255))
-		return 0;
-	ip = val << 24;
-	if (*p != '.')
-		return 0;
-	p++;
-	if (((val = getdec(&p)) < 0) || (val > 255))
-		return 0;
-	ip |= (val << 16);
-	if (*p != '.')
-		return 0;
-	p++;
-	if (((val = getdec(&p)) < 0) || (val > 255))
-		return 0;
-	ip |= (val << 8);
-	if (*p != '.')
-		return 0;
-	p++;
-	if (((val = getdec(&p)) < 0) || (val > 255))
-		return 0;
-	ip |= val;
-	if (*p != ':')
+	if (*p != '/') {
+		ip = 0;
+		if (((val = getdec(&p)) < 0) || (val > 255))
+			return 0;
+		ip = val << 24;
+		if (*p != '.')
+			return 0;
+		p++;
+		if (((val = getdec(&p)) < 0) || (val > 255))
+			return 0;
+		ip |= (val << 16);
+		if (*p != '.')
+			return 0;
+		p++;
+		if (((val = getdec(&p)) < 0) || (val > 255))
+			return 0;
+		ip |= (val << 8);
+		if (*p != '.')
+			return 0;
+		p++;
+		if (((val = getdec(&p)) < 0) || (val > 255))
+			return 0;
+		ip |= val;
+		if (*p != ':')
+			return 0;
+		p++;
+
+		addr->sin_addr.s_addr = htonl(ip);
+	} else if (siaddr != NULL)
+		bcopy(siaddr, &addr->sin_addr.s_addr, sizeof(struct in_addr));
+	else
 		return 0;
-	p++;
 
-	addr->sin_addr.s_addr = htonl(ip);
 	addr->sin_len = sizeof(struct sockaddr_in);
 	addr->sin_family = AF_INET;
 
-	strncpy(path, p, MNAMELEN - 1);
+	strlcpy(path, p, MNAMELEN);
 	return 1;
 }
 
@@ -1551,7 +1559,12 @@ bootpc_decode_reply(struct nfsv3_diskles
 		if (gctx->setrootfs != 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 == '/') {
+				printf("root_server ");
+				print_sin_addr(&nd->root_saddr);
+				printf(" ");
+			}
 			printf("rootfs %s ", p);
 			gctx->gotrootpath = 1;
 			ifctx->gotrootpath = 1;

-- 
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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-hackers/attachments/20040210/2b96c112/attachment.bin


More information about the freebsd-hackers mailing list