From 7e688e2cec5f776a1eedc6348b30fe13d507c292 Mon Sep 17 00:00:00 2001 From: brooks Date: Fri, 12 Mar 2004 20:37:40 +0000 Subject: Allow kernel with the BOOTP option to boot when DHCP/BOOTP sets the root path to an absolute path without a host name. Previously, there was a nasty POLA violation where a system would PXE boot until you added the BOOTP option and then it would panic instead. Reviewed by: tegge, Dirk-Willem van Gulik (a previous version) Submitted by: tegge (getip function) --- sys/nfsclient/bootp_subr.c | 48 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/sys/nfsclient/bootp_subr.c b/sys/nfsclient/bootp_subr.c index c4d9eea..f21689d 100644 --- a/sys/nfsclient/bootp_subr.c +++ b/sys/nfsclient/bootp_subr.c @@ -216,8 +216,10 @@ SYSCTL_STRING(_kern, OID_AUTO, bootp_cookie, CTLFLAG_RD, /* 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 int getip(char **ptr, struct in_addr *ip); static char *substr(char *a, char *b); static void mountopts(struct nfs_args *args, char *p); static int xdr_opaque_decode(struct mbuf **ptr, u_char *buf, int len); @@ -1157,11 +1159,36 @@ bootpc_adjust_interface(struct bootpc_ifcontext *ifctx, } 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) { + + if (getip(&p, &addr->sin_addr) == 0) { + if (siaddr != NULL && *p == '/') + bcopy(siaddr, &addr->sin_addr, sizeof(struct in_addr)); + else + return 0; + } else { + if (*p != ':') + return 0; + p++; + } + + addr->sin_len = sizeof(struct sockaddr_in); + addr->sin_family = AF_INET; + + strlcpy(path, p, MNAMELEN); + return 1; +} + +static int +getip(char **ptr, struct in_addr *addr) +{ + char *p; unsigned int ip; int val; + p = *ptr; ip = 0; if (((val = getdec(&p)) < 0) || (val > 255)) return 0; @@ -1184,15 +1211,9 @@ setfs(struct sockaddr_in *addr, char *path, char *p) if (((val = getdec(&p)) < 0) || (val > 255)) return 0; ip |= val; - if (*p != ':') - 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); + addr->s_addr = htonl(ip); + *ptr = p; return 1; } @@ -1551,7 +1572,12 @@ bootpc_decode_reply(struct nfsv3_diskless *nd, struct bootpc_ifcontext *ifctx, 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; -- cgit v1.1