summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGene Cumm <gene.cumm@gmail.com>2012-06-01 21:40:46 -0400
committerGene Cumm <gene.cumm@gmail.com>2012-06-01 21:40:46 -0400
commit616162f3564a3cebc8e18c8033fee4e244db5271 (patch)
tree99762542e93bb90c038a9efc3c80ca30818fe6ef
parent3cf65ff842c9017195646e684a437d100316dfe9 (diff)
downloadsyslinux-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.c33
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);