[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