diff options
author | brooks <brooks@FreeBSD.org> | 2004-03-12 20:37:40 +0000 |
---|---|---|
committer | brooks <brooks@FreeBSD.org> | 2004-03-12 20:37:40 +0000 |
commit | 7e688e2cec5f776a1eedc6348b30fe13d507c292 (patch) | |
tree | 731e5005e3fce9e06f1da7c64c76130fcad48627 /sys | |
parent | 2cb0d83a6cc5446e8257008554a0c581ed8cfbd5 (diff) | |
download | FreeBSD-src-7e688e2cec5f776a1eedc6348b30fe13d507c292.zip FreeBSD-src-7e688e2cec5f776a1eedc6348b30fe13d507c292.tar.gz |
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 <dirkx at webweaving.org>
(a previous version)
Submitted by: tegge (getip function)
Diffstat (limited to 'sys')
-rw-r--r-- | sys/nfsclient/bootp_subr.c | 48 |
1 files 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; |