diff options
author | Gene Cumm <gene.cumm@gmail.com> | 2012-06-01 21:40:46 -0400 |
---|---|---|
committer | Gene Cumm <gene.cumm@gmail.com> | 2012-06-01 21:40:46 -0400 |
commit | 616162f3564a3cebc8e18c8033fee4e244db5271 (patch) | |
tree | 99762542e93bb90c038a9efc3c80ca30818fe6ef | |
parent | 3cf65ff842c9017195646e684a437d100316dfe9 (diff) | |
download | syslinux-616162f3564a3cebc8e18c8033fee4e244db5271.tar.gz |
pxechn.c32: add -S to transform sname to siaddr
Signed-off-by: Gene Cumm <gene.cumm@gmail.com>
-rw-r--r-- | com32/modules/pxechn.c | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/com32/modules/pxechn.c b/com32/modules/pxechn.c index 301f311e..26376900 100644 --- a/com32/modules/pxechn.c +++ b/com32/modules/pxechn.c @@ -117,6 +117,7 @@ struct pxelinux_opt { uint32_t force; uint32_t wait; /* Additional decision to wait before boot */ int32_t wds; /* WDS option/level */ + in_addr_t sip; /* siaddr: Next Server IP Address */ struct dhcp_option p[PXECHN_NUM_PKT_AVAIL]; /* original _DHCP_DISCOVER, _DHCP_ACK, _CACHED_REPLY then modified packets */ char host[PXECHN_HOST_LEN]; @@ -463,6 +464,7 @@ void pxechn_init(struct pxelinux_opt *pxe) pxe->wait = 0; pxe->gip = 0; pxe->wds = 0; + pxe->sip = 0; pxe->host[0] = 0; pxe->host[((NUM_DHCP_OPTS) - 1)] = 0; for (int j = 0; j < PXECHN_NUM_PKT_TYPE; j++){ @@ -741,7 +743,7 @@ int pxechn_parse_args(int argc, char *argv[], struct pxelinux_opt *pxe, { int arg, optnum, rv = 0; char *p = NULL; - const char optstr[] = "c:f:g:o:p:t:uwW"; + const char optstr[] = "c:f:g:o:p:St:uwW"; struct dhcp_option iopt; if (pxe->p[5].data) @@ -775,6 +777,9 @@ int pxechn_parse_args(int argc, char *argv[], struct pxelinux_opt *pxe, case 'p': /* prefix */ pxechn_setopt_str(&(opts[210]), optarg); break; + case 'S': /* sip from sName */ + pxe->sip = 1; + break; case 't': /* timeout */ optnum = strtoul(optarg, &p, 0); if (p != optarg) { @@ -819,6 +824,7 @@ int pxechn_args(int argc, char *argv[], struct pxelinux_opt *pxe) pxe_bootp_t *bootp0, *bootp1; int ret = 0; struct dhcp_option *opts; + char *str; opts = pxe->opts[2]; /* Start filling packet #1 */ @@ -836,7 +842,30 @@ int pxechn_args(int argc, char *argv[], struct pxelinux_opt *pxe) ret = pxechn_parse_args(argc, argv, pxe, opts); if (ret) return ret; - bootp1->sip = pxe->fip; + if (pxe->sip > 0xFFFFFF) { /* a real IPv4 address */ + bootp1->sip = pxe->sip; + } else if ((pxe->sip == 1) + && (opts[66].len > 0)){ + /* unterminated? */ + if (strnlen(opts[66].data, opts[66].len) == (size_t)opts[66].len) { + str = malloc(opts[66].len + 1); + if (str) { + memcpy(str, opts[66].data, opts[66].len); + str[opts[66].len] = 0; + } + } else { + str = opts[66].data; + } + if (str) { + bootp1->sip = pxe_dns(str); + if (str != opts[66].data) + free(str); + } else { + bootp1->sip = pxe->fip; + } + } else { + bootp1->sip = pxe->fip; + } bootp1->gip = pxe->gip; ret = dhcp_pack_packet(bootp1, (size_t *)&(pxe->p[5].len), opts); |