summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--com32/include/syslinux/config.h9
-rw-r--r--core/comboot.inc4
-rw-r--r--core/fs/pxe/dhcp_option.c12
-rw-r--r--core/fs/pxe/dnsresolv.c5
-rw-r--r--core/fs/pxe/idle.c2
-rw-r--r--core/fs/pxe/pxe.c42
-rw-r--r--core/fs/pxe/pxe.h29
-rw-r--r--core/pxelinux.asm14
-rw-r--r--doc/comboot.txt8
9 files changed, 82 insertions, 43 deletions
diff --git a/com32/include/syslinux/config.h b/com32/include/syslinux/config.h
index 868b0f10..60d8d231 100644
--- a/com32/include/syslinux/config.h
+++ b/com32/include/syslinux/config.h
@@ -54,6 +54,14 @@ struct syslinux_version {
const char *copyright_string;
};
+struct syslinux_ipinfo {
+ uint32_t ipver;
+ uint32_t myip;
+ uint32_t netmask;
+ uint32_t gateway;
+ uint32_t serverip;
+};
+
extern __nocommon struct syslinux_version __syslinux_version;
static inline const struct syslinux_version *syslinux_version(void)
{
@@ -116,6 +124,7 @@ union syslinux_derivative_info {
uint32_t _eflags;
const void *pxenvptr;
const void *stack;
+ const struct syslinux_ipinfo *ipinfo;
} pxe; /* pxelinux */
struct {
uint16_t _gs, _fs, _es, _ds;
diff --git a/core/comboot.inc b/core/comboot.inc
index 45b770f3..0c9956a0 100644
--- a/core/comboot.inc
+++ b/core/comboot.inc
@@ -580,8 +580,10 @@ comapi_derinfo:
mov P_SI,ax
mov ax,[InitStack+2]
mov P_FS,ax
- mov eax,[MyIP]
+ mov eax,[IPInfo.MyIP]
mov P_ECX,eax
+ mov P_GS,0
+ mov P_DI,IPInfo
%else
; Physical medium...
diff --git a/core/fs/pxe/dhcp_option.c b/core/fs/pxe/dhcp_option.c
index e18b605d..39b51666 100644
--- a/core/fs/pxe/dhcp_option.c
+++ b/core/fs/pxe/dhcp_option.c
@@ -16,14 +16,14 @@ static void subnet_mask(void *data, int opt_len)
{
if (opt_len != 4)
return;
- net_mask = *(uint32_t *)data;
+ IPInfo.netmask = *(uint32_t *)data;
}
static void router(void *data, int opt_len)
{
if (opt_len != 4)
return;
- gate_way = *(uint32_t *)data;
+ IPInfo.gateway = *(uint32_t *)data;
}
static void dns_servers(void *data, int opt_len)
@@ -83,12 +83,12 @@ static void server(void *data, int opt_len)
if (opt_len != 4)
return;
- if (server_ip)
+ if (IPInfo.serverip)
return;
ip = *(uint32_t *)data;
if (ip_ok(ip))
- server_ip = ip;
+ IPInfo.serverip = ip;
}
static void client_identifier(void *data, int opt_len)
@@ -246,10 +246,10 @@ void parse_dhcp(int pkt_len)
over_load = 0;
if (ip_ok(dhcp->yip))
- MyIP = dhcp->yip;
+ IPInfo.myip = dhcp->yip;
if (ip_ok(dhcp->sip))
- server_ip = dhcp->sip;
+ IPInfo.serverip = dhcp->sip;
opt_len = (char *)dhcp + pkt_len - (char *)&dhcp->options;
if (opt_len && (dhcp->option_magic == BOOTP_OPTION_MAGIC))
diff --git a/core/fs/pxe/dnsresolv.c b/core/fs/pxe/dnsresolv.c
index df7f33c1..ecee7854 100644
--- a/core/fs/pxe/dnsresolv.c
+++ b/core/fs/pxe/dnsresolv.c
@@ -229,7 +229,7 @@ uint32_t dns_resolv(const char *name)
continue; /* just move on before runing the time out */
udp_write.status = 0;
udp_write.ip = srv;
- udp_write.gw = ((srv ^ MyIP) & net_mask) ? gate_way : 0;
+ udp_write.gw = gateway(srv);
udp_write.src_port = local_port;
udp_write.dst_port = DNS_PORT;
udp_write.buffer_size = p - DNSSendBuf;
@@ -242,7 +242,7 @@ uint32_t dns_resolv(const char *name)
while (1) {
udp_read.status = 0;
udp_read.src_ip = srv;
- udp_read.dest_ip = MyIP;
+ udp_read.dest_ip = IPInfo.myip;
udp_read.s_port = DNS_PORT;
udp_read.d_port = local_port;
udp_read.buffer_size = DNS_MAX_PACKET;
@@ -349,4 +349,5 @@ void pxe_dns_resolv(com32sys_t *regs)
const char *name = MK_PTR(regs->ds, regs->esi.w[0]);
regs->eax.l = dns_resolv(name);
+ printf("dnsresolv returns %08x\n", regs->eax.l);
}
diff --git a/core/fs/pxe/idle.c b/core/fs/pxe/idle.c
index 0538b163..52a87c34 100644
--- a/core/fs/pxe/idle.c
+++ b/core/fs/pxe/idle.c
@@ -27,7 +27,7 @@ static int pxe_idle_poll(void)
memset(&read_buf, 0, sizeof read_buf);
read_buf.src_ip = 0; /* Any destination */
- read_buf.dest_ip = MyIP;
+ read_buf.dest_ip = IPInfo.myip;
read_buf.s_port = 0; /* Any source port */
read_buf.d_port = htons(9); /* Discard port (not used...) */
read_buf.buffer_size = sizeof junk_pkt;
diff --git a/core/fs/pxe/pxe.c b/core/fs/pxe/pxe.c
index 011ef293..ef2398b4 100644
--- a/core/fs/pxe/pxe.c
+++ b/core/fs/pxe/pxe.c
@@ -9,10 +9,7 @@
#define GPXE 1
-uint32_t server_ip = 0; /* IP address of boot server */
-uint32_t net_mask = 0; /* net_mask of this subnet */
-uint32_t gate_way = 0; /* Default router */
-uint16_t real_base_mem; /* Amount of DOS memory after freeing */
+static uint16_t real_base_mem; /* Amount of DOS memory after freeing */
uint8_t MAC[MAC_MAX]; /* Actual MAC address */
uint8_t MAC_len; /* MAC address len */
@@ -297,7 +294,7 @@ static void tftp_error(struct inode *inode, uint16_t errnum,
udp_write.src_port = socket->tftp_localport;
udp_write.dst_port = socket->tftp_remoteport;
udp_write.ip = socket->tftp_remoteip;
- udp_write.gw = ((udp_write.ip ^ MyIP) & net_mask) ? gate_way : 0;
+ udp_write.gw = gateway(udp_write.ip);
udp_write.buffer = FAR_PTR(&err_buf);
udp_write.buffer_size = 4 + len + 1;
@@ -326,7 +323,7 @@ static void ack_packet(struct inode *inode, uint16_t ack_num)
udp_write.src_port = socket->tftp_localport;
udp_write.dst_port = socket->tftp_remoteport;
udp_write.ip = socket->tftp_remoteip;
- udp_write.gw = ((udp_write.ip ^ MyIP) & net_mask) ? gate_way : 0;
+ udp_write.gw = gateway(udp_write.ip);
udp_write.buffer = FAR_PTR(ack_packet_buf);
udp_write.buffer_size = 4;
@@ -513,7 +510,7 @@ static void fill_buffer(struct inode *inode)
udp_read.buffer = FAR_PTR(packet_buf);
udp_read.buffer_size = PKTBUF_SIZE;
udp_read.src_ip = socket->tftp_remoteip;
- udp_read.dest_ip = MyIP;
+ udp_read.dest_ip = IPInfo.myip;
udp_read.s_port = socket->tftp_remoteport;
udp_read.d_port = socket->tftp_localport;
err = pxe_call(PXENV_UDP_READ, &udp_read);
@@ -688,12 +685,12 @@ static void pxe_searchdir(const char *filename, struct file *file)
case PXE_RELATIVE: /* Really shouldn't happen... */
case PXE_URL:
buf = stpcpy(buf, filename);
- ip = server_ip; /* Default server */
+ ip = IPInfo.serverip; /* Default server */
break;
case PXE_HOMESERVER:
buf = stpcpy(buf, filename+2);
- ip = server_ip;
+ ip = IPInfo.serverip;
break;
case PXE_TFTP:
@@ -781,7 +778,7 @@ sendreq:
tid = socket->tftp_localport; /* TID(local port No) */
udp_write.buffer = FAR_PTR(rrq_packet_buf);
udp_write.ip = ip;
- udp_write.gw = ((udp_write.ip ^ MyIP) & net_mask) ? gate_way : 0;
+ udp_write.gw = gateway(udp_write.ip);
udp_write.src_port = tid;
udp_write.dst_port = server_port;
udp_write.buffer_size = buf - rrq_packet_buf;
@@ -794,7 +791,7 @@ wait_pkt:
buf = packet_buf;
udp_read.buffer = FAR_PTR(buf);
udp_read.buffer_size = PKTBUF_SIZE;
- udp_read.dest_ip = MyIP;
+ udp_read.dest_ip = IPInfo.myip;
udp_read.d_port = tid;
err = pxe_call(PXENV_UDP_READ, &udp_read);
if (err) {
@@ -1107,7 +1104,7 @@ static int pxe_load_config(void)
return 0;
/* Nope, try hexadecimal IP prefixes... */
- uchexbytes(config_file, (uint8_t *)&MyIP, 4); /* Convet to hex string */
+ uchexbytes(config_file, (uint8_t *)&IPInfo.myip, 4); /* Convet to hex string */
last = &config_file[8];
while (tries) {
*last = '\0'; /* Zero-terminate string */
@@ -1151,26 +1148,23 @@ char __bss16 IPOption[3+4*16];
static void genipopt(void)
{
char *p = IPOption;
+ const uint32_t *v = &IPInfo.myip;
+ int i;
p = stpcpy(p, "ip=");
- p += gendotquad(p, MyIP);
- *p++ = ':';
-
- p += gendotquad(p, server_ip);
- *p++ = ':';
-
- p += gendotquad(p, gate_way);
- *p++ = ':';
-
- gendotquad(p, net_mask);
+ for (i = 0; i < 4; i++) {
+ p += gendotquad(p, *v++);
+ *p++ = ':';
+ }
+ *--p = '\0';
}
/* Generate ip= option and print the ip adress */
static void ip_init(void)
{
- uint32_t ip = MyIP;
+ uint32_t ip = IPInfo.myip;
genipopt();
gendotquad(dot_quad_buf, ip);
@@ -1412,7 +1406,7 @@ static void udp_init(void)
{
int err;
static __lowmem struct s_PXENV_UDP_OPEN udp_open;
- udp_open.src_ip = MyIP;
+ udp_open.src_ip = IPInfo.myip;
err = pxe_call(PXENV_UDP_OPEN, &udp_open);
if (err || udp_open.status) {
printf("Failed to initialize UDP stack ");
diff --git a/core/fs/pxe/pxe.h b/core/fs/pxe/pxe.h
index e801aea5..cad63507 100644
--- a/core/fs/pxe/pxe.h
+++ b/core/fs/pxe/pxe.h
@@ -170,13 +170,20 @@ struct pxe_pvt_inode {
#define PVT(i) ((struct pxe_pvt_inode *)((i)->pvt))
/*
+ * Network boot information
+ */
+struct ip_info {
+ uint32_t ipv4;
+ uint32_t myip;
+ uint32_t serverip;
+ uint32_t gateway;
+ uint32_t netmask;
+};
+
+/*
* Variable externs
*/
-extern uint32_t server_ip;
-extern uint32_t MyIP;
-extern uint32_t net_mask;
-extern uint32_t gate_way;
-extern uint16_t server_port;
+extern struct ip_info IPInfo;
extern uint8_t MAC[];
extern char BOOTIFStr[];
@@ -195,7 +202,6 @@ extern char dot_quad_buf[];
extern uint32_t dns_server[];
-extern uint16_t real_base_mem;
extern uint16_t APIVer;
extern far_ptr_t PXEEntry;
extern uint8_t KeepPXE;
@@ -209,6 +215,17 @@ extern char uuid[];
extern uint16_t BIOS_fbm;
extern const uint8_t TimeoutTable[];
+/*
+ * Compute the suitable gateway for a specific route -- too many
+ * vendor PXE stacks don't do this correctly...
+ */
+static inline uint32_t gateway(uint32_t ip)
+{
+ if ((ip ^ IPInfo.myip) & IPInfo.netmask)
+ return IPInfo.gateway;
+ else
+ return 0;
+}
/*
* functions
diff --git a/core/pxelinux.asm b/core/pxelinux.asm
index 0b87e735..6fb77c25 100644
--- a/core/pxelinux.asm
+++ b/core/pxelinux.asm
@@ -530,7 +530,15 @@ exten_table_end:
KeepPXE db 0 ; Should PXE be kept around?
;
-; IP information (initialized to "unknown" values)
+; IP information. Note that the field are in the same order as the
+; Linux kernel expects in the ip= option.
+;
+ section .bss16
alignz 4
- global MyIP
-MyIP dd 0 ; My IP address
+ global IPInfo
+IPInfo:
+.IPv4 resd 1 ; IPv4 information
+.MyIP resd 1 ; My IP address
+.ServerIP resd 1
+.GatewayIP resd 1
+.Netmask resd 1
diff --git a/doc/comboot.txt b/doc/comboot.txt
index f39d7243..036bd784 100644
--- a/doc/comboot.txt
+++ b/doc/comboot.txt
@@ -448,6 +448,7 @@ AX=000Ah [2.00] Get Derivative-Specific Information
ECX Local IP number (network byte order) [3.85]
ES:BX pointer to PXENV+ or !PXE structure
FS:SI pointer to original stack with invocation record
+ GS:DI pointer to network information [4.00]
Note: DX notes the API version detected by PXELINUX,
which may be more conservative than the actual version
@@ -481,6 +482,13 @@ AX=000Ah [2.00] Get Derivative-Specific Information
[fs:si+44] PXE return IP <- t.o.s. when PXELINUX invoked
[fs:si+46] PXE return CS
+ GS:DI points to a structure of the following form:
+
+ [gs:di+0] 4 - IPv4
+ [gs:di+4] My IP
+ [gs:di+8] Boot server IP
+ [gs:di+12] Gateway IP
+ [gs:di+16] Netmask
[ISOLINUX]
Input: AX 000Ah