diff options
-rw-r--r-- | com32/include/syslinux/config.h | 9 | ||||
-rw-r--r-- | core/comboot.inc | 4 | ||||
-rw-r--r-- | core/fs/pxe/dhcp_option.c | 12 | ||||
-rw-r--r-- | core/fs/pxe/dnsresolv.c | 5 | ||||
-rw-r--r-- | core/fs/pxe/idle.c | 2 | ||||
-rw-r--r-- | core/fs/pxe/pxe.c | 42 | ||||
-rw-r--r-- | core/fs/pxe/pxe.h | 29 | ||||
-rw-r--r-- | core/pxelinux.asm | 14 | ||||
-rw-r--r-- | doc/comboot.txt | 8 |
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 |