summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrooks <brooks@FreeBSD.org>2004-03-12 20:37:40 +0000
committerbrooks <brooks@FreeBSD.org>2004-03-12 20:37:40 +0000
commit7e688e2cec5f776a1eedc6348b30fe13d507c292 (patch)
tree731e5005e3fce9e06f1da7c64c76130fcad48627
parent2cb0d83a6cc5446e8257008554a0c581ed8cfbd5 (diff)
downloadFreeBSD-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)
-rw-r--r--sys/nfsclient/bootp_subr.c48
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;
OpenPOWER on IntegriCloud